#include <string>
using std::string;
-#include "i18n.hh"
#include "blackbox.hh"
-#include "Basemenu.hh"
-#include "Clientmenu.hh"
-#include "GCCache.hh"
-#include "Image.hh"
-#include "Rootmenu.hh"
-#include "Screen.hh"
-#include "Slit.hh"
-#include "Toolbar.hh"
-#include "Util.hh"
-#include "Window.hh"
-#include "Workspace.hh"
-#include "Workspacemenu.hh"
-#include "XAtom.hh"
-
-// X event scanner for enter/leave notifies - adapted from twm
-struct scanargs {
- Window w;
- bool leave, inferior, enter;
-};
-
-static Bool queueScanner(Display *, XEvent *e, char *args) {
- scanargs *scan = (scanargs *) args;
- if ((e->type == LeaveNotify) &&
- (e->xcrossing.window == scan->w) &&
- (e->xcrossing.mode == NotifyNormal)) {
- scan->leave = True;
- scan->inferior = (e->xcrossing.detail == NotifyInferior);
- } else if ((e->type == EnterNotify) && (e->xcrossing.mode == NotifyUngrab)) {
- scan->enter = True;
- }
-
- return False;
-}
+#include "gccache.hh"
+#include "image.hh"
+#include "screen.hh"
+#include "util.hh"
+#include "window.hh"
+#include "workspace.hh"
+#include "xatom.hh"
Blackbox *blackbox;
-Blackbox::Blackbox(char **m_argv, char *dpy_name, char *rc, char *menu)
+Blackbox::Blackbox(char **m_argv, char *dpy_name, char *rc)
: BaseDisplay(m_argv[0], dpy_name) {
if (! XSupportsLocale())
fprintf(stderr, "X server does not support locale\n");
if (! rc) rc = "~/.openbox/rc";
rc_file = expandTilde(rc);
config.setFile(rc_file);
- if (! menu) menu = "~/.openbox/menu";
- menu_file = expandTilde(menu);
no_focus = False;
if (screenList.empty()) {
fprintf(stderr,
- i18n(blackboxSet, blackboxNoManagableScreens,
- "Blackbox::Blackbox: no managable screens found, aborting.\n"));
+ "Blackbox::Blackbox: no managable screens found, aborting.\n");
::exit(3);
}
XSynchronize(getXDisplay(), False);
XSync(getXDisplay(), False);
- reconfigure_wait = reread_menu_wait = False;
+ reconfigure_wait = False;
timer = new BTimer(this, this);
timer->setTimeout(0l);
Blackbox::~Blackbox(void) {
std::for_each(screenList.begin(), screenList.end(), PointerAssassin());
- std::for_each(menuTimestamps.begin(), menuTimestamps.end(),
- PointerAssassin());
-
delete xatom;
delete timer;
last_time = e->xbutton.time;
BlackboxWindow *win = (BlackboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
- Slit *slit = (Slit *) 0;
- Toolbar *tbar = (Toolbar *) 0;
BScreen *scrn = (BScreen *) 0;
if ((win = searchWindow(e->xbutton.window))) {
/* XXX: is this sane on low colour desktops? */
if (e->xbutton.button == 1)
win->installColormap(True);
- } else if ((menu = searchMenu(e->xbutton.window))) {
- menu->buttonPressEvent(&e->xbutton);
- } else if ((slit = searchSlit(e->xbutton.window))) {
- slit->buttonPressEvent(&e->xbutton);
- } else if ((tbar = searchToolbar(e->xbutton.window))) {
- tbar->buttonPressEvent(&e->xbutton);
} else if ((scrn = searchScreen(e->xbutton.window))) {
scrn->buttonPressEvent(&e->xbutton);
if (active_screen != scrn) {
last_time = e->xbutton.time;
BlackboxWindow *win = (BlackboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
- Toolbar *tbar = (Toolbar *) 0;
if ((win = searchWindow(e->xbutton.window)))
win->buttonReleaseEvent(&e->xbutton);
- else if ((menu = searchMenu(e->xbutton.window)))
- menu->buttonReleaseEvent(&e->xbutton);
- else if ((tbar = searchToolbar(e->xbutton.window)))
- tbar->buttonReleaseEvent(&e->xbutton);
break;
}
case ConfigureRequest: {
- // compress configure requests...
- XEvent realevent;
- unsigned int i = 0;
- while(XCheckTypedWindowEvent(getXDisplay(), e->xconfigurerequest.window,
- ConfigureRequest, &realevent)) {
- i++;
- }
- if ( i > 0 )
- e = &realevent;
-
BlackboxWindow *win = (BlackboxWindow *) 0;
- Slit *slit = (Slit *) 0;
if ((win = searchWindow(e->xconfigurerequest.window))) {
win->configureRequestEvent(&e->xconfigurerequest);
- } else if ((slit = searchSlit(e->xconfigurerequest.window))) {
- slit->configureRequestEvent(&e->xconfigurerequest);
} else {
if (validateWindow(e->xconfigurerequest.window)) {
XWindowChanges xwc;
focus = True;
}
- if (focus && (win->isTransient() || win->getScreen()->doFocusNew()))
+ if (focus && (win->isTransient() || win->getScreen()->doFocusNew()) &&
+ win->isVisible())
win->setInputFocus();
} else {
BScreen *screen = searchScreen(e->xmaprequest.parent);
case UnmapNotify: {
BlackboxWindow *win = (BlackboxWindow *) 0;
- Slit *slit = (Slit *) 0;
BScreen *screen = (BScreen *) 0;
if ((win = searchWindow(e->xunmap.window))) {
win->unmapNotifyEvent(&e->xunmap);
- } else if ((slit = searchSlit(e->xunmap.window))) {
- slit->unmapNotifyEvent(&e->xunmap);
} else if ((screen = searchSystrayWindow(e->xunmap.window))) {
screen->removeSystrayWindow(e->xunmap.window);
}
case DestroyNotify: {
BlackboxWindow *win = (BlackboxWindow *) 0;
- Slit *slit = (Slit *) 0;
BScreen *screen = (BScreen *) 0;
BWindowGroup *group = (BWindowGroup *) 0;
if ((win = searchWindow(e->xdestroywindow.window))) {
win->destroyNotifyEvent(&e->xdestroywindow);
- } else if ((slit = searchSlit(e->xdestroywindow.window))) {
- slit->removeClient(e->xdestroywindow.window, False);
} else if ((group = searchGroup(e->xdestroywindow.window))) {
delete group;
} else if ((screen = searchSystrayWindow(e->xunmap.window))) {
to an already unmapped window.
*/
BlackboxWindow *win = searchWindow(e->xreparent.window);
- if (win) {
+ if (win)
win->reparentNotifyEvent(&e->xreparent);
- } else {
- Slit *slit = searchSlit(e->xreparent.window);
- if (slit && slit->getWindowID() != e->xreparent.parent)
- slit->removeClient(e->xreparent.window, True);
- }
break;
}
if ( i > 0 )
e = &realevent;
+ // the pointer is on the wrong screen
+ if (! e->xmotion.same_screen)
+ break;
+
// strip the lock key modifiers
- e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
+ e->xmotion.state &= ~(NumLockMask | ScrollLockMask | LockMask);
last_time = e->xmotion.time;
BlackboxWindow *win = (BlackboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
if ((win = searchWindow(e->xmotion.window)))
win->motionNotifyEvent(&e->xmotion);
- else if ((menu = searchMenu(e->xmotion.window)))
- menu->motionNotifyEvent(&e->xmotion);
break;
}
BScreen *screen = (BScreen *) 0;
BlackboxWindow *win = (BlackboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
- Toolbar *tbar = (Toolbar *) 0;
- Slit *slit = (Slit *) 0;
if (e->xcrossing.mode == NotifyGrab) break;
- XEvent dummy;
- scanargs sa;
- sa.w = e->xcrossing.window;
- sa.enter = sa.leave = False;
- XCheckIfEvent(getXDisplay(), &dummy, queueScanner, (char *) &sa);
-
if ((e->xcrossing.window == e->xcrossing.root) &&
(screen = searchScreen(e->xcrossing.window))) {
screen->getImageControl()->installRootColormap();
} else if ((win = searchWindow(e->xcrossing.window))) {
- if (win->getScreen()->isSloppyFocus() &&
- (! win->isFocused()) && (! no_focus) &&
- win->isNormal()) { // don't focus non-normal windows with mouseover
- if (((! sa.leave) || sa.inferior) && win->isVisible()) {
- if (win->setInputFocus())
- win->installColormap(True); // XXX: shouldnt we honour no install?
- }
- }
- } else if ((menu = searchMenu(e->xcrossing.window))) {
- menu->enterNotifyEvent(&e->xcrossing);
- } else if ((tbar = searchToolbar(e->xcrossing.window))) {
- tbar->enterNotifyEvent(&e->xcrossing);
- } else if ((slit = searchSlit(e->xcrossing.window))) {
- slit->enterNotifyEvent(&e->xcrossing);
+ if (! no_focus)
+ win->enterNotifyEvent(&e->xcrossing);
}
break;
}
last_time = e->xcrossing.time;
BlackboxWindow *win = (BlackboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
- Toolbar *tbar = (Toolbar *) 0;
- Slit *slit = (Slit *) 0;
-
- if ((menu = searchMenu(e->xcrossing.window)))
- menu->leaveNotifyEvent(&e->xcrossing);
- else if ((win = searchWindow(e->xcrossing.window)))
- win->installColormap(False);
- else if ((tbar = searchToolbar(e->xcrossing.window)))
- tbar->leaveNotifyEvent(&e->xcrossing);
- else if ((slit = searchSlit(e->xcrossing.window)))
- slit->leaveNotifyEvent(&e->xcrossing);
+
+ if ((win = searchWindow(e->xcrossing.window)))
+ win->leaveNotifyEvent(&e->xcrossing);
break;
}
e->xexpose.height = ey2 - ey1 + 1;
BlackboxWindow *win = (BlackboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
- Toolbar *tbar = (Toolbar *) 0;
if ((win = searchWindow(e->xexpose.window)))
win->exposeEvent(&e->xexpose);
- else if ((menu = searchMenu(e->xexpose.window)))
- menu->exposeEvent(&e->xexpose);
- else if ((tbar = searchToolbar(e->xexpose.window)))
- tbar->exposeEvent(&e->xexpose);
break;
}
case KeyPress: {
- Toolbar *tbar = searchToolbar(e->xkey.window);
-
- if (tbar && tbar->isEditing())
- tbar->keyPressEvent(&e->xkey);
-
break;
}
has moved to a known window.
*/
e->xfocus.window = None;
+
+ no_focus = False; // focusing is back on
}
break;
BScreen *screen = win->getScreen();
if (win->isIconic())
- win->deiconify(False, True);
- if (win->isShaded())
- win->shade();
- if (win->getWorkspaceNumber() != screen->getCurrentWorkspaceID())
+ win->deiconify(False, False);
+ if (! win->isStuck() &&
+ (win->getWorkspaceNumber() != screen->getCurrentWorkspaceID())) {
+ no_focus = True;
screen->changeWorkspaceID(win->getWorkspaceNumber());
+ }
if (win->isVisible() && win->setInputFocus()) {
win->getScreen()->getWorkspace(win->getWorkspaceNumber())->
raiseWindow(win);
else
win->show();
screen->reassociateWindow(win, wksp, True);
- } else if (wksp == 0xfffffffe) { // XXX: BUG, BUT DOING THIS SO KDE WORKS FOR NOW!!
+ } else if (wksp == 0xfffffffe || // XXX: BUG, BUT DOING THIS SO KDE WORKS FOR NOW!!
+ wksp == 0xffffffff) {
if (win->isIconic()) win->deiconify(False, True);
if (! win->isStuck()) win->stick();
if (! win->isVisible()) win->show();
// NET_NUMBER_OF_DESKTOPS
BScreen *screen = searchScreen(e->xclient.window);
- if (e->xclient.data.l[0] > 0) {
- if ((unsigned) e->xclient.data.l[0] < screen->getWorkspaceCount()) {
- // shrink
- for (int i = screen->getWorkspaceCount();
- i > e->xclient.data.l[0]; --i)
- screen->removeLastWorkspace();
- // removeLast already sets the current workspace to the
- // last available one.
- } else if ((unsigned) e->xclient.data.l[0] >
- screen->getWorkspaceCount()) {
- // grow
- for(int i = screen->getWorkspaceCount();
- i < e->xclient.data.l[0]; ++i)
- screen->addWorkspace();
- }
- }
+ if (e->xclient.data.l[0] > 0)
+ screen->changeWorkspaceCount((unsigned) e->xclient.data.l[0]);
} else if (e->xclient.message_type ==
xatom->getAtom(XAtom::net_close_window)) {
// NET_CLOSE_WINDOW
XShapeEvent *shape_event = (XShapeEvent *) e;
BlackboxWindow *win = searchWindow(e->xany.window);
- if (win)
+ if (win && shape_event->kind == ShapeBounding)
win->shapeEvent(shape_event);
}
#endif // SHAPE
bool Blackbox::handleSignal(int sig) {
switch (sig) {
case SIGHUP:
- restart();
+ reconfigure();
break;
case SIGUSR1:
- reconfigure();
+ restart();
break;
case SIGUSR2:
- rereadMenu();
break;
case SIGPIPE:
}
-Basemenu *Blackbox::searchMenu(Window window) {
- MenuLookup::iterator it = menuSearchList.find(window);
- if (it != menuSearchList.end())
- return it->second;
-
- return (Basemenu*) 0;
-}
-
-
-Toolbar *Blackbox::searchToolbar(Window window) {
- ToolbarLookup::iterator it = toolbarSearchList.find(window);
- if (it != toolbarSearchList.end())
- return it->second;
-
- return (Toolbar*) 0;
-}
-
-
-Slit *Blackbox::searchSlit(Window window) {
- SlitLookup::iterator it = slitSearchList.find(window);
- if (it != slitSearchList.end())
- return it->second;
-
- return (Slit*) 0;
-}
-
-
void Blackbox::saveSystrayWindowSearch(Window window, BScreen *screen) {
systraySearchList.insert(WindowScreenLookupPair(window, screen));
}
}
-void Blackbox::saveMenuSearch(Window window, Basemenu *data) {
- menuSearchList.insert(MenuLookupPair(window, data));
-}
-
-
-void Blackbox::saveToolbarSearch(Window window, Toolbar *data) {
- toolbarSearchList.insert(ToolbarLookupPair(window, data));
-}
-
-
-void Blackbox::saveSlitSearch(Window window, Slit *data) {
- slitSearchList.insert(SlitLookupPair(window, data));
-}
-
-
void Blackbox::removeSystrayWindowSearch(Window window) {
systraySearchList.erase(window);
}
}
-void Blackbox::removeMenuSearch(Window window) {
- menuSearchList.erase(window);
-}
-
-
-void Blackbox::removeToolbarSearch(Window window) {
- toolbarSearchList.erase(window);
-}
-
-
-void Blackbox::removeSlitSearch(Window window) {
- slitSearchList.erase(window);
-}
-
-
void Blackbox::restart(const char *prog) {
shutdown();
}
+#ifdef XINERAMA
+void Blackbox::saveXineramaPlacement(bool x) {
+ resource.xinerama_placement = x;
+ config.setValue("session.xineramaSupport.windowPlacement",
+ resource.xinerama_placement);
+ reconfigure(); // make sure all screens get this change
+}
+
+
+void Blackbox::saveXineramaMaximizing(bool x) {
+ resource.xinerama_maximize = x;
+ config.setValue("session.xineramaSupport.windowMaximizing",
+ resource.xinerama_maximize);
+ reconfigure(); // make sure all screens get this change
+}
+
+
+void Blackbox::saveXineramaSnapping(bool x) {
+ resource.xinerama_snap = x;
+ config.setValue("session.xineramaSupport.windowSnapping",
+ resource.xinerama_snap);
+ reconfigure(); // make sure all screens get this change
+}
+#endif // XINERAMA
+
+
/*
* Save all values as they are so that the defaults will be written to the rc
* file
config.setValue("session.cacheMax", resource.cache_max);
config.setValue("session.styleFile", resource.style_file);
config.setValue("session.titlebarLayout", resource.titlebar_layout);
+
+ string s;
+ if (resource.mod_mask & Mod1Mask) s += "Mod1-";
+ if (resource.mod_mask & Mod2Mask) s += "Mod2-";
+ if (resource.mod_mask & Mod3Mask) s += "Mod3-";
+ if (resource.mod_mask & Mod4Mask) s += "Mod4-";
+ if (resource.mod_mask & Mod5Mask) s += "Mod5-";
+ if (resource.mod_mask & ShiftMask) s += "Shift-";
+ if (resource.mod_mask & ControlMask) s += "Control-";
+ s.resize(s.size() - 1); // drop the last '-'
+ config.setValue("session.modifierMask", s);
+#ifdef XINERAMA
+ saveXineramaPlacement(resource.xinerama_placement);
+ saveXineramaMaximizing(resource.xinerama_maximize);
+ saveXineramaSnapping(resource.xinerama_snap);
+#endif // XINERAMA
+
std::for_each(screenList.begin(), screenList.end(),
std::mem_fun(&BScreen::save_rc));
if (! config.getValue("session.titlebarLayout", resource.titlebar_layout))
resource.titlebar_layout = "ILMC";
+
+#ifdef XINERAMA
+ if (! config.getValue("session.xineramaSupport.windowPlacement",
+ resource.xinerama_placement))
+ resource.xinerama_placement = false;
+
+ if (! config.getValue("session.xineramaSupport.windowMaximizing",
+ resource.xinerama_maximize))
+ resource.xinerama_maximize = false;
+
+ if (! config.getValue("session.xineramaSupport.windowSnapping",
+ resource.xinerama_snap))
+ resource.xinerama_snap = false;
+#endif // XINERAMA
+
+ resource.mod_mask = 0;
+ if (config.getValue("session.modifierMask", s)) {
+ if (s.find("Mod1") != string::npos)
+ resource.mod_mask |= Mod1Mask;
+ if (s.find("Mod2") != string::npos)
+ resource.mod_mask |= Mod2Mask;
+ if (s.find("Mod3") != string::npos)
+ resource.mod_mask |= Mod3Mask;
+ if (s.find("Mod4") != string::npos)
+ resource.mod_mask |= Mod4Mask;
+ if (s.find("Mod5") != string::npos)
+ resource.mod_mask |= Mod5Mask;
+ if (s.find("Shift") != string::npos)
+ resource.mod_mask |= ShiftMask;
+ if (s.find("Control") != string::npos)
+ resource.mod_mask |= ControlMask;
+ }
+ if (! resource.mod_mask)
+ resource.mod_mask = Mod1Mask;
}
void Blackbox::reconfigure(void) {
+ // don't reconfigure while saving the initial rc file, it's a waste and it
+ // breaks somethings (workspace names)
+ if (isStartup()) return;
+
reconfigure_wait = True;
if (! timer->isTiming()) timer->start();
void Blackbox::real_reconfigure(void) {
load_rc();
- std::for_each(menuTimestamps.begin(), menuTimestamps.end(),
- PointerAssassin());
- menuTimestamps.clear();
-
gcCache()->purge();
std::for_each(screenList.begin(), screenList.end(),
}
-void Blackbox::checkMenu(void) {
- bool reread = False;
- MenuTimestampList::iterator it = menuTimestamps.begin();
- for(; it != menuTimestamps.end(); ++it) {
- MenuTimestamp *tmp = *it;
- struct stat buf;
-
- if (! stat(tmp->filename.c_str(), &buf)) {
- if (tmp->timestamp != buf.st_ctime)
- reread = True;
- } else {
- reread = True;
- }
- }
-
- if (reread) rereadMenu();
-}
-
-
-void Blackbox::rereadMenu(void) {
- reread_menu_wait = True;
-
- if (! timer->isTiming()) timer->start();
-}
-
-
-void Blackbox::real_rereadMenu(void) {
- std::for_each(menuTimestamps.begin(), menuTimestamps.end(),
- PointerAssassin());
- menuTimestamps.clear();
-
- std::for_each(screenList.begin(), screenList.end(),
- std::mem_fun(&BScreen::rereadMenu));
-}
-
-
void Blackbox::saveStyleFilename(const string& filename) {
assert(! filename.empty());
resource.style_file = filename;
}
-void Blackbox::addMenuTimestamp(const string& filename) {
- assert(! filename.empty());
- bool found = False;
-
- MenuTimestampList::iterator it = menuTimestamps.begin();
- for (; it != menuTimestamps.end() && ! found; ++it) {
- if ((*it)->filename == filename) found = True;
- }
- if (! found) {
- struct stat buf;
-
- if (! stat(filename.c_str(), &buf)) {
- MenuTimestamp *ts = new MenuTimestamp;
-
- ts->filename = filename;
- ts->timestamp = buf.st_ctime;
-
- menuTimestamps.push_back(ts);
- }
- }
-}
-
-
void Blackbox::timeout(void) {
if (reconfigure_wait)
real_reconfigure();
- if (reread_menu_wait)
- real_rereadMenu();
-
- reconfigure_wait = reread_menu_wait = False;
+ reconfigure_wait = False;
}
}
if (active_screen && active_screen->isScreenManaged()) {
- active_screen->getToolbar()->redrawWindowLabel(True);
active_screen->updateNetizenWindowFocus();
}
if (old_screen && old_screen != active_screen) {
- old_screen->getToolbar()->redrawWindowLabel(True);
old_screen->updateNetizenWindowFocus();
}
}