X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Fblackbox.cc;h=8dc7db838ff04656c43e2f3060176a055ec47347;hb=a0cf45a0ef5f7e2cbf0833f4d8655131912400cc;hp=266d0e7318a6b1ffa807a48699e4e7b899eada73;hpb=a7db565c75f316fd04ccb04004b58f6378af63c9;p=chaz%2Fopenbox diff --git a/src/blackbox.cc b/src/blackbox.cc index 266d0e73..8dc7db83 100644 --- a/src/blackbox.cc +++ b/src/blackbox.cc @@ -145,6 +145,12 @@ Blackbox::Blackbox(char **m_argv, char *dpy_name, char *rc, char *menu) ::blackbox = this; argv = m_argv; + + // 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); @@ -156,17 +162,18 @@ Blackbox::Blackbox(char **m_argv, char *dpy_name, char *rc, char *menu) 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(); - xatom = new XAtom(this); + 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); @@ -320,7 +327,20 @@ 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->setInputFocus(); + } else { BScreen *screen = searchScreen(e->xmaprequest.parent); if (! screen) { @@ -356,11 +376,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; @@ -369,6 +392,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))) { @@ -377,6 +401,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; @@ -432,13 +458,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; } @@ -464,7 +490,8 @@ void Blackbox::process_event(XEvent *e) { screen->getImageControl()->installRootColormap(); } else if ((win = searchWindow(e->xcrossing.window))) { if (win->getScreen()->isSloppyFocus() && - (! win->isFocused()) && (! no_focus)) { + (! 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? @@ -656,6 +683,7 @@ void Blackbox::process_event(XEvent *e) { case ClientMessage: { if (e->xclient.format == 32) { 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; @@ -663,19 +691,46 @@ 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, True); + if (win->isShaded()) + win->shade(); + if (win->getWorkspaceNumber() != screen->getCurrentWorkspaceID()) + 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) { @@ -684,7 +739,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()) { @@ -697,6 +777,171 @@ 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()); + } + } + } + } } } @@ -726,10 +971,13 @@ void Blackbox::process_event(XEvent *e) { bool Blackbox::handleSignal(int sig) { switch (sig) { case SIGHUP: - case SIGUSR1: reconfigure(); break; + case SIGUSR1: + restart(); + break; + case SIGUSR2: rereadMenu(); break; @@ -774,6 +1022,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()) @@ -819,6 +1076,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)); } @@ -844,6 +1106,11 @@ void Blackbox::saveSlitSearch(Window window, Slit *data) { } +void Blackbox::removeSystrayWindowSearch(Window window) { + systraySearchList.erase(window); +} + + void Blackbox::removeWindowSearch(Window window) { windowSearchList.erase(window); } @@ -873,6 +1140,7 @@ void Blackbox::restart(const char *prog) { shutdown(); if (prog) { + putenv(const_cast(screenList.front()->displayString().c_str())); execlp(prog, prog, NULL); perror(prog); } @@ -896,18 +1164,6 @@ void Blackbox::shutdown(void) { } -void Blackbox::saveWindowToWindowSnap(bool s) { - resource.window_to_window_snap = s; - config.setValue("session.windowToWindowSnap", resource.window_to_window_snap); -} - - -void Blackbox::saveWindowCornerSnap(bool s) { - resource.window_corner_snap = s; - config.setValue("session.windowCornerSnap", resource.window_corner_snap); -} - - /* * Save all values as they are so that the defaults will be written to the rc * file @@ -925,8 +1181,6 @@ void Blackbox::save_rc(void) { config.setValue("session.cacheMax", resource.cache_max); config.setValue("session.styleFile", resource.style_file); config.setValue("session.titlebarLayout", resource.titlebar_layout); - saveWindowToWindowSnap(resource.window_to_window_snap); - saveWindowCornerSnap(resource.window_corner_snap); std::for_each(screenList.begin(), screenList.end(), std::mem_fun(&BScreen::save_rc)); @@ -938,7 +1192,7 @@ void Blackbox::save_rc(void) { void Blackbox::load_rc(void) { if (! config.load()) - config.create(); + config.create(); string s; @@ -974,14 +1228,6 @@ void Blackbox::load_rc(void) { if (! config.getValue("session.titlebarLayout", resource.titlebar_layout)) resource.titlebar_layout = "ILMC"; - - if (! config.getValue("session.windowToWindowSnap", - resource.window_to_window_snap)) - resource.window_to_window_snap = true; - - if (! config.getValue("session.windowCornerSnap", - resource.window_corner_snap)) - resource.window_corner_snap = true; } @@ -1083,6 +1329,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;