]> Dogcows Code - chaz/openbox/blobdiff - src/Workspace.cc
sync with bb cvs
[chaz/openbox] / src / Workspace.cc
index 35b3b593f3fc221d0a51d57db6dbd23b13a74b89..9606140d6262392dbcfdf2205757b7203f85b8e7 100644 (file)
@@ -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,19 +99,25 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) {
 
   stackingList.remove(w);
 
-  if (w->isFocused() && ! screen->getBlackbox()->doShutdown()) {
-    BlackboxWindow *newfocus = 0;
-    if (w->isTransient())
-      newfocus = w->getTransientFor();
-    if (! newfocus && ! stackingList.empty())
-      newfocus = stackingList.front();
-    if (! newfocus || ! newfocus->setInputFocus())
-      screen->getBlackbox()->setFocusedWindow(0);
+  // pass focus to the next appropriate window
+  if ((w->isFocused() || w == lastfocus) &&
+      ! screen->getBlackbox()->doShutdown()) {
+    if (id == screen->getCurrentWorkspaceID()) {
+      // The window is on the visible workspace
+      focusFallback(w);
+    } else {
+      // The window is not on the visible workspace.
+      if (lastfocus == w) {
+        // The window was the last-focus target, so we need to replace it.
+        setLastFocusedWindow(stackingList.front());
+      }
+      // if the window focused on the current workspace, then reapply that
+      // workspace's focus too
+      if (w->isFocused())
+        screen->getCurrentWorkspace()->focusFallback(w);
+    }
   }
 
-  if (lastfocus == w)
-    lastfocus = (BlackboxWindow *) 0;
-
   windowList.remove(w);
   clientmenu->remove(w->getWindowNumber());
   clientmenu->update();
@@ -129,6 +137,37 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) {
 }
 
 
+void Workspace::focusFallback(const BlackboxWindow *old_window) {
+  BlackboxWindow *newfocus = 0;
+
+  // 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);
+}
+
+
 void Workspace::showAll(void) {
   std::for_each(stackingList.begin(), stackingList.end(),
                 std::mem_fun(&BlackboxWindow::show));
@@ -224,7 +263,6 @@ void Workspace::lowerTransients(const BlackboxWindow * const win,
       wkspc->stackingList.push_back((*it));
     }
   }
-
 }
 
 
@@ -287,6 +325,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();
 }
 
 
@@ -297,12 +336,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();
@@ -357,6 +390,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());
 }
@@ -366,6 +407,7 @@ bool Workspace::isLastWindow(const BlackboxWindow* const w) const {
   return (w == windowList.back());
 }
 
+
 void Workspace::setCurrent(void) {
   screen->changeWorkspaceID(id);
 }
@@ -375,12 +417,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();
This page took 0.024357 seconds and 4 git commands to generate.