// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifdef HAVE_CONFIG_H
-# include "../config.h"
-#endif
+#include "config.h"
#include "openbox.hh"
#include "client.hh"
#include "otk/property.hh"
#include "otk/util.hh"
#include "otk/rendercolor.hh"
+#include "otk/renderstyle.hh"
extern "C" {
#include <X11/cursorfont.h>
-#ifdef HAVE_STDIO_H
-# include <stdio.h>
-#endif // HAVE_STDIO_H
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif // HAVE_STDLIB_H
-
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif // HAVE_SIGNAL_H
# include <fcntl.h>
#endif // HAVE_FCNTL_H
-#ifdef HAVE_UNISTD_H
-# include <sys/types.h>
-# include <unistd.h>
-#endif // HAVE_UNISTD_H
-
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif // HAVE_SYS_SELECT_H
-
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
#endif // HAVE_SYS_WAIT_H
}
#include <algorithm>
+#include <cstdio>
+#include <cstdlib>
+
+namespace otk {
+extern void initialize();
+extern void destroy();
+}
namespace ob {
Openbox::Openbox(int argc, char **argv)
: otk::EventDispatcher(),
- otk::EventHandler(),
- _display()
+ otk::EventHandler()
{
struct sigaction action;
openbox = this;
- _displayreq = (char*) 0;
_argv = argv;
_shutdown = false;
_restart = false;
_scriptfilepath = otk::expandTilde("~/.openbox/user.py");
_focused_client = 0;
_sync = false;
+ _single = false;
parseCommandLine(argc, argv);
+ otk::initialize();
+
XSynchronize(**otk::display, _sync);
// set up the signal handler
// anything that died while we were restarting won't give us a SIGCHLD
while (waitpid(-1, NULL, WNOHANG) > 0);
- otk::RenderColor::initialize();
- otk::Timer::initialize();
- otk::Property::initialize();
_actions = new Actions();
_bindings = new Bindings();
python_exec(SCRIPTDIR"/defaults.py"); // system default bahaviors
// initialize all the screens
+ _focused_screen = 0;
+
for (int i = 0, max = ScreenCount(**otk::display); i < max; ++i) {
Screen *screen;
+ // in single mode skip the screens we don't want to manage
if (_single && i != DefaultScreen(**otk::display)) {
_screens.push_back(0);
continue;
}
+ // try manage the screen
screen = new Screen(i);
- if (screen->managed())
+ if (screen->managed()) {
_screens.push_back(screen);
- else {
+ if (!_focused_screen) // set this to the first screen managed
+ _focused_screen = screen;
+ } else {
delete screen;
_screens.push_back(0);
}
}
+ assert(_focused_screen);
+
if (_screens.empty()) {
printf(_("No screens were found without a window manager. Exiting.\n"));
::exit(1);
for (it = _screens.begin(); it != end; ++it) {
(*it)->manageExisting();
}
-
+
// grab any keys set up before the screens existed
_bindings->grabKeys(true);
// set up input focus
- _focused_screen = _screens[0];
setFocusedClient(0);
_state = State_Normal; // done starting
{
_state = State_Exiting; // time to kill everything
- int first_screen = _screens.front()->number();
-
std::for_each(_screens.begin(), _screens.end(), otk::PointerAssassin());
delete _bindings;
CurrentTime);
XSync(**otk::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::display->destroy();
-
- otk::Timer::destroy();
- otk::RenderColor::destroy();
-
- if (_restart) {
- if (!_restart_prog.empty()) {
- otk::putenv(otk::display->screenInfo(first_screen)->displayString());
- execl("/bin/sh", "/bin/sh", "-c", _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);
- }
+ otk::destroy();
}
for (int i = 1; i < argc; ++i) {
std::string arg(argv[i]);
- if (arg == "-display") {
- if (++i >= argc)
- err = true;
- else
- _displayreq = argv[i];
- } else if (arg == "-rc") {
+ if (arg == "-rc") {
if (++i >= argc)
err = true;
else
-rc <string> use alternate resource file.\n\
-menu <string> use alternate menu file.\n\
-script <string> use alternate startup script file.\n\
- -sync run in synchronous mode (for debugging).\n\
+ -sync run in synchronous mode (for debugging X errors).\n\
-version display version and exit.\n\
-help display this help text and exit.\n\n"), _argv[0]);
void Openbox::setFocusedClient(Client *c)
{
+ // sometimes this is called with the already-focused window, this is
+ // important for the python scripts to work (eg, c = 0 twice). don't just
+ // return if _focused_client == c
+
+ assert(_focused_screen);
+
+ // uninstall the old colormap
+ if (_focused_client)
+ _focused_client->installColormap(false);
+ else
+ _focused_screen->installColormap(false);
+
_focused_client = c;
if (c) {
_focused_screen = _screens[c->screen()];
+
+ // install the client's colormap
+ c->installColormap(true);
} else {
- assert(_focused_screen);
XSetInputFocus(**otk::display, _focused_screen->focuswindow(),
RevertToNone, CurrentTime);
+
+ // install the root window colormap
+ _focused_screen->installColormap(true);
}
// set the NET_ACTIVE_WINDOW hint for all screens
ScreenList::iterator it, end = _screens.end();