#endif // HAVE_STRING_H
}
+#include <assert.h>
+
#include <functional>
#include <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;
lastfocus = (BlackboxWindow *) 0;
- setName(screen->getNameOfWorkspace(id));
+ setName("");
}
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());
wkspc->stackingList.push_back((*it));
}
}
-
}
XLowerWindow(screen->getBaseDisplay()->getXDisplay(), stack_vector.front());
XRestackWindows(screen->getBaseDisplay()->getXDisplay(),
&stack_vector[0], stack_vector.size());
+ screen->lowerDesktops();
}
}
-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();
}
+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());
}
return (w == windowList.back());
}
+
void Workspace::setCurrent(void) {
screen->changeWorkspaceID(id);
}
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();
if (screen->getPlacementPolicy() == BScreen::RowSmartPlacement) {
if(screen->getRowPlacementDirection() == BScreen::LeftRight) {
if(screen->getColPlacementDirection() == BScreen::TopBottom)
- sort(spaces.begin(), spaces.end(), rowLRTB);
+ std::sort(spaces.begin(), spaces.end(), rowLRTB);
else
- sort(spaces.begin(), spaces.end(), rowLRBT);
+ std::sort(spaces.begin(), spaces.end(), rowLRBT);
} else {
if(screen->getColPlacementDirection() == BScreen::TopBottom)
- sort(spaces.begin(), spaces.end(), rowRLTB);
+ std::sort(spaces.begin(), spaces.end(), rowRLTB);
else
- sort(spaces.begin(), spaces.end(), rowRLBT);
+ std::sort(spaces.begin(), spaces.end(), rowRLBT);
}
} else {
if(screen->getColPlacementDirection() == BScreen::TopBottom) {
if(screen->getRowPlacementDirection() == BScreen::LeftRight)
- sort(spaces.begin(), spaces.end(), colLRTB);
+ std::sort(spaces.begin(), spaces.end(), colLRTB);
else
- sort(spaces.begin(), spaces.end(), colRLTB);
+ std::sort(spaces.begin(), spaces.end(), colRLTB);
} else {
if(screen->getRowPlacementDirection() == BScreen::LeftRight)
- sort(spaces.begin(), spaces.end(), colLRBT);
+ std::sort(spaces.begin(), spaces.end(), colLRBT);
else
- sort(spaces.begin(), spaces.end(), colRLBT);
+ std::sort(spaces.begin(), spaces.end(), colRLBT);
}
}