From 2dde696a1335ef61bb368c55f4ee52e1dd8610a1 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 16 Jul 2002 08:00:59 +0000 Subject: [PATCH] much awesome support for special windows like panels/desktops. All 'non-normal' windows are treated equally now, with a fe wexceptionms for the desktop for stacking. Fix some ClicmMousePlacement bugs while we're at it. --- src/Screen.cc | 72 ++++++++++++++++++---------------------- src/Screen.hh | 3 -- src/Window.cc | 85 +++++++++++++++++------------------------------- src/Window.hh | 7 ++-- src/Workspace.cc | 43 +++++++++++++----------- src/Workspace.hh | 2 +- src/blackbox.cc | 26 ++------------- src/blackbox.hh | 5 +-- 8 files changed, 95 insertions(+), 148 deletions(-) diff --git a/src/Screen.cc b/src/Screen.cc index 4df5ea17..e0ef585f 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -312,9 +312,6 @@ BScreen::~BScreen(void) { std::for_each(netizenList.begin(), netizenList.end(), PointerAssassin()); - while (! desktopWindowList.empty()) - removeDesktopWindow(desktopWindowList[0]); - while (! systrayWindowList.empty()) removeSystrayWindow(systrayWindowList[0]); @@ -652,7 +649,7 @@ void BScreen::load_rc(void) { else if (s == "UnderMousePlacement") resource.placement_policy = UnderMousePlacement; else if (s == "ClickMousePlacement") - resource.placement_policy = UnderMousePlacement; + resource.placement_policy = ClickMousePlacement; else if (s == "ColSmartPlacement") resource.placement_policy = ColSmartPlacement; else //if (s == "RowSmartPlacement") @@ -1168,49 +1165,33 @@ void BScreen::removeSystrayWindow(Window window) { } -void BScreen::addDesktopWindow(Window window) { - desktopWindowList.push_back(window); - XLowerWindow(blackbox->getXDisplay(), window); - XSelectInput(blackbox->getXDisplay(), window, StructureNotifyMask); - blackbox->saveDesktopWindowSearch(window, this); -} - - -void BScreen::removeDesktopWindow(Window window) { - WindowList::iterator it = desktopWindowList.begin(); - const WindowList::iterator end = desktopWindowList.end(); - for (; it != end; ++it) - if (*it == window) { - desktopWindowList.erase(it); - XSelectInput(blackbox->getXDisplay(), window, None); - blackbox->removeDesktopWindowSearch(window); - break; - } -} - - void BScreen::manageWindow(Window w) { + // is the window a KDE systray window? + Window systray; + if (xatom->getValue(w, XAtom::kde_net_wm_system_tray_window_for, + XAtom::window, systray) && systray) { + addSystrayWindow(w); + return; + } + new BlackboxWindow(blackbox, w, this); BlackboxWindow *win = blackbox->searchWindow(w); if (! win) return; - if (win->windowType() == BlackboxWindow::Type_Desktop) { - // desktop windows cant do anything, so we remove all the normal window - // stuff from them, they are only kept around so that we can keep them on - // the bottom of the z-order - win->restore(True); - addDesktopWindow(win->getClientWindow()); - delete win; - return; - } - windowList.push_back(win); - updateClientList(); + + if (win->isNormal()) { + // don't list non-normal windows as managed windows + windowList.push_back(win); + updateClientList(); + } else if (win->isDesktop()) { + desktopWindowList.push_back(win->getFrameWindow()); + } XMapRequestEvent mre; mre.window = w; - if (blackbox->isStartup()) win->restoreAttributes(); + if (blackbox->isStartup() && win->isNormal()) win->restoreAttributes(); win->mapRequestEvent(&mre); } @@ -1224,8 +1205,20 @@ void BScreen::unmanageWindow(BlackboxWindow *w, bool remap) { else if (w->isIconic()) removeIcon(w); - windowList.remove(w); - updateClientList(); + if (w->isNormal()) { + // we don't list non-normal windows as managed windows + windowList.remove(w); + updateClientList(); + } else if (w->isDesktop()) { + WindowList::iterator it = desktopWindowList.begin(); + const WindowList::iterator end = desktopWindowList.end(); + for (; it != end; ++it) + if (*it == w->getFrameWindow()) { + desktopWindowList.erase(it); + break; + } + assert(it != end); // the window wasnt a desktop window? + } if (blackbox->getFocusedWindow() == w) blackbox->setFocusedWindow((BlackboxWindow *) 0); @@ -2149,7 +2142,6 @@ void BScreen::buttonPressEvent(const XButtonEvent *xbutton) { void BScreen::propertyNotifyEvent(const XPropertyEvent *pe) { if (pe->atom == xatom->getAtom(XAtom::net_desktop_names)) { // _NET_WM_DESKTOP_NAMES - fprintf(stderr, "UPDATING WORKSPACE NAMES\n"); WorkspaceList::iterator it = workspacesList.begin(); const WorkspaceList::iterator end = workspacesList.end(); for (; it != end; ++it) { diff --git a/src/Screen.hh b/src/Screen.hh index 8f7a26e9..7cbe441a 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -320,9 +320,6 @@ public: void addNetizen(Netizen *n); void removeNetizen(Window w); - void addDesktopWindow(Window window); - void removeDesktopWindow(Window window); - void addSystrayWindow(Window window); void removeSystrayWindow(Window window); diff --git a/src/Window.cc b/src/Window.cc index 90224fe5..a336eaeb 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -152,17 +152,10 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { client.rect.setRect(wattrib.x, wattrib.y, wattrib.width, wattrib.height); client.old_bw = wattrib.border_width; + timer = 0; windowmenu = 0; lastButtonPressTime = 0; - timer = new BTimer(blackbox, this); - timer->setTimeout(blackbox->getAutoRaiseDelay()); - - if (! getBlackboxHints()) { - getMWMHints(); - getNetWMHints(); - } - // get size, aspect, minimum/maximum size and other hints set by the // client getWMProtocols(); @@ -175,10 +168,12 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { return; } - if (isKDESystrayWindow()) { - screen->addSystrayWindow(client.window); - delete this; - return; + timer = new BTimer(blackbox, this); + timer->setTimeout(blackbox->getAutoRaiseDelay()); + + if (! getBlackboxHints()) { + getMWMHints(); + getNetWMHints(); } frame.window = createToplevelWindow(); @@ -199,32 +194,16 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { // adjust the window decorations/behavior based on the window type switch (window_type) { case Type_Desktop: - // desktop windows are not managed by us, we just make sure they stay on the - // bottom. - return; - case Type_Dock: case Type_Menu: - // docks (such as kicker) and menus (as used by kde for the 'desktop menu' - // which mimics apple, cannot be moved, and appear on all workspaces - // also, these have no decorations - functions &= ~(Func_Move); - decorations &= ~Decor_Titlebar; - flags.stuck = True; case Type_Toolbar: case Type_Utility: - // these windows have minimal decorations, only a titlebar, and cannot - // be resized or iconified - decorations &= ~(Decor_Maximize | Decor_Handle | Decor_Border | - Decor_Iconify); - functions &= ~(Func_Resize | Func_Maximize | Func_Iconify); - break; - case Type_Splash: - // splash screens have no functionality or decorations, they are left up - // to the application which created them + // none of these windows are decorated or manipulated by the window manager decorations = 0; functions = 0; + blackbox_attrib.workspace = 0; // we do need to belong to a workspace + flags.stuck = True; // we show up on all workspaces break; case Type_Dialog: @@ -1441,15 +1420,6 @@ void BlackboxWindow::getTransientInfo(void) { } -bool BlackboxWindow::isKDESystrayWindow(void) { - Window systray; - if (xatom->getValue(client.window, XAtom::kde_net_wm_system_tray_window_for, - XAtom::window, systray) && systray) - return True; - return False; -} - - BlackboxWindow *BlackboxWindow::getTransientFor(void) const { if (client.transient_for && client.transient_for != (BlackboxWindow*) ~0ul) @@ -1942,11 +1912,10 @@ void BlackboxWindow::stick(void) { if (! flags.iconic) screen->reassociateWindow(this, BSENTINEL, True); - else - // temporary fix since sticky windows suck. set the hint to what we - // actually hold in our data. - xatom->setValue(client.window, XAtom::net_wm_desktop, XAtom::cardinal, - blackbox_attrib.workspace); + // temporary fix since sticky windows suck. set the hint to what we + // actually hold in our data. + xatom->setValue(client.window, XAtom::net_wm_desktop, XAtom::cardinal, + blackbox_attrib.workspace); setState(current_state); } else { @@ -2538,16 +2507,22 @@ void BlackboxWindow::mapRequestEvent(const XMapRequestEvent *re) { default: show(); screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this); - if (! blackbox->isStartup() && (isTransient() || screen->doFocusNew())) { - XSync(blackbox->getXDisplay(), False); // make sure the frame is mapped.. - setInputFocus(); + if (isNormal()) { + if (! blackbox->isStartup()) { + XSync(blackbox->getXDisplay(), False); // make sure the frame is mapped + if (isTransient() || screen->doFocusNew()) { + setInputFocus(); + } + if (screen->getPlacementPolicy() == BScreen::ClickMousePlacement) { + int x, y, rx, ry; + Window c, r; + unsigned int m; + XQueryPointer(blackbox->getXDisplay(), screen->getRootWindow(), + &r, &c, &rx, &ry, &x, &y, &m); + beginMove(rx, ry); + } + } } - int x, y, rx, ry; - Window c, r; - unsigned int m; - XQueryPointer(screen->getBlackbox()->getXDisplay(), screen->getRootWindow(), - &r, &c, &rx, &ry, &x, &y, &m); - beginMove(rx, ry); break; } } @@ -2742,7 +2717,7 @@ void BlackboxWindow::configureRequestEvent(const XConfigureRequestEvent *cr) { configure(req.x(), req.y(), req.width(), req.height()); } - if (cr->value_mask & CWStackMode) { + if (cr->value_mask & CWStackMode && !isDesktop()) { switch (cr->detail) { case Below: case BottomIf: diff --git a/src/Window.hh b/src/Window.hh index 328b5ffa..c024e5bc 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -267,7 +267,6 @@ private: void getMWMHints(void); bool getBlackboxHints(void); void getTransientInfo(void); - bool isKDESystrayWindow(void); void setNetWMAttributes(void); void associateClientWindow(void); void decorate(void); @@ -321,8 +320,12 @@ public: inline bool isMaximizable(void) const { return functions & Func_Maximize; } inline bool isResizable(void) const { return functions & Func_Resize; } inline bool isClosable(void) const { return functions & Func_Close; } - inline WindowType windowType(void) const { return window_type; } + // is a 'normal' window? meaning, a standard client application + inline bool isNormal(void) const + { return window_type == Type_Dialog || window_type == Type_Normal; } + inline bool isDesktop(void) const { return window_type == Type_Desktop; } + inline bool hasTitlebar(void) const { return decorations & Decor_Titlebar; } inline const BlackboxWindowList &getTransients(void) const diff --git a/src/Workspace.cc b/src/Workspace.cc index 4fd579e4..843f8100 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -79,22 +79,28 @@ void Workspace::addWindow(BlackboxWindow *w, bool place) { if (place) placeWindow(w); - w->setWorkspace(id); - w->setWindowNumber(windowList.size()); - stackingList.push_front(w); - windowList.push_back(w); + + if (w->isNormal()) { + w->setWorkspace(id); + w->setWindowNumber(windowList.size()); - clientmenu->insert(w->getTitle()); - clientmenu->update(); + windowList.push_back(w); + + clientmenu->insert(w->getTitle()); + clientmenu->update(); - screen->updateNetizenWindowAdd(w->getClientWindow(), id); + screen->updateNetizenWindowAdd(w->getClientWindow(), id); + } - raiseWindow(w); + if (! w->isDesktop()) + raiseWindow(w); + else + lowerWindow(w); } -unsigned int Workspace::removeWindow(BlackboxWindow *w) { +void Workspace::removeWindow(BlackboxWindow *w) { assert(w != 0); stackingList.remove(w); @@ -113,6 +119,8 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) { } } + if (! w->isNormal()) return; + windowList.remove(w); clientmenu->remove(w->getWindowNumber()); clientmenu->update(); @@ -127,8 +135,6 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) { if (i == 0) cascade_x = cascade_y = 32; - - return i; } @@ -154,10 +160,7 @@ void Workspace::focusFallback(const BlackboxWindow *old_window) { end = stackingList.end(); for (; it != end; ++it) { BlackboxWindow *tmp = *it; - if (! (tmp->windowType() == BlackboxWindow::Type_Dialog || - tmp->windowType() == BlackboxWindow::Type_Normal)) - continue; // don't fallback to special windows - if (tmp && tmp->setInputFocus()) { + if (tmp && tmp->isNormal() && tmp->setInputFocus()) { // we found our new focus target newfocus = tmp; break; @@ -281,8 +284,10 @@ void Workspace::lowerTransients(const BlackboxWindow * const win, void Workspace::raiseWindow(BlackboxWindow *w) { BlackboxWindow *win = w; + if (win->isDesktop()) return; + // walk up the transient_for's to the window that is not a transient - while (win->isTransient()) { + while (win->isTransient() && ! win->isDesktop()) { if (! win->getTransientFor()) break; win = win->getTransientFor(); } @@ -296,7 +301,7 @@ void Workspace::raiseWindow(BlackboxWindow *w) { *(stack++) = win->getFrameWindow(); screen->updateNetizenWindowRaise(win->getClientWindow()); - if (! win->isIconic()) { + if (! (win->isIconic() || win->isDesktop())) { Workspace *wkspc = screen->getWorkspace(win->getWorkspaceNumber()); wkspc->stackingList.remove(win); wkspc->stackingList.push_front(win); @@ -312,7 +317,7 @@ void Workspace::lowerWindow(BlackboxWindow *w) { BlackboxWindow *win = w; // walk up the transient_for's to the window that is not a transient - while (win->isTransient()) { + while (win->isTransient() && ! win->isDesktop()) { if (! win->getTransientFor()) break; win = win->getTransientFor(); } @@ -328,7 +333,7 @@ void Workspace::lowerWindow(BlackboxWindow *w) { *(stack++) = win->getFrameWindow(); screen->updateNetizenWindowLower(win->getClientWindow()); - if (! win->isIconic()) { + if (! (win->isIconic() || win->isDesktop())) { Workspace *wkspc = screen->getWorkspace(win->getWorkspaceNumber()); wkspc->stackingList.remove(win); wkspc->stackingList.push_back(win); diff --git a/src/Workspace.hh b/src/Workspace.hh index fcf46630..09dc2779 100644 --- a/src/Workspace.hh +++ b/src/Workspace.hh @@ -93,7 +93,7 @@ public: bool isLastWindow(const BlackboxWindow* w) const; void addWindow(BlackboxWindow *w, bool place = False); - unsigned int removeWindow(BlackboxWindow *w); + void removeWindow(BlackboxWindow *w); unsigned int getCount(void) const; void appendStackOrder(BlackboxWindowList &stack_order) const; diff --git a/src/blackbox.cc b/src/blackbox.cc index ba0b0747..71098444 100644 --- a/src/blackbox.cc +++ b/src/blackbox.cc @@ -384,8 +384,6 @@ void Blackbox::process_event(XEvent *e) { 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; @@ -405,8 +403,6 @@ void Blackbox::process_event(XEvent *e) { 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; @@ -494,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? @@ -1038,15 +1035,6 @@ 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()) @@ -1101,11 +1089,6 @@ 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)); } @@ -1136,11 +1119,6 @@ void Blackbox::saveSlitSearch(Window window, Slit *data) { } -void Blackbox::removeDesktopWindowSearch(Window window) { - desktopSearchList.erase(window); -} - - void Blackbox::removeSystrayWindowSearch(Window window) { systraySearchList.erase(window); } diff --git a/src/blackbox.hh b/src/blackbox.hh index 3a9986af..a6e689d7 100644 --- a/src/blackbox.hh +++ b/src/blackbox.hh @@ -123,7 +123,7 @@ private: typedef std::map WindowScreenLookup; typedef WindowScreenLookup::value_type WindowScreenLookupPair; - WindowScreenLookup systraySearchList, desktopSearchList; + WindowScreenLookup systraySearchList; typedef std::map GroupLookup; typedef GroupLookup::value_type GroupLookupPair; @@ -175,7 +175,6 @@ public: Basemenu *searchMenu(Window window); BWindowGroup *searchGroup(Window window); - BScreen *searchDesktopWindow(Window window); BScreen *searchSystrayWindow(Window window); BlackboxWindow *searchWindow(Window window); BScreen *searchScreen(Window window); @@ -183,14 +182,12 @@ public: Slit *searchSlit(Window); void saveMenuSearch(Window window, Basemenu *data); - void saveDesktopWindowSearch(Window window, BScreen *screen); void saveSystrayWindowSearch(Window window, BScreen *screen); void saveWindowSearch(Window window, BlackboxWindow *data); void saveGroupSearch(Window window, BWindowGroup *data); void saveToolbarSearch(Window window, Toolbar *data); void saveSlitSearch(Window window, Slit *data); void removeMenuSearch(Window window); - void removeDesktopWindowSearch(Window window); void removeSystrayWindowSearch(Window window); void removeWindowSearch(Window window); void removeGroupSearch(Window window); -- 2.39.2