X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fblackbox.cc;h=00a640381530341f1974dacc5a92334ac9bb79fd;hb=ffa4c7f3414944869016497a4f560c24b9d8b3e9;hp=56782248dddd5b9a3ef6802df26ef17e8f20cd0c;hpb=e90fafd2fd907a81bdc60ad8b6de35fc1595cdff;p=chaz%2Fopenbox diff --git a/src/blackbox.cc b/src/blackbox.cc index 56782248..00a64038 100644 --- a/src/blackbox.cc +++ b/src/blackbox.cc @@ -111,6 +111,7 @@ using std::string; #include "Workspace.hh" #include "Workspacemenu.hh" #include "XAtom.hh" +#include "Input.hh" // X event scanner for enter/leave notifies - adapted from twm struct scanargs { @@ -156,17 +157,20 @@ 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()); + input = new BInput(this); 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); @@ -356,11 +360,16 @@ 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); + } else if ((screen = searchDesktopWindow(e->xunmap.window))) { + screen->removeDesktopWindow(e->xunmap.window); } break; @@ -369,6 +378,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 +387,10 @@ 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); + } else if ((screen = searchDesktopWindow(e->xunmap.window))) { + screen->removeDesktopWindow(e->xunmap.window); } break; @@ -656,6 +670,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,18 +678,35 @@ 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); unsigned int workspace = e->xclient.data.l[0]; if (screen && workspace < screen->getWorkspaceCount()) screen->changeWorkspaceID(workspace); - } else if (e->xclient.message_type == getBlackboxChangeWindowFocusAtom()) { + } else if (e->xclient.message_type == + xatom->getAtom(XAtom::blackbox_change_window_focus) || + e->xclient.message_type == + xatom->getAtom(XAtom::net_active_window)) { + // NET_ACTIVE_WINDOW BlackboxWindow *win = searchWindow(e->xclient.window); - if (win && win->isVisible() && win->setInputFocus()) - win->installColormap(True); - } else if (e->xclient.message_type == getBlackboxCycleWindowFocusAtom()) { + if (win) { + if (win->isIconic()) + win->deiconify(False, True); + 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) { @@ -683,7 +715,31 @@ 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!! + 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()) { @@ -696,6 +752,185 @@ 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) { + 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(); + } + } + } 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()); + } + } + } + } } } @@ -773,6 +1008,24 @@ BScreen *Blackbox::searchScreen(Window window) { } +BScreen *Blackbox::searchDesktopWindow(Window window) { + WindowScreenLookup::iterator it = desktopSearchList.find(window); + if (it != desktopSearchList.end()) + return it->second; + + return (BScreen*) 0; +} + + +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()) @@ -818,6 +1071,16 @@ Slit *Blackbox::searchSlit(Window window) { } +void Blackbox::saveDesktopWindowSearch(Window window, BScreen *screen) { + desktopSearchList.insert(WindowScreenLookupPair(window, screen)); +} + + +void Blackbox::saveSystrayWindowSearch(Window window, BScreen *screen) { + systraySearchList.insert(WindowScreenLookupPair(window, screen)); +} + + void Blackbox::saveWindowSearch(Window window, BlackboxWindow *data) { windowSearchList.insert(WindowLookupPair(window, data)); } @@ -843,6 +1106,16 @@ void Blackbox::saveSlitSearch(Window window, Slit *data) { } +void Blackbox::removeDesktopWindowSearch(Window window) { + desktopSearchList.erase(window); +} + + +void Blackbox::removeSystrayWindowSearch(Window window) { + systraySearchList.erase(window); +} + + void Blackbox::removeWindowSearch(Window window) { windowSearchList.erase(window); } @@ -872,6 +1145,7 @@ void Blackbox::restart(const char *prog) { shutdown(); if (prog) { + putenv(const_cast(screenList.front()->displayString().c_str())); execlp(prog, prog, NULL); perror(prog); } @@ -1060,6 +1334,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;