X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2FWorkspace.cc;h=88280a1d32eaeb9260069d4e816d742c879c4129;hb=90dbcb271c5e6d7ca73c19a519b93885b833db0a;hp=90a83b2678a43a531dd78f214b668b2fb1055299;hpb=e15e4a9e03dd7b64004b76ca84b07c12c251f67b;p=chaz%2Fopenbox diff --git a/src/Workspace.cc b/src/Workspace.cc index 90a83b26..88280a1d 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -70,7 +70,7 @@ Workspace::Workspace(BScreen *scrn, unsigned int i) { lastfocus = (BlackboxWindow *) 0; - setName(""); + readName(); } @@ -102,39 +102,14 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) { // pass focus to the next appropriate window if ((w->isFocused() || w == lastfocus) && ! screen->getBlackbox()->doShutdown()) { - BlackboxWindow *newfocus = 0; - if (w->isTransient()) { - newfocus = w->getTransientFor(); - if (newfocus && - (newfocus->isIconic() || // do not focus icons - newfocus->getWorkspaceNumber() != id)) // or other workspaces - newfocus = 0; - } - if (! newfocus && ! stackingList.empty()) - newfocus = stackingList.front(); - - assert(newfocus != w); // this would be very wrong. - - if (id == screen->getCurrentWorkspaceID()) { - /* - if the window is on the visible workspace, then try focus it, and fall - back to the default focus target if the window won't focus. - */ - if (! (newfocus && newfocus->setInputFocus())) - screen->getBlackbox()->setFocusedWindow(0); - } else if (lastfocus == w) { - /* - If this workspace is not the current one do not assume that - w == lastfocus. If a sticky window is removed on a workspace other - than where it originated, it will fire the removeWindow on a - non-visible workspace. - */ - - /* - If the window isn't on the visible workspace, don't focus the new one, - just mark it to be focused when the workspace comes into view. - */ - setLastFocusedWindow(newfocus); + 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); } } @@ -157,6 +132,51 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) { } +void Workspace::focusFallback(const BlackboxWindow *old_window) { + BlackboxWindow *newfocus = 0; + + if (id == screen->getCurrentWorkspaceID()) { + // The window is on the visible workspace. + + // if it's a transient, then try to focus its parent + if (old_window && old_window->isTransient()) { + newfocus = old_window->getTransientFor(); + + if (! newfocus || + newfocus->isIconic() || // do not focus icons + newfocus->getWorkspaceNumber() != id || // or other workspaces + ! newfocus->setInputFocus()) + newfocus = 0; + } + + if (! newfocus) { + BlackboxWindowList::iterator it = stackingList.begin(), + end = stackingList.end(); + for (; it != end; ++it) { + BlackboxWindow *tmp = *it; + if (tmp && tmp->setInputFocus()) { + // we found our new focus target + newfocus = tmp; + break; + } + } + } + + screen->getBlackbox()->setFocusedWindow(newfocus); + } else { + // The window is not on the visible workspace. + + if (old_window && lastfocus == old_window) { + // The window was the last-focus target, so we need to replace it. + BlackboxWindow *win = (BlackboxWindow*) 0; + if (! stackingList.empty()) + win = stackingList.front(); + setLastFocusedWindow(win); + } + } +} + + void Workspace::showAll(void) { std::for_each(stackingList.begin(), stackingList.end(), std::mem_fun(&BlackboxWindow::show)); @@ -311,10 +331,7 @@ void Workspace::lowerWindow(BlackboxWindow *w) { wkspc->stackingList.push_back(win); } - XLowerWindow(screen->getBaseDisplay()->getXDisplay(), stack_vector.front()); - XRestackWindows(screen->getBaseDisplay()->getXDisplay(), - &stack_vector[0], stack_vector.size()); - screen->lowerDesktops(); + screen->lowerWindows(&stack_vector[0], stack_vector.size()); } @@ -402,43 +419,48 @@ void Workspace::setCurrent(void) { } -void Workspace::setName(const string& new_name) { - if (! new_name.empty()) { - name = new_name; +void Workspace::readName(void) { + XAtom::StringVect namesList; + unsigned long numnames = id + 1; + + // attempt to get from the _NET_WM_DESKTOP_NAMES property + if (xatom->getValue(screen->getRootWindow(), XAtom::net_desktop_names, + XAtom::utf8, numnames, namesList) && + namesList.size() > id) { + name = namesList[id]; + + clientmenu->setLabel(name); + clientmenu->update(); } else { - // attempt to get from the _NET_WM_DESKTOP_NAMES property - XAtom::StringVect namesList; - unsigned long numnames = id + 1; - if (xatom->getValue(screen->getRootWindow(), XAtom::net_desktop_names, - XAtom::utf8, numnames, namesList) && - namesList.size() > id) { - name = namesList[id]; - } else { - string tmp =i18n(WorkspaceSet, WorkspaceDefaultNameFormat, - "Workspace %d"); - assert(tmp.length() < 32); - char default_name[32]; - sprintf(default_name, tmp.c_str(), id + 1); - name = default_name; - } + /* + Use a default name. This doesn't actually change the class. That will + happen after the setName changes the root property, and that change + makes its way back to this function. + */ + string tmp =i18n(WorkspaceSet, WorkspaceDefaultNameFormat, + "Workspace %d"); + assert(tmp.length() < 32); + char default_name[32]; + sprintf(default_name, tmp.c_str(), id + 1); + + setName(default_name); // save this into the _NET_WM_DESKTOP_NAMES property } - - // reset the property with the new name +} + + +void Workspace::setName(const string& new_name) { + // set the _NET_WM_DESKTOP_NAMES property with the new name XAtom::StringVect namesList; unsigned long numnames = (unsigned) -1; if (xatom->getValue(screen->getRootWindow(), XAtom::net_desktop_names, - XAtom::utf8, numnames, namesList)) { - if (namesList.size() > id) - namesList[id] = name; - else - namesList.push_back(name); - } + XAtom::utf8, numnames, namesList) && + namesList.size() > id) + namesList[id] = new_name; + else + namesList.push_back(new_name); + xatom->setValue(screen->getRootWindow(), XAtom::net_desktop_names, XAtom::utf8, namesList); - - clientmenu->setLabel(name); - clientmenu->update(); - screen->saveWorkspaceNames(); }