X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fblackbox.cc;h=e8b8dcaaf5210b4985acda63be926f2d3075a5b9;hb=db3e93a3c1a57d962741a572a0913ce2555d9dba;hp=4325933beb8e3e7c695f8f73e008e4c148e97c37;hpb=8794d357e67abddf9fda9db77b235e294d0ec590;p=chaz%2Fopenbox diff --git a/src/blackbox.cc b/src/blackbox.cc index 4325933b..e8b8dcaa 100644 --- a/src/blackbox.cc +++ b/src/blackbox.cc @@ -28,7 +28,6 @@ extern "C" { #include #include -#include #include #include #include @@ -91,6 +90,8 @@ extern "C" { #endif // HAVE_LIBGEN_H } +#include + #include #include using std::string; @@ -109,32 +110,12 @@ using std::string; #include "Window.hh" #include "Workspace.hh" #include "Workspacemenu.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 "XAtom.hh" Blackbox *blackbox; -Blackbox::Blackbox(char **m_argv, char *dpy_name, char *rc) +Blackbox::Blackbox(char **m_argv, char *dpy_name, char *rc, char *menu) : BaseDisplay(m_argv[0], dpy_name) { if (! XSupportsLocale()) fprintf(stderr, "X server does not support locale\n"); @@ -144,25 +125,35 @@ Blackbox::Blackbox(char **m_argv, char *dpy_name, char *rc) ::blackbox = this; argv = m_argv; - if (! rc) rc = "~/.blackboxrc"; + + // try to make sure the ~/.openbox directory exists + mkdir(expandTilde("~/.openbox").c_str(), S_IREAD | S_IWRITE | S_IEXEC | + S_IRGRP | S_IWGRP | S_IXGRP | + S_IROTH | S_IWOTH | S_IXOTH); + + 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; resource.auto_raise_delay.tv_sec = resource.auto_raise_delay.tv_usec = 0; active_screen = 0; - focused_window = (BlackboxWindow *) 0; + focused_window = changing_window = (BlackboxWindow *) 0; - XrmInitialize(); load_rc(); - init_icccm(); + xatom = new XAtom(getXDisplay()); cursor.session = XCreateFontCursor(getXDisplay(), XC_left_ptr); cursor.move = XCreateFontCursor(getXDisplay(), XC_fleur); cursor.ll_angle = XCreateFontCursor(getXDisplay(), XC_ll_angle); cursor.lr_angle = XCreateFontCursor(getXDisplay(), XC_lr_angle); + cursor.ul_angle = XCreateFontCursor(getXDisplay(), XC_ul_angle); + cursor.ur_angle = XCreateFontCursor(getXDisplay(), XC_ur_angle); for (unsigned int i = 0; i < getNumberOfScreens(); i++) { BScreen *screen = new BScreen(this, i); @@ -182,6 +173,9 @@ Blackbox::Blackbox(char **m_argv, char *dpy_name, char *rc) ::exit(3); } + // save current settings and default values + save_rc(); + // set the screen with mouse to the first managed screen active_screen = screenList.front(); setFocusedWindow(0); @@ -202,6 +196,8 @@ Blackbox::~Blackbox(void) { std::for_each(menuTimestamps.begin(), menuTimestamps.end(), PointerAssassin()); + delete xatom; + delete timer; } @@ -266,16 +262,6 @@ void Blackbox::process_event(XEvent *e) { } 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; @@ -311,7 +297,21 @@ void Blackbox::process_event(XEvent *e) { BlackboxWindow *win = searchWindow(e->xmaprequest.window); - if (! win) { + if (win) { + bool focus = False; + if (win->isIconic()) { + win->deiconify(); + focus = True; + } + if (win->isShaded()) { + win->shade(); + focus = True; + } + + if (focus && (win->isTransient() || win->getScreen()->doFocusNew()) && + win->isVisible()) + win->setInputFocus(); + } else { BScreen *screen = searchScreen(e->xmaprequest.parent); if (! screen) { @@ -347,11 +347,14 @@ void Blackbox::process_event(XEvent *e) { 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); } break; @@ -360,6 +363,7 @@ void Blackbox::process_event(XEvent *e) { case DestroyNotify: { BlackboxWindow *win = (BlackboxWindow *) 0; Slit *slit = (Slit *) 0; + BScreen *screen = (BScreen *) 0; BWindowGroup *group = (BWindowGroup *) 0; if ((win = searchWindow(e->xdestroywindow.window))) { @@ -368,6 +372,8 @@ void Blackbox::process_event(XEvent *e) { slit->removeClient(e->xdestroywindow.window, False); } else if ((group = searchGroup(e->xdestroywindow.window))) { delete group; + } else if ((screen = searchSystrayWindow(e->xunmap.window))) { + screen->removeSystrayWindow(e->xunmap.window); } break; @@ -404,8 +410,12 @@ void Blackbox::process_event(XEvent *e) { 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; @@ -423,13 +433,13 @@ void Blackbox::process_event(XEvent *e) { case PropertyNotify: { last_time = e->xproperty.time; - if (e->xproperty.state != PropertyDelete) { - BlackboxWindow *win = searchWindow(e->xproperty.window); - - if (win) - win->propertyNotifyEvent(e->xproperty.atom); - } + BlackboxWindow *win = (BlackboxWindow *) 0; + BScreen *screen = (BScreen *) 0; + if ((win = searchWindow(e->xproperty.window))) + win->propertyNotifyEvent(&e->xproperty); + else if ((screen = searchScreen(e->xproperty.window))) + screen->propertyNotifyEvent(&e->xproperty); break; } @@ -444,23 +454,12 @@ void Blackbox::process_event(XEvent *e) { 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)) { - if (((! sa.leave) || sa.inferior) && win->isVisible()) { - if (win->setInputFocus()) - win->installColormap(True); // XXX: shouldnt we honour no install? - } - } + if (! no_focus) + win->enterNotifyEvent(&e->xcrossing); } else if ((menu = searchMenu(e->xcrossing.window))) { menu->enterNotifyEvent(&e->xcrossing); } else if ((tbar = searchToolbar(e->xcrossing.window))) { @@ -482,7 +481,7 @@ void Blackbox::process_event(XEvent *e) { if ((menu = searchMenu(e->xcrossing.window))) menu->leaveNotifyEvent(&e->xcrossing); else if ((win = searchWindow(e->xcrossing.window))) - win->installColormap(False); + win->leaveNotifyEvent(&e->xcrossing); else if ((tbar = searchToolbar(e->xcrossing.window))) tbar->leaveNotifyEvent(&e->xcrossing); else if ((slit = searchSlit(e->xcrossing.window))) @@ -552,11 +551,14 @@ void Blackbox::process_event(XEvent *e) { } case FocusIn: { - if (e->xfocus.detail != NotifyNonlinear) { + if (e->xfocus.detail != NotifyNonlinear && + e->xfocus.detail != NotifyAncestor) { /* don't process FocusIns when: 1. the new focus window isn't an ancestor or inferior of the old focus window (NotifyNonlinear) + make sure to allow the FocusIn when the old focus window was an + ancestor but didn't have a parent, such as root (NotifyAncestor) */ break; } @@ -572,6 +574,8 @@ void Blackbox::process_event(XEvent *e) { has moved to a known window. */ e->xfocus.window = None; + + no_focus = False; // focusing is back on } break; @@ -643,7 +647,8 @@ void Blackbox::process_event(XEvent *e) { case ClientMessage: { if (e->xclient.format == 32) { - if (e->xclient.message_type == getWMChangeStateAtom()) { + if (e->xclient.message_type == xatom->getAtom(XAtom::wm_change_state)) { + // WM_CHANGE_STATE message BlackboxWindow *win = searchWindow(e->xclient.window); if (! win || ! win->validateClient()) return; @@ -651,19 +656,47 @@ void Blackbox::process_event(XEvent *e) { win->iconify(); if (e->xclient.data.l[0] == NormalState) win->deiconify(); - } else if(e->xclient.message_type == getBlackboxChangeWorkspaceAtom()) { + } else if (e->xclient.message_type == + xatom->getAtom(XAtom::blackbox_change_workspace) || + e->xclient.message_type == + xatom->getAtom(XAtom::net_current_desktop)) { + // NET_CURRENT_DESKTOP message BScreen *screen = searchScreen(e->xclient.window); - if (screen && e->xclient.data.l[0] >= 0 && - e->xclient.data.l[0] < - static_cast(screen->getWorkspaceCount())) - screen->changeWorkspaceID(e->xclient.data.l[0]); - } else if (e->xclient.message_type == getBlackboxChangeWindowFocusAtom()) { + unsigned int workspace = e->xclient.data.l[0]; + if (screen && workspace < screen->getWorkspaceCount()) + screen->changeWorkspaceID(workspace); + } else if (e->xclient.message_type == + xatom->getAtom(XAtom::blackbox_change_window_focus)) { + // TEMP HACK TO KEEP BBKEYS WORKING BlackboxWindow *win = searchWindow(e->xclient.window); if (win && win->isVisible() && win->setInputFocus()) win->installColormap(True); - } else if (e->xclient.message_type == getBlackboxCycleWindowFocusAtom()) { + } else if (e->xclient.message_type == + xatom->getAtom(XAtom::net_active_window)) { + // NET_ACTIVE_WINDOW + BlackboxWindow *win = searchWindow(e->xclient.window); + + if (win) { + BScreen *screen = win->getScreen(); + + if (win->isIconic()) + 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); + win->installColormap(True); + } + } + } else if (e->xclient.message_type == + xatom->getAtom(XAtom::blackbox_cycle_window_focus)) { + // BLACKBOX_CYCLE_WINDOW_FOCUS BScreen *screen = searchScreen(e->xclient.window); if (screen) { @@ -672,7 +705,32 @@ void Blackbox::process_event(XEvent *e) { else screen->nextFocus(); } - } else if (e->xclient.message_type == getBlackboxChangeAttributesAtom()) { + } else if (e->xclient.message_type == + xatom->getAtom(XAtom::net_wm_desktop)) { + // NET_WM_DESKTOP + BlackboxWindow *win = searchWindow(e->xclient.window); + + if (win) { + BScreen *screen = win->getScreen(); + unsigned long wksp = (unsigned) e->xclient.data.l[0]; + if (wksp < screen->getWorkspaceCount()) { + if (win->isIconic()) win->deiconify(False, True); + if (win->isStuck()) win->stick(); + if (wksp != screen->getCurrentWorkspaceID()) + win->withdraw(); + else + win->show(); + screen->reassociateWindow(win, wksp, True); + } 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(); + } + } + } else if (e->xclient.message_type == + xatom->getAtom(XAtom::blackbox_change_attributes)) { + // BLACKBOX_CHANGE_ATTRIBUTES BlackboxWindow *win = searchWindow(e->xclient.window); if (win && win->validateClient()) { @@ -685,6 +743,193 @@ void Blackbox::process_event(XEvent *e) { win->changeBlackboxHints(&net); } + } else if (e->xclient.message_type == + xatom->getAtom(XAtom::net_number_of_desktops)) { + // NET_NUMBER_OF_DESKTOPS + BScreen *screen = searchScreen(e->xclient.window); + + 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 + BlackboxWindow *win = searchWindow(e->xclient.window); + if (win && win->validateClient()) + win->close(); // could this be smarter? + } else if (e->xclient.message_type == + xatom->getAtom(XAtom::net_wm_moveresize)) { + // NET_WM_MOVERESIZE + BlackboxWindow *win = searchWindow(e->xclient.window); + if (win && win->validateClient()) { + int x_root = e->xclient.data.l[0], + y_root = e->xclient.data.l[1]; + if ((Atom) e->xclient.data.l[2] == + xatom->getAtom(XAtom::net_wm_moveresize_move)) { + win->beginMove(x_root, y_root); + } else { + if ((Atom) e->xclient.data.l[2] == + xatom->getAtom(XAtom::net_wm_moveresize_size_topleft)) + win->beginResize(x_root, y_root, BlackboxWindow::TopLeft); + else if ((Atom) e->xclient.data.l[2] == + xatom->getAtom(XAtom::net_wm_moveresize_size_topright)) + win->beginResize(x_root, y_root, BlackboxWindow::TopRight); + else if ((Atom) e->xclient.data.l[2] == + xatom->getAtom(XAtom::net_wm_moveresize_size_bottomleft)) + win->beginResize(x_root, y_root, BlackboxWindow::BottomLeft); + else if ((Atom) e->xclient.data.l[2] == + xatom->getAtom(XAtom::net_wm_moveresize_size_bottomright)) + win->beginResize(x_root, y_root, BlackboxWindow::BottomRight); + } + } + } else if (e->xclient.message_type == + xatom->getAtom(XAtom::net_wm_state)) { + // NET_WM_STATE + BlackboxWindow *win = searchWindow(e->xclient.window); + if (win && win->validateClient()) { + const Atom action = (Atom) e->xclient.data.l[0]; + const Atom state[] = { (Atom) e->xclient.data.l[1], + (Atom) e->xclient.data.l[2] }; + + for (int i = 0; i < 2; ++i) { + if (! state[i]) + continue; + + if ((Atom) e->xclient.data.l[0] == 1) { + // ADD + if (state[i] == xatom->getAtom(XAtom::net_wm_state_modal)) { + win->setModal(True); + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_maximized_vert)) { + if (win->isMaximizedHoriz()) { + win->maximize(0); // unmaximize + win->maximize(1); // full + } else if (! win->isMaximized()) { + win->maximize(2); // vert + } + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_maximized_horz)) { + if (win->isMaximizedVert()) { + win->maximize(0); // unmaximize + win->maximize(1); // full + } else if (! win->isMaximized()) { + win->maximize(3); // horiz + } + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_shaded)) { + if (! win->isShaded()) + win->shade(); + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_skip_taskbar)) { + win->setSkipTaskbar(True); + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_skip_pager)) { + win->setSkipPager(True); + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_fullscreen)) { + win->setFullscreen(True); + } + } else if (action == 0) { + // REMOVE + if (state[i] == xatom->getAtom(XAtom::net_wm_state_modal)) { + win->setModal(False); + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_maximized_vert)) { + if (win->isMaximizedFull()) { + win->maximize(0); // unmaximize + win->maximize(3); // horiz + } else if (win->isMaximizedVert()) { + win->maximize(0); // unmaximize + } + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_maximized_horz)) { + if (win->isMaximizedFull()) { + win->maximize(0); // unmaximize + win->maximize(2); // vert + } else if (win->isMaximizedHoriz()) { + win->maximize(0); // unmaximize + } + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_shaded)) { + if (win->isShaded()) + win->shade(); + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_skip_taskbar)) { + win->setSkipTaskbar(False); + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_skip_pager)) { + win->setSkipPager(False); + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_fullscreen)) { + win->setFullscreen(False); + } + } else if (action == 2) { + // TOGGLE + if (state[i] == xatom->getAtom(XAtom::net_wm_state_modal)) { + win->setModal(! win->isModal()); + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_maximized_vert)) { + if (win->isMaximizedFull()) { + win->maximize(0); // unmaximize + win->maximize(3); // horiz + } else if (win->isMaximizedVert()) { + win->maximize(0); // unmaximize + } else if (win->isMaximizedHoriz()) { + win->maximize(0); // unmaximize + win->maximize(1); // full + } else { + win->maximize(2); // vert + } + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_maximized_horz)) { + if (win->isMaximizedFull()) { + win->maximize(0); // unmaximize + win->maximize(2); // vert + } else if (win->isMaximizedHoriz()) { + win->maximize(0); // unmaximize + } else if (win->isMaximizedVert()) { + win->maximize(0); // unmaximize + win->maximize(1); // full + } else { + win->maximize(3); // horiz + } + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_shaded)) { + win->shade(); + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_skip_taskbar)) { + win->setSkipTaskbar(! win->skipTaskbar()); + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_skip_pager)) { + win->setSkipPager(! win->skipPager()); + } else if (state[i] == + xatom->getAtom(XAtom::net_wm_state_fullscreen)) { + win->setFullscreen(! win->isFullscreen()); + } + } + } + } + } else if (e->xclient.message_type == + xatom->getAtom(XAtom::openbox_show_root_menu) || + e->xclient.message_type == + xatom->getAtom(XAtom::openbox_show_workspace_menu)) { + // find the screen the mouse is on + int x, y; + ScreenList::iterator it, end = screenList.end(); + for (it = screenList.begin(); it != end; ++it) { + Window w; + int i; + unsigned int m; + if (XQueryPointer(getXDisplay(), (*it)->getRootWindow(), + &w, &w, &x, &y, &i, &i, &m)) + break; + } + if (it != end) { + if (e->xclient.message_type == + xatom->getAtom(XAtom::openbox_show_root_menu)) + (*it)->showRootMenu(x, y); + else + (*it)->showWorkspaceMenu(x, y); + } } } @@ -718,7 +963,7 @@ bool Blackbox::handleSignal(int sig) { break; case SIGUSR1: - reload_rc(); + restart(); break; case SIGUSR2: @@ -740,89 +985,6 @@ bool Blackbox::handleSignal(int sig) { } -void Blackbox::init_icccm(void) { - xa_wm_colormap_windows = - XInternAtom(getXDisplay(), "WM_COLORMAP_WINDOWS", False); - xa_wm_protocols = XInternAtom(getXDisplay(), "WM_PROTOCOLS", False); - xa_wm_state = XInternAtom(getXDisplay(), "WM_STATE", False); - xa_wm_change_state = XInternAtom(getXDisplay(), "WM_CHANGE_STATE", False); - xa_wm_delete_window = XInternAtom(getXDisplay(), "WM_DELETE_WINDOW", False); - xa_wm_take_focus = XInternAtom(getXDisplay(), "WM_TAKE_FOCUS", False); - motif_wm_hints = XInternAtom(getXDisplay(), "_MOTIF_WM_HINTS", False); - - blackbox_hints = XInternAtom(getXDisplay(), "_BLACKBOX_HINTS", False); - blackbox_attributes = - XInternAtom(getXDisplay(), "_BLACKBOX_ATTRIBUTES", False); - blackbox_change_attributes = - XInternAtom(getXDisplay(), "_BLACKBOX_CHANGE_ATTRIBUTES", False); - blackbox_structure_messages = - XInternAtom(getXDisplay(), "_BLACKBOX_STRUCTURE_MESSAGES", False); - blackbox_notify_startup = - XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_STARTUP", False); - blackbox_notify_window_add = - XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_WINDOW_ADD", False); - blackbox_notify_window_del = - XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_WINDOW_DEL", False); - blackbox_notify_current_workspace = - XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_CURRENT_WORKSPACE", False); - blackbox_notify_workspace_count = - XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_WORKSPACE_COUNT", False); - blackbox_notify_window_focus = - XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_WINDOW_FOCUS", False); - blackbox_notify_window_raise = - XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_WINDOW_RAISE", False); - blackbox_notify_window_lower = - XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_WINDOW_LOWER", False); - blackbox_change_workspace = - XInternAtom(getXDisplay(), "_BLACKBOX_CHANGE_WORKSPACE", False); - blackbox_change_window_focus = - XInternAtom(getXDisplay(), "_BLACKBOX_CHANGE_WINDOW_FOCUS", False); - blackbox_cycle_window_focus = - XInternAtom(getXDisplay(), "_BLACKBOX_CYCLE_WINDOW_FOCUS", False); - -#ifdef NEWWMSPEC - net_supported = XInternAtom(getXDisplay(), "_NET_SUPPORTED", False); - net_client_list = XInternAtom(getXDisplay(), "_NET_CLIENT_LIST", False); - net_client_list_stacking = - XInternAtom(getXDisplay(), "_NET_CLIENT_LIST_STACKING", False); - net_number_of_desktops = - XInternAtom(getXDisplay(), "_NET_NUMBER_OF_DESKTOPS", False); - net_desktop_geometry = - XInternAtom(getXDisplay(), "_NET_DESKTOP_GEOMETRY", False); - net_desktop_viewport = - XInternAtom(getXDisplay(), "_NET_DESKTOP_VIEWPORT", False); - net_current_desktop = - XInternAtom(getXDisplay(), "_NET_CURRENT_DESKTOP", False); - net_desktop_names = XInternAtom(getXDisplay(), "_NET_DESKTOP_NAMES", False); - net_active_window = XInternAtom(getXDisplay(), "_NET_ACTIVE_WINDOW", False); - net_workarea = XInternAtom(getXDisplay(), "_NET_WORKAREA", False); - net_supporting_wm_check = - XInternAtom(getXDisplay(), "_NET_SUPPORTING_WM_CHECK", False); - net_virtual_roots = XInternAtom(getXDisplay(), "_NET_VIRTUAL_ROOTS", False); - net_close_window = XInternAtom(getXDisplay(), "_NET_CLOSE_WINDOW", False); - net_wm_moveresize = XInternAtom(getXDisplay(), "_NET_WM_MOVERESIZE", False); - net_properties = XInternAtom(getXDisplay(), "_NET_PROPERTIES", False); - net_wm_name = XInternAtom(getXDisplay(), "_NET_WM_NAME", False); - net_wm_desktop = XInternAtom(getXDisplay(), "_NET_WM_DESKTOP", False); - net_wm_window_type = - XInternAtom(getXDisplay(), "_NET_WM_WINDOW_TYPE", False); - net_wm_state = XInternAtom(getXDisplay(), "_NET_WM_STATE", False); - net_wm_strut = XInternAtom(getXDisplay(), "_NET_WM_STRUT", False); - net_wm_icon_geometry = - XInternAtom(getXDisplay(), "_NET_WM_ICON_GEOMETRY", False); - net_wm_icon = XInternAtom(getXDisplay(), "_NET_WM_ICON", False); - net_wm_pid = XInternAtom(getXDisplay(), "_NET_WM_PID", False); - net_wm_handled_icons = - XInternAtom(getXDisplay(), "_NET_WM_HANDLED_ICONS", False); - net_wm_ping = XInternAtom(getXDisplay(), "_NET_WM_PING", False); -#endif // NEWWMSPEC - -#ifdef HAVE_GETPID - blackbox_pid = XInternAtom(getXDisplay(), "_BLACKBOX_PID", False); -#endif // HAVE_GETPID -} - - bool Blackbox::validateWindow(Window window) { XEvent event; if (XCheckTypedWindowEvent(getXDisplay(), window, DestroyNotify, &event)) { @@ -848,6 +1010,15 @@ BScreen *Blackbox::searchScreen(Window window) { } +BScreen *Blackbox::searchSystrayWindow(Window window) { + WindowScreenLookup::iterator it = systraySearchList.find(window); + if (it != systraySearchList.end()) + return it->second; + + return (BScreen*) 0; +} + + BlackboxWindow *Blackbox::searchWindow(Window window) { WindowLookup::iterator it = windowSearchList.find(window); if (it != windowSearchList.end()) @@ -893,6 +1064,11 @@ Slit *Blackbox::searchSlit(Window window) { } +void Blackbox::saveSystrayWindowSearch(Window window, BScreen *screen) { + systraySearchList.insert(WindowScreenLookupPair(window, screen)); +} + + void Blackbox::saveWindowSearch(Window window, BlackboxWindow *data) { windowSearchList.insert(WindowLookupPair(window, data)); } @@ -918,6 +1094,11 @@ void Blackbox::saveSlitSearch(Window window, Slit *data) { } +void Blackbox::removeSystrayWindowSearch(Window window) { + systraySearchList.erase(window); +} + + void Blackbox::removeWindowSearch(Window window) { windowSearchList.erase(window); } @@ -947,6 +1128,7 @@ void Blackbox::restart(const char *prog) { shutdown(); if (prog) { + putenv(const_cast(screenList.front()->displayString().c_str())); execlp(prog, prog, NULL); perror(prog); } @@ -967,560 +1149,158 @@ void Blackbox::shutdown(void) { std::mem_fun(&BScreen::shutdown)); XSync(getXDisplay(), False); - - save_rc(); } -void Blackbox::save_rc(void) { - XrmDatabase new_blackboxrc = (XrmDatabase) 0; - char rc_string[1024]; - - load_rc(); - - sprintf(rc_string, "session.menuFile: %s", getMenuFilename()); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.colorsPerChannel: %d", - resource.colors_per_channel); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.doubleClickInterval: %lu", - resource.double_click_interval); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.autoRaiseDelay: %lu", - ((resource.auto_raise_delay.tv_sec * 1000) + - (resource.auto_raise_delay.tv_usec / 1000))); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.cacheLife: %lu", resource.cache_life / 60000); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.cacheMax: %lu", resource.cache_max); - XrmPutLineResource(&new_blackboxrc, rc_string); - - ScreenList::iterator it = screenList.begin(); - for (; it != screenList.end(); ++it) { - BScreen *screen = *it; - int screen_number = screen->getScreenNumber(); - - char *placement = (char *) 0; - - switch (screen->getSlitPlacement()) { - case Slit::TopLeft: placement = "TopLeft"; break; - case Slit::CenterLeft: placement = "CenterLeft"; break; - case Slit::BottomLeft: placement = "BottomLeft"; break; - case Slit::TopCenter: placement = "TopCenter"; break; - case Slit::BottomCenter: placement = "BottomCenter"; break; - case Slit::TopRight: placement = "TopRight"; break; - case Slit::BottomRight: placement = "BottomRight"; break; - case Slit::CenterRight: default: placement = "CenterRight"; break; - } - - sprintf(rc_string, "session.screen%d.slit.placement: %s", screen_number, - placement); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.screen%d.slit.direction: %s", screen_number, - ((screen->getSlitDirection() == Slit::Horizontal) ? "Horizontal" : - "Vertical")); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.screen%d.slit.onTop: %s", screen_number, - ((screen->getSlit()->isOnTop()) ? "True" : "False")); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.screen%d.slit.autoHide: %s", screen_number, - ((screen->getSlit()->doAutoHide()) ? "True" : "False")); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.opaqueMove: %s", - ((screen->doOpaqueMove()) ? "True" : "False")); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.imageDither: %s", - ((screen->getImageControl()->doDither()) ? "True" : "False")); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.screen%d.fullMaximization: %s", screen_number, - ((screen->doFullMax()) ? "True" : "False")); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.screen%d.focusNewWindows: %s", screen_number, - ((screen->doFocusNew()) ? "True" : "False")); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.screen%d.focusLastWindow: %s", screen_number, - ((screen->doFocusLast()) ? "True" : "False")); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.screen%d.rowPlacementDirection: %s", - screen_number, - ((screen->getRowPlacementDirection() == BScreen::LeftRight) ? - "LeftToRight" : "RightToLeft")); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.screen%d.colPlacementDirection: %s", - screen_number, - ((screen->getColPlacementDirection() == BScreen::TopBottom) ? - "TopToBottom" : "BottomToTop")); - XrmPutLineResource(&new_blackboxrc, rc_string); - - switch (screen->getPlacementPolicy()) { - case BScreen::CascadePlacement: - placement = "CascadePlacement"; - break; - case BScreen::ColSmartPlacement: - placement = "ColSmartPlacement"; - break; +#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 +} - case BScreen::RowSmartPlacement: - default: - placement = "RowSmartPlacement"; - break; - } - sprintf(rc_string, "session.screen%d.windowPlacement: %s", screen_number, - placement); - XrmPutLineResource(&new_blackboxrc, rc_string); - - string fmodel; - if (screen->isSloppyFocus()) { - fmodel = "SloppyFocus"; - if (screen->doAutoRaise()) fmodel += " AutoRaise"; - if (screen->doClickRaise()) fmodel += " ClickRaise"; - } else { - fmodel = "ClickToFocus"; - } - sprintf(rc_string, "session.screen%d.focusModel: %s", screen_number, - fmodel.c_str()); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.screen%d.workspaces: %d", screen_number, - screen->getWorkspaceCount()); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.screen%d.toolbar.onTop: %s", screen_number, - ((screen->getToolbar()->isOnTop()) ? "True" : "False")); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.screen%d.toolbar.autoHide: %s", - screen_number, - ((screen->getToolbar()->doAutoHide()) ? "True" : "False")); - XrmPutLineResource(&new_blackboxrc, rc_string); - - switch (screen->getToolbarPlacement()) { - case Toolbar::TopLeft: placement = "TopLeft"; break; - case Toolbar::BottomLeft: placement = "BottomLeft"; break; - case Toolbar::TopCenter: placement = "TopCenter"; break; - case Toolbar::TopRight: placement = "TopRight"; break; - case Toolbar::BottomRight: placement = "BottomRight"; break; - case Toolbar::BottomCenter: default: placement = "BottomCenter"; break; - } - sprintf(rc_string, "session.screen%d.toolbar.placement: %s", - screen_number, placement); - XrmPutLineResource(&new_blackboxrc, rc_string); - - load_rc(screen); - - // these are static, but may not be saved in the users .blackboxrc, - // writing these resources will allow the user to edit them at a later - // time... but loading the defaults before saving allows us to rewrite the - // users changes... - -#ifdef HAVE_STRFTIME - sprintf(rc_string, "session.screen%d.strftimeFormat: %s", screen_number, - screen->getStrftimeFormat()); - XrmPutLineResource(&new_blackboxrc, rc_string); -#else // !HAVE_STRFTIME - sprintf(rc_string, "session.screen%d.dateFormat: %s", screen_number, - ((screen->getDateFormat() == B_EuropeanDate) ? - "European" : "American")); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.screen%d.clockFormat: %d", screen_number, - ((screen->isClock24Hour()) ? 24 : 12)); - XrmPutLineResource(&new_blackboxrc, rc_string); -#endif // HAVE_STRFTIME - - sprintf(rc_string, "session.screen%d.edgeSnapThreshold: %d", - screen_number, screen->getEdgeSnapThreshold()); - XrmPutLineResource(&new_blackboxrc, rc_string); - - sprintf(rc_string, "session.screen%d.toolbar.widthPercent: %d", - screen_number, screen->getToolbarWidthPercent()); - XrmPutLineResource(&new_blackboxrc, rc_string); - - // write out the user's workspace names - - string save_string = screen->getWorkspace(0)->getName(); - for (unsigned int i = 1; i < screen->getWorkspaceCount(); ++i) { - save_string += ','; - save_string += screen->getWorkspace(i)->getName(); - } +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 +} - char *resource_string = new char[save_string.length() + 48]; - sprintf(resource_string, "session.screen%d.workspaceNames: %s", - screen_number, save_string.c_str()); - XrmPutLineResource(&new_blackboxrc, resource_string); - delete [] resource_string; - } +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 - XrmDatabase old_blackboxrc = XrmGetFileDatabase(rc_file.c_str()); + +/* + * Save all values as they are so that the defaults will be written to the rc + * file + */ +void Blackbox::save_rc(void) { + config.setAutoSave(false); + + config.setValue("session.colorsPerChannel", resource.colors_per_channel); + config.setValue("session.doubleClickInterval", + resource.double_click_interval); + config.setValue("session.autoRaiseDelay", + ((resource.auto_raise_delay.tv_sec * 1000) + + (resource.auto_raise_delay.tv_usec / 1000))); + config.setValue("session.cacheLife", resource.cache_life / 60000); + 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 - XrmMergeDatabases(new_blackboxrc, &old_blackboxrc); - XrmPutFileDatabase(old_blackboxrc, rc_file.c_str()); - XrmDestroyDatabase(old_blackboxrc); + std::for_each(screenList.begin(), screenList.end(), + std::mem_fun(&BScreen::save_rc)); + + config.setAutoSave(true); + config.save(); } void Blackbox::load_rc(void) { - XrmDatabase database = (XrmDatabase) 0; - - database = XrmGetFileDatabase(rc_file.c_str()); - - XrmValue value; - char *value_type; - int int_value; - unsigned long long_value; - - if (XrmGetResource(database, "session.menuFile", "Session.MenuFile", - &value_type, &value)) { - resource.menu_file = expandTilde(value.addr); - } else { - resource.menu_file = DEFAULTMENU; - } - - resource.colors_per_channel = 4; - if (XrmGetResource(database, "session.colorsPerChannel", - "Session.ColorsPerChannel", &value_type, &value) && - sscanf(value.addr, "%d", &int_value) == 1) { - resource.colors_per_channel = int_value; - if (resource.colors_per_channel < 2) resource.colors_per_channel = 2; - if (resource.colors_per_channel > 6) resource.colors_per_channel = 6; - } - - if (XrmGetResource(database, "session.styleFile", "Session.StyleFile", - &value_type, &value)) - resource.style_file = expandTilde(value.addr); + if (! config.load()) + config.create(); + + string s; + + if (! config.getValue("session.colorsPerChannel", + resource.colors_per_channel)) + resource.colors_per_channel = 4; + if (resource.colors_per_channel < 2) resource.colors_per_channel = 2; + else if (resource.colors_per_channel > 6) resource.colors_per_channel = 6; + + if (config.getValue("session.styleFile", s)) + resource.style_file = expandTilde(s); else resource.style_file = DEFAULTSTYLE; - resource.double_click_interval = 250; - if (XrmGetResource(database, "session.doubleClickInterval", - "Session.DoubleClickInterval", &value_type, &value) && - sscanf(value.addr, "%lu", &long_value) == 1) { - resource.double_click_interval = long_value; - } - - resource.auto_raise_delay.tv_usec = 400; - if (XrmGetResource(database, "session.autoRaiseDelay", - "Session.AutoRaiseDelay", &value_type, &value) && - sscanf(value.addr, "%lu", &long_value) == 1) { - resource.auto_raise_delay.tv_usec = long_value; - } + if (! config.getValue("session.doubleClickInterval", + resource.double_click_interval)); + resource.double_click_interval = 250; + if (! config.getValue("session.autoRaiseDelay", + resource.auto_raise_delay.tv_usec)) + resource.auto_raise_delay.tv_usec = 400; resource.auto_raise_delay.tv_sec = resource.auto_raise_delay.tv_usec / 1000; resource.auto_raise_delay.tv_usec -= (resource.auto_raise_delay.tv_sec * 1000); resource.auto_raise_delay.tv_usec *= 1000; - resource.cache_life = 5l; - if (XrmGetResource(database, "session.cacheLife", "Session.CacheLife", - &value_type, &value) && - sscanf(value.addr, "%lu", &long_value) == 1) { - resource.cache_life = long_value; - } + if (! config.getValue("session.cacheLife", resource.cache_life)) + resource.cache_life = 5; resource.cache_life *= 60000; - resource.cache_max = 200; - if (XrmGetResource(database, "session.cacheMax", "Session.CacheMax", - &value_type, &value) && - sscanf(value.addr, "%lu", &long_value) == 1) { - resource.cache_max = long_value; + if (! config.getValue("session.cacheMax", resource.cache_max)) + resource.cache_max = 200; + + 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; } -} - - -void Blackbox::load_rc(BScreen *screen) { - XrmDatabase database = (XrmDatabase) 0; - - database = XrmGetFileDatabase(rc_file.c_str()); - - XrmValue value; - char *value_type, name_lookup[1024], class_lookup[1024]; - int screen_number = screen->getScreenNumber(); - int int_value; - - sprintf(name_lookup, "session.screen%d.fullMaximization", screen_number); - sprintf(class_lookup, "Session.Screen%d.FullMaximization", screen_number); - screen->saveFullMax(False); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value) && - ! strncasecmp(value.addr, "true", value.size)) { - screen->saveFullMax(True); - } - - sprintf(name_lookup, "session.screen%d.focusNewWindows", screen_number); - sprintf(class_lookup, "Session.Screen%d.FocusNewWindows", screen_number); - screen->saveFocusNew(False); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value) && - ! strncasecmp(value.addr, "true", value.size)) { - screen->saveFocusNew(True); - } - - sprintf(name_lookup, "session.screen%d.focusLastWindow", screen_number); - sprintf(class_lookup, "Session.Screen%d.focusLastWindow", screen_number); - screen->saveFocusLast(False); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value) && - ! strncasecmp(value.addr, "true", value.size)) { - screen->saveFocusLast(True); - } - - sprintf(name_lookup, "session.screen%d.rowPlacementDirection", - screen_number); - sprintf(class_lookup, "Session.Screen%d.RowPlacementDirection", - screen_number); - screen->saveRowPlacementDirection(BScreen::LeftRight); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value) && - ! strncasecmp(value.addr, "righttoleft", value.size)) { - screen->saveRowPlacementDirection(BScreen::RightLeft); - } - - sprintf(name_lookup, "session.screen%d.colPlacementDirection", - screen_number); - sprintf(class_lookup, "Session.Screen%d.ColPlacementDirection", - screen_number); - screen->saveColPlacementDirection(BScreen::TopBottom); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value) && - ! strncasecmp(value.addr, "bottomtotop", value.size)) { - screen->saveColPlacementDirection(BScreen::BottomTop); - } - - sprintf(name_lookup, "session.screen%d.workspaces", screen_number); - sprintf(class_lookup, "Session.Screen%d.Workspaces", screen_number); - screen->saveWorkspaces(1); - if (XrmGetResource(database, name_lookup, class_lookup, - &value_type, &value) && - sscanf(value.addr, "%d", &int_value) == 1 && - int_value > 0 && int_value < 128) { - screen->saveWorkspaces(int_value); - } - - sprintf(name_lookup, "session.screen%d.toolbar.widthPercent", - screen_number); - sprintf(class_lookup, "Session.Screen%d.Toolbar.WidthPercent", - screen_number); - screen->saveToolbarWidthPercent(66); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value) && - sscanf(value.addr, "%d", &int_value) == 1 && - int_value > 0 && int_value <= 100) { - screen->saveToolbarWidthPercent(int_value); - } - - sprintf(name_lookup, "session.screen%d.toolbar.placement", screen_number); - sprintf(class_lookup, "Session.Screen%d.Toolbar.Placement", screen_number); - screen->saveToolbarPlacement(Toolbar::BottomCenter); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value)) { - if (! strncasecmp(value.addr, "TopLeft", value.size)) - screen->saveToolbarPlacement(Toolbar::TopLeft); - else if (! strncasecmp(value.addr, "BottomLeft", value.size)) - screen->saveToolbarPlacement(Toolbar::BottomLeft); - else if (! strncasecmp(value.addr, "TopCenter", value.size)) - screen->saveToolbarPlacement(Toolbar::TopCenter); - else if (! strncasecmp(value.addr, "TopRight", value.size)) - screen->saveToolbarPlacement(Toolbar::TopRight); - else if (! strncasecmp(value.addr, "BottomRight", value.size)) - screen->saveToolbarPlacement(Toolbar::BottomRight); - } - screen->removeWorkspaceNames(); - - sprintf(name_lookup, "session.screen%d.workspaceNames", screen_number); - sprintf(class_lookup, "Session.Screen%d.WorkspaceNames", screen_number); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value)) { - string search = value.addr; - string::const_iterator it = search.begin(), - end = search.end(); - while (1) { - string::const_iterator tmp = it; // current string.begin() - it = std::find(tmp, end, ','); // look for comma between tmp and end - screen->addWorkspaceName(string(tmp, it)); // string = search[tmp:it] - if (it == end) break; - ++it; - } - } - - sprintf(name_lookup, "session.screen%d.toolbar.onTop", screen_number); - sprintf(class_lookup, "Session.Screen%d.Toolbar.OnTop", screen_number); - screen->saveToolbarOnTop(False); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value) && - ! strncasecmp(value.addr, "true", value.size)) { - screen->saveToolbarOnTop(True); - } - - sprintf(name_lookup, "session.screen%d.toolbar.autoHide", screen_number); - sprintf(class_lookup, "Session.Screen%d.Toolbar.autoHide", screen_number); - screen->saveToolbarAutoHide(False); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value) && - ! strncasecmp(value.addr, "true", value.size)) { - screen->saveToolbarAutoHide(True); - } - - sprintf(name_lookup, "session.screen%d.focusModel", screen_number); - sprintf(class_lookup, "Session.Screen%d.FocusModel", screen_number); - screen->saveSloppyFocus(True); - screen->saveAutoRaise(False); - screen->saveClickRaise(False); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value)) { - string fmodel = value.addr; - - if (fmodel.find("ClickToFocus") != string::npos) { - screen->saveSloppyFocus(False); - } else { - // must be sloppy - - if (fmodel.find("AutoRaise") != string::npos) - screen->saveAutoRaise(True); - if (fmodel.find("ClickRaise") != string::npos) - screen->saveClickRaise(True); - } - } - - sprintf(name_lookup, "session.screen%d.windowPlacement", screen_number); - sprintf(class_lookup, "Session.Screen%d.WindowPlacement", screen_number); - screen->savePlacementPolicy(BScreen::RowSmartPlacement); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value)) { - if (! strncasecmp(value.addr, "RowSmartPlacement", value.size)) - /* pass */; - else if (! strncasecmp(value.addr, "ColSmartPlacement", value.size)) - screen->savePlacementPolicy(BScreen::ColSmartPlacement); - else if (! strncasecmp(value.addr, "CascadePlacement", value.size)) - screen->savePlacementPolicy(BScreen::CascadePlacement); - } - - sprintf(name_lookup, "session.screen%d.slit.placement", screen_number); - sprintf(class_lookup, "Session.Screen%d.Slit.Placement", screen_number); - screen->saveSlitPlacement(Slit::CenterRight); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value)) { - if (! strncasecmp(value.addr, "TopLeft", value.size)) - screen->saveSlitPlacement(Slit::TopLeft); - else if (! strncasecmp(value.addr, "CenterLeft", value.size)) - screen->saveSlitPlacement(Slit::CenterLeft); - else if (! strncasecmp(value.addr, "BottomLeft", value.size)) - screen->saveSlitPlacement(Slit::BottomLeft); - else if (! strncasecmp(value.addr, "TopCenter", value.size)) - screen->saveSlitPlacement(Slit::TopCenter); - else if (! strncasecmp(value.addr, "BottomCenter", value.size)) - screen->saveSlitPlacement(Slit::BottomCenter); - else if (! strncasecmp(value.addr, "TopRight", value.size)) - screen->saveSlitPlacement(Slit::TopRight); - else if (! strncasecmp(value.addr, "BottomRight", value.size)) - screen->saveSlitPlacement(Slit::BottomRight); - } - - sprintf(name_lookup, "session.screen%d.slit.direction", screen_number); - sprintf(class_lookup, "Session.Screen%d.Slit.Direction", screen_number); - screen->saveSlitDirection(Slit::Vertical); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value) && - ! strncasecmp(value.addr, "Horizontal", value.size)) { - screen->saveSlitDirection(Slit::Horizontal); - } - - sprintf(name_lookup, "session.screen%d.slit.onTop", screen_number); - sprintf(class_lookup, "Session.Screen%d.Slit.OnTop", screen_number); - screen->saveSlitOnTop(False); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value) && - ! strncasecmp(value.addr, "True", value.size)) { - screen->saveSlitOnTop(True); - } - - sprintf(name_lookup, "session.screen%d.slit.autoHide", screen_number); - sprintf(class_lookup, "Session.Screen%d.Slit.AutoHide", screen_number); - screen->saveSlitAutoHide(False); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value) && - ! strncasecmp(value.addr, "true", value.size)) { - screen->saveSlitAutoHide(True); - } - -#ifdef HAVE_STRFTIME - sprintf(name_lookup, "session.screen%d.strftimeFormat", screen_number); - sprintf(class_lookup, "Session.Screen%d.StrftimeFormat", screen_number); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value)) { - screen->saveStrftimeFormat(value.addr); - } else { - screen->saveStrftimeFormat("%I:%M %p"); - } -#else // HAVE_STRFTIME - sprintf(name_lookup, "session.screen%d.dateFormat", screen_number); - sprintf(class_lookup, "Session.Screen%d.DateFormat", screen_number); - screen->saveDateFormat(B_AmericanDate); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value)) { - if (! strncasecmp(value.addr, "european", value.size)) - screen->saveDateFormat(B_EuropeanDate); - } - - sprintf(name_lookup, "session.screen%d.clockFormat", screen_number); - sprintf(class_lookup, "Session.Screen%d.ClockFormat", screen_number); - screen->saveClock24Hour(False); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value) && - sscanf(value.addr, "%d", &int_value) == 1 && int_value == 24) { - screen->saveClock24Hour(True); - } -#endif // HAVE_STRFTIME - - sprintf(name_lookup, "session.screen%d.edgeSnapThreshold", screen_number); - sprintf(class_lookup, "Session.Screen%d.EdgeSnapThreshold", screen_number); - if (XrmGetResource(database, name_lookup, class_lookup, &value_type, - &value) && - sscanf(value.addr, "%d", &int_value) == 1) { - screen->saveEdgeSnapThreshold(int_value); - } - - screen->saveImageDither(True); - if (XrmGetResource(database, "session.imageDither", "Session.ImageDither", - &value_type, &value) && - ! strncasecmp("false", value.addr, value.size)) { - screen->saveImageDither(False); - } - - screen->saveOpaqueMove(False); - if (XrmGetResource(database, "session.opaqueMove", "Session.OpaqueMove", - &value_type, &value) && - ! strncasecmp("true", value.addr, value.size)) { - screen->saveOpaqueMove(True); - } - - XrmDestroyDatabase(database); -} - - -void Blackbox::reload_rc(void) { - load_rc(); - reconfigure(); + 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(); @@ -1528,20 +1308,8 @@ void Blackbox::reconfigure(void) { void Blackbox::real_reconfigure(void) { - XrmDatabase new_blackboxrc = (XrmDatabase) 0; - char *style = new char[resource.style_file.length() + 20]; - - sprintf(style, "session.styleFile: %s", getStyleFilename()); - XrmPutLineResource(&new_blackboxrc, style); - - delete [] style; - - XrmDatabase old_blackboxrc = XrmGetFileDatabase(rc_file.c_str()); - - XrmMergeDatabases(new_blackboxrc, &old_blackboxrc); - XrmPutFileDatabase(old_blackboxrc, rc_file.c_str()); - if (old_blackboxrc) XrmDestroyDatabase(old_blackboxrc); - + load_rc(); + std::for_each(menuTimestamps.begin(), menuTimestamps.end(), PointerAssassin()); menuTimestamps.clear(); @@ -1592,15 +1360,16 @@ void Blackbox::real_rereadMenu(void) { void Blackbox::saveStyleFilename(const string& filename) { assert(! filename.empty()); resource.style_file = filename; + config.setValue("session.styleFile", resource.style_file); } -void Blackbox::saveMenuFilename(const string& filename) { +void Blackbox::addMenuTimestamp(const string& filename) { assert(! filename.empty()); bool found = False; MenuTimestampList::iterator it = menuTimestamps.begin(); - for (; it != menuTimestamps.end() && !found; ++it) { + for (; it != menuTimestamps.end() && ! found; ++it) { if ((*it)->filename == filename) found = True; } if (! found) { @@ -1629,6 +1398,13 @@ void Blackbox::timeout(void) { } +void Blackbox::setChangingWindow(BlackboxWindow *win) { + // make sure one of the two is null and the other isn't + assert((! changing_window && win) || (! win && changing_window)); + changing_window = win; +} + + void Blackbox::setFocusedWindow(BlackboxWindow *win) { if (focused_window && focused_window == win) // nothing to do return; @@ -1653,17 +1429,17 @@ void Blackbox::setFocusedWindow(BlackboxWindow *win) { if (active_screen) { // set input focus to the toolbar of the screen with mouse XSetInputFocus(getXDisplay(), - active_screen->getToolbar()->getWindowID(), + active_screen->getRootWindow(), RevertToPointerRoot, CurrentTime); } else { // set input focus to the toolbar of the first managed screen XSetInputFocus(getXDisplay(), - screenList.front()->getToolbar()->getWindowID(), + screenList.front()->getRootWindow(), RevertToPointerRoot, CurrentTime); } } else { // set input focus to the toolbar of the last screen - XSetInputFocus(getXDisplay(), old_screen->getToolbar()->getWindowID(), + XSetInputFocus(getXDisplay(), old_screen->getRootWindow(), RevertToPointerRoot, CurrentTime); } }