void Openbox::signalHandler(int signal)
{
switch (signal) {
+ case SIGUSR1:
+ printf("Caught SIGUSR1 signal. Restarting.\n");
+ instance->restart();
+ break;
+
case SIGHUP:
- // XXX: Do something with HUP? Really shouldn't, we get this when X shuts
- // down and hangs-up on us.
-
case SIGINT:
case SIGTERM:
case SIGPIPE:
printf("Caught signal %d. Exiting.\n", signal);
instance->shutdown();
-
break;
+
case SIGFPE:
case SIGSEGV:
printf("Caught signal %d. Aborting and dumping core.\n", signal);
Openbox::instance = this;
_displayreq = (char*) 0;
- _argv0 = argv[0];
- _doshutdown = false;
+ _argv = argv;
+ _shutdown = false;
+ _restart = false;
_rcfilepath = otk::expandTilde("~/.openbox/rc3");
_scriptfilepath = otk::expandTilde("~/.openbox/user.py");
_focused_client = 0;
action.sa_handler = Openbox::signalHandler;
action.sa_mask = sigset_t();
action.sa_flags = SA_NOCLDSTOP | SA_NODEFER;
+ sigaction(SIGUSR1, &action, (struct sigaction *) 0);
sigaction(SIGPIPE, &action, (struct sigaction *) 0);
sigaction(SIGSEGV, &action, (struct sigaction *) 0);
sigaction(SIGFPE, &action, (struct sigaction *) 0);
_cursors.ul_angle = XCreateFontCursor(otk::OBDisplay::display, XC_ul_angle);
_cursors.ur_angle = XCreateFontCursor(otk::OBDisplay::display, XC_ur_angle);
- // start up python and load config values
+ // initialize scripting
python_init(argv[0]);
+
+ // load config values
python_exec(SCRIPTDIR"/config.py"); // load openbox config values
+ // run all of the python scripts
+ python_exec(SCRIPTDIR"/builtins.py"); // builtin callbacks
+ // run the user's script
+ python_exec(_scriptfilepath.c_str());
// initialize all the screens
OBScreen *screen;
::exit(1);
}
- // run all of the python scripts, including the user's
- python_exec(SCRIPTDIR"/globals.py"); // create/set global vars
- python_exec(SCRIPTDIR"/clientmotion.py"); // moving and resizing clients
- python_exec(SCRIPTDIR"/clicks.py"); // titlebar/root clicks and dblclicks
- python_exec(_scriptfilepath.c_str());
-
ScreenList::iterator it, end = _screens.end();
for (it = _screens.begin(); it != end; ++it) {
(*it)->manageExisting();
{
_state = State_Exiting; // time to kill everything
- delete _bindings;
- delete _actions;
+ int first_screen = _screens.front()->number();
std::for_each(_screens.begin(), _screens.end(), otk::PointerAssassin());
+ delete _bindings;
+ delete _actions;
delete _property;
- // close the X display
- otk::OBDisplay::destroy();
+ python_destroy();
+
+ XSetInputFocus(otk::OBDisplay::display, PointerRoot, RevertToNone,
+ CurrentTime);
+ XSync(otk::OBDisplay::display, false);
+
+ // this tends to block.. i honestly am not sure why. causing an x error in
+ // the shutdown process unblocks it. blackbox simply did a ::exit(0), so
+ // all im gunna do is the same.
+ //otk::OBDisplay::destroy();
+
+ if (_restart) {
+ if (!_restart_prog.empty()) {
+ const std::string &dstr =
+ otk::OBDisplay::screenInfo(first_screen)->displayString();
+ putenv(const_cast<char *>(dstr.c_str()));
+ execlp(_restart_prog.c_str(), _restart_prog.c_str(), NULL);
+ perror(_restart_prog.c_str());
+ }
+
+ // fall back in case the above execlp doesn't work
+ execvp(_argv[0], _argv);
+ execvp(otk::basename(_argv[0]).c_str(), _argv);
+ }
}
-menu <string> use alternate menu file.\n\
-script <string> use alternate startup script file.\n\
-version display version and exit.\n\
- -help display this help text and exit.\n\n"), _argv0);
+ -help display this help text and exit.\n\n"), _argv[0]);
printf(_("Compile time options:\n\
Debugging: %s\n\
void Openbox::eventLoop()
{
- while (!_doshutdown) {
+ while (!_shutdown) {
+ _timermanager.fire(!_sync); // wait if not in sync mode
dispatchEvents(); // from OtkEventDispatcher
XFlush(otk::OBDisplay::display); // flush here before we go wait for timers
- _timermanager.fire();
}
}
XSetInputFocus(otk::OBDisplay::display, _focused_screen->focuswindow(),
RevertToNone, CurrentTime);
}
-}
+ // set the NET_ACTIVE_WINDOW hint for all screens
+ ScreenList::iterator it, end = _screens.end();
+ for (it = _screens.begin(); it != end; ++it) {
+ int num = (*it)->number();
+ Window root = otk::OBDisplay::screenInfo(num)->rootWindow();
+ _property->set(root, otk::OBProperty::net_active_window,
+ otk::OBProperty::Atom_Window,
+ (c && _focused_screen == *it) ? c->window() : None);
+ }
+ // call the python Focus callbacks
+ EventData *data = new_event_data(_focused_screen->number(),
+ c ? c->window() : 0,
+ EventFocus, 0);
+ Openbox::instance->bindings()->fireEvent(data);
+ Py_XDECREF((PyObject*)data);
+}
-bool Openbox::getConfigString(const char *name, std::string *value) {
- return python_get_string(name, value);
+void Openbox::execute(int screen, const std::string &bin)
+{
+#ifdef __EMX__
+ // XXX: whats this for? windows?
+ spawnlp(P_NOWAIT, "cmd.exe", "cmd.exe", "/c", bin.c_str(), NULL);
+#else // __EMX__
+ if (screen >= ScreenCount(otk::OBDisplay::display))
+ screen = 0;
+ const std::string &dstr =
+ otk::OBDisplay::screenInfo(screen)->displayString();
+
+ if (! fork()) {
+ setsid();
+ int ret = putenv(const_cast<char *>(dstr.c_str()));
+ assert(ret != -1);
+ ret = execl("/bin/sh", "/bin/sh", "-c", bin.c_str(), NULL);
+ exit(ret);
+ }
+#endif // __EMX__
}
}