From 5ec63388b8fbbdffc0999ba727ad718f87d683fc Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sat, 27 Jul 2002 18:17:45 +0000 Subject: [PATCH] fixes to make sticky windows work better. they appear in all workspace lists, they get focus when switching workspaces properly, their workspace menus show their focus properly. --- src/Screen.cc | 2 + src/Window.cc | 21 ++++++---- src/Workspace.cc | 102 +++++++++++++++++++++++++++++++---------------- src/Workspace.hh | 5 ++- 4 files changed, 86 insertions(+), 44 deletions(-) diff --git a/src/Screen.cc b/src/Screen.cc index 13916bae..b6c05619 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -1516,6 +1516,8 @@ void BScreen::reassociateWindow(BlackboxWindow *w, unsigned int wkspc_id, removeIcon(w); getWorkspace(wkspc_id)->addWindow(w); } else if (ignore_sticky || ! w->isStuck()) { + if (w->isStuck()) + w->stick(); getWorkspace(w->getWorkspaceNumber())->removeWindow(w); getWorkspace(wkspc_id)->addWindow(w); } diff --git a/src/Window.cc b/src/Window.cc index 1662484a..2d183749 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -1963,6 +1963,10 @@ void BlackboxWindow::stick(void) { blackbox_attrib.flags ^= AttribOmnipresent; blackbox_attrib.attrib ^= AttribOmnipresent; + for (unsigned int i = 0; i < screen->getNumberOfWorkspaces(); ++i) + if (i != blackbox_attrib.workspace) + screen->getWorkspace(i)->removeWindow(this, True); + flags.stuck = False; if (! flags.iconic) @@ -1972,11 +1976,6 @@ void BlackboxWindow::stick(void) { xatom->setValue(client.window, XAtom::net_wm_desktop, XAtom::cardinal, blackbox_attrib.workspace); - for (unsigned int i = 0; i < screen->getNumberOfWorkspaces(); ++i) - if (i != blackbox_attrib.workspace) - if (screen->getWorkspace(i)->getLastFocusedWindow() == this) - screen->getWorkspace(i)->focusFallback(this); - setState(current_state); } else { flags.stuck = True; @@ -1988,6 +1987,10 @@ void BlackboxWindow::stick(void) { // value than that contained in the class' data. xatom->setValue(client.window, XAtom::net_wm_desktop, XAtom::cardinal, 0xffffffff); + + for (unsigned int i = 0; i < screen->getNumberOfWorkspaces(); ++i) + if (i != blackbox_attrib.workspace) + screen->getWorkspace(i)->addWindow(this, False, True); setState(current_state); } @@ -2102,9 +2105,11 @@ void BlackboxWindow::setFocusFlag(bool focus) { if (! flags.iconic) { // iconic windows arent in a workspace menu! - Clientmenu *menu = - screen->getWorkspace(blackbox_attrib.workspace)->getMenu(); - menu->setItemSelected(window_number, isFocused()); + if (flags.stuck) + screen->getCurrentWorkspace()->setFocused(this, isFocused()); + else + screen->getWorkspace(blackbox_attrib.workspace)-> + setFocused(this, flags.focused); } } diff --git a/src/Workspace.cc b/src/Workspace.cc index a7887945..88541b07 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -78,32 +78,47 @@ Workspace::Workspace(BScreen *scrn, unsigned int i) { } -void Workspace::addWindow(BlackboxWindow *w, bool place) { +void Workspace::addWindow(BlackboxWindow *w, bool place, bool sticky) { assert(w != 0); if (place) placeWindow(w); stackingList.push_front(w); + // if the window is sticky, then it needs to be added on all other + // workspaces too! + if (! sticky && w->isStuck()) { + for (unsigned int i = 0; i < screen->getWorkspaceCount(); ++i) + if (i != id) + screen->getWorkspace(i)->addWindow(w, place, True); + } + if (w->isNormal()) { - w->setWorkspace(id); - w->setWindowNumber(windowList.size()); + if (! sticky) { + w->setWorkspace(id); + w->setWindowNumber(windowList.size()); + } windowList.push_back(w); clientmenu->insert(w->getTitle()); clientmenu->update(); - screen->updateNetizenWindowAdd(w->getClientWindow(), id); - - if (id != screen->getCurrentWorkspaceID() && - screen->doFocusNew()) { - /* - not on the focused workspace, so the window is not going to get focus - but if the user wants new windows focused, then it should get focus - when this workspace does become focused. - */ - lastfocus = w; + if (! sticky) + screen->updateNetizenWindowAdd(w->getClientWindow(), id); + + if (screen->doFocusNew() || (w->isTransient() && w->getTransientFor() && + w->getTransientFor()->isFocused())) { + if (id == screen->getCurrentWorkspaceID()) + w->setInputFocus(); + else { + /* + not on the focused workspace, so the window is not going to get focus + but if the user wants new windows focused, then it should get focus + when this workspace does become focused. + */ + lastfocus = w; + } } } @@ -114,7 +129,7 @@ void Workspace::addWindow(BlackboxWindow *w, bool place) { } -void Workspace::removeWindow(BlackboxWindow *w) { +void Workspace::removeWindow(BlackboxWindow *w, bool sticky) { assert(w != 0); stackingList.remove(w); @@ -123,29 +138,38 @@ void Workspace::removeWindow(BlackboxWindow *w) { if ((w->isFocused() || w == lastfocus) && ! screen->getBlackbox()->doShutdown()) { focusFallback(w); - - // if the window is sticky, then it needs to be removed on all other - // workspaces too! - if (w->isStuck()) { - for (unsigned int i = 0; i < screen->getWorkspaceCount(); ++i) - if (i != id) - screen->getWorkspace(i)->focusFallback(w); - } + } + + // if the window is sticky, then it needs to be removed on all other + // workspaces too! + if (! sticky && w->isStuck()) { + for (unsigned int i = 0; i < screen->getWorkspaceCount(); ++i) + if (i != id) + screen->getWorkspace(i)->removeWindow(w, True); } if (! w->isNormal()) return; - windowList.remove(w); - clientmenu->remove(w->getWindowNumber()); + BlackboxWindowList::iterator it, end = windowList.end(); + int i; + for (i = 0, it = windowList.begin(); it != end; ++it, ++i) + if (*it == w) + break; + assert(it != end); + + windowList.erase(it); + clientmenu->remove(i); clientmenu->update(); - screen->updateNetizenWindowDel(w->getClientWindow()); + if (! sticky) { + screen->updateNetizenWindowDel(w->getClientWindow()); - BlackboxWindowList::iterator it = windowList.begin(); - const BlackboxWindowList::iterator end = windowList.end(); - unsigned int i = 0; - for (; it != end; ++it, ++i) - (*it)->setWindowNumber(i); + BlackboxWindowList::iterator it = windowList.begin(); + const BlackboxWindowList::iterator end = windowList.end(); + unsigned int i = 0; + for (; it != end; ++it, ++i) + (*it)->setWindowNumber(i); + } if (i == 0) { cascade_x = cascade_y = 0; @@ -201,13 +225,24 @@ void Workspace::focusFallback(const BlackboxWindow *old_window) { } +void Workspace::setFocused(const BlackboxWindow *w, bool focused) { + BlackboxWindowList::iterator it, end = windowList.end(); + int i; + for (i = 0, it = windowList.begin(); it != end; ++it, ++i) + if (*it == w) + break; + assert(it != end); + + clientmenu->setItemSelected(i, focused); +} + + void Workspace::showAll(void) { BlackboxWindowList::iterator it = stackingList.begin(); const BlackboxWindowList::iterator end = stackingList.end(); for (; it != end; ++it) { BlackboxWindow *bw = *it; - if (! bw->isStuck()) - bw->show(); + bw->show(); } } @@ -220,8 +255,7 @@ void Workspace::hideAll(void) { BlackboxWindow *bw = *it; ++it; // withdraw removes the current item from the list so we need the next // iterator before that happens - if (! bw->isStuck()) - bw->withdraw(); + bw->withdraw(); } } diff --git a/src/Workspace.hh b/src/Workspace.hh index 7934308d..819b6391 100644 --- a/src/Workspace.hh +++ b/src/Workspace.hh @@ -91,12 +91,13 @@ public: BlackboxWindow* getTopWindowOnStack(void) const; void sendWindowList(Netizen &n); void focusFallback(const BlackboxWindow *old_window); + void setFocused(const BlackboxWindow *w, bool focused); bool isCurrent(void) const; bool isLastWindow(const BlackboxWindow* w) const; - void addWindow(BlackboxWindow *w, bool place = False); - void removeWindow(BlackboxWindow *w); + void addWindow(BlackboxWindow *w, bool place = False, bool sticky = False); + void removeWindow(BlackboxWindow *w, bool sticky = False); unsigned int getCount(void) const; void appendStackOrder(BlackboxWindowList &stack_order) const; -- 2.39.2