X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2FWorkspace.cc;h=90a83b2678a43a531dd78f214b668b2fb1055299;hb=6716bd33235b6fda4aeea75aea7c446e9f27fe40;hp=64710a59a999f86d14b089ef5600c22f2bbdf9da;hpb=aad50046de0b1971f869ee95a0f80267c74a1fd3;p=chaz%2Fopenbox diff --git a/src/Workspace.cc b/src/Workspace.cc index 64710a59..90a83b26 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -55,10 +55,12 @@ using std::string; #include "Window.hh" #include "Workspace.hh" #include "Windowmenu.hh" +#include "XAtom.hh" Workspace::Workspace(BScreen *scrn, unsigned int i) { screen = scrn; + xatom = screen->getBlackbox()->getXAtom(); cascade_x = cascade_y = 32; @@ -68,7 +70,7 @@ Workspace::Workspace(BScreen *scrn, unsigned int i) { lastfocus = (BlackboxWindow *) 0; - setName(screen->getNameOfWorkspace(id)); + setName(""); } @@ -97,18 +99,44 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) { stackingList.remove(w); - if (w->isFocused() && ! screen->getBlackbox()->doShutdown()) { + // pass focus to the next appropriate window + if ((w->isFocused() || w == lastfocus) && + ! screen->getBlackbox()->doShutdown()) { BlackboxWindow *newfocus = 0; - if (w->isTransient()) + 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(); - if (! newfocus || ! newfocus->setInputFocus()) - screen->getBlackbox()->setFocusedWindow(0); - } - if (lastfocus == w) - lastfocus = (BlackboxWindow *) 0; + 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); + } + } windowList.remove(w); clientmenu->remove(w->getWindowNumber()); @@ -286,6 +314,7 @@ void Workspace::lowerWindow(BlackboxWindow *w) { XLowerWindow(screen->getBaseDisplay()->getXDisplay(), stack_vector.front()); XRestackWindows(screen->getBaseDisplay()->getXDisplay(), &stack_vector[0], stack_vector.size()); + screen->lowerDesktops(); } @@ -296,12 +325,6 @@ void Workspace::reconfigure(void) { } -void Workspace::updateFocusModel(void) { - std::for_each(windowList.begin(), windowList.end(), - std::mem_fun(&BlackboxWindow::updateFocusModel)); -} - - BlackboxWindow *Workspace::getWindow(unsigned int index) { if (index < windowList.size()) { BlackboxWindowList::iterator it = windowList.begin(); @@ -356,6 +379,14 @@ unsigned int Workspace::getCount(void) const { } +void Workspace::appendStackOrder(BlackboxWindowList &stack_order) const { + BlackboxWindowList::const_reverse_iterator it = stackingList.rbegin(); + const BlackboxWindowList::const_reverse_iterator end = stackingList.rend(); + for (; it != end; ++it) + stack_order.push_back(*it); +} + + bool Workspace::isCurrent(void) const { return (id == screen->getCurrentWorkspaceID()); } @@ -365,6 +396,7 @@ bool Workspace::isLastWindow(const BlackboxWindow* const w) const { return (w == windowList.back()); } + void Workspace::setCurrent(void) { screen->changeWorkspaceID(id); } @@ -374,12 +406,35 @@ void Workspace::setName(const string& new_name) { if (! new_name.empty()) { name = new_name; } 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; + // 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; + } + } + + // reset the 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->setValue(screen->getRootWindow(), XAtom::net_desktop_names, + XAtom::utf8, namesList); clientmenu->setLabel(name); clientmenu->update();