]> Dogcows Code - chaz/openbox/blobdiff - src/Workspace.cc
sync with blackbox-cvs
[chaz/openbox] / src / Workspace.cc
index 3ef99ea749d054ac3e1016b17e9808af9517dd0e..1d07a5bea12daa5db632dc0b88df2d931f646ac3 100644 (file)
@@ -38,6 +38,8 @@ extern "C" {
 #endif // HAVE_STRING_H
 }
 
+#include <assert.h>
+
 #include <functional>
 #include <string>
 
@@ -95,18 +97,39 @@ 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())
       newfocus = w->getTransientFor();
     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());
@@ -222,7 +245,6 @@ void Workspace::lowerTransients(const BlackboxWindow * const win,
       wkspc->stackingList.push_back((*it));
     }
   }
-
 }
 
 
@@ -382,6 +404,7 @@ void Workspace::setName(const string& new_name) {
 
   clientmenu->setLabel(name);
   clientmenu->update();
+  screen->saveWorkspaceNames();
 }
 
 
@@ -487,11 +510,14 @@ bool Workspace::smartPlacement(Rect& win, const Rect& availableArea) {
   spaces.push_back(availableArea); //initially the entire screen is free
 
   //Find Free Spaces
-  BlackboxWindowList::iterator wit = windowList.begin(),
-                               end = windowList.end();
+  BlackboxWindowList::const_iterator wit = windowList.begin(),
+    end = windowList.end();
   Rect tmp;
   for (; wit != end; ++wit) {
     const BlackboxWindow* const curr = *wit;
+
+    if (curr->isShaded()) continue;
+
     tmp.setRect(curr->frameRect().x(), curr->frameRect().y(),
                 curr->frameRect().width() + screen->getBorderWidth(),
                 curr->frameRect().height() + screen->getBorderWidth());
@@ -502,26 +528,26 @@ bool Workspace::smartPlacement(Rect& win, const Rect& availableArea) {
   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);
     }
   }
 
@@ -555,6 +581,31 @@ bool Workspace::smartPlacement(Rect& win, const Rect& availableArea) {
 }
 
 
+bool Workspace::underMousePlacement(Rect &win, const Rect &availableArea) {
+  int x, y, rx, ry;
+  Window c, r;
+  unsigned int m;
+  XQueryPointer(screen->getBlackbox()->getXDisplay(), screen->getRootWindow(),
+                &r, &c, &rx, &ry, &x, &y, &m);
+  x = rx - win.width() / 2;
+  y = ry - win.height() / 2;
+
+  if (x < availableArea.x())
+    x = availableArea.x();
+  if (y < availableArea.y())
+    y = availableArea.y();
+  if (x + win.width() > availableArea.x() + availableArea.width())
+    x = availableArea.x() + availableArea.width() - win.width();
+  if (y + win.height() > availableArea.y() + availableArea.height())
+    y = availableArea.y() + availableArea.height() - win.height();
+
+  win.setX(x);
+  win.setY(y);
+
+  return True;
+}
+
+
 bool Workspace::cascadePlacement(Rect &win, const Rect &availableArea) {
   if ((cascade_x > static_cast<signed>(availableArea.width() / 2)) ||
       (cascade_y > static_cast<signed>(availableArea.height() / 2)))
@@ -582,6 +633,8 @@ void Workspace::placeWindow(BlackboxWindow *win) {
   case BScreen::ColSmartPlacement:
     placed = smartPlacement(new_win, availableArea);
     break;
+  case BScreen::UnderMousePlacement:
+    placed = underMousePlacement(new_win, availableArea);
   default:
     break; // handled below
   } // switch
This page took 0.024132 seconds and 4 git commands to generate.