]> Dogcows Code - chaz/openbox/blobdiff - src/Workspace.cc
add comment
[chaz/openbox] / src / Workspace.cc
index 26b48e42f0f139055b0359f08f0b0ccdfc31d928..366e8192e616e3f96dbfa093a8f489fb6e54e5a6 100644 (file)
@@ -48,6 +48,7 @@ using std::string;
 #include "i18n.hh"
 #include "blackbox.hh"
 #include "Clientmenu.hh"
+#include "Font.hh"
 #include "Netizen.hh"
 #include "Screen.hh"
 #include "Toolbar.hh"
@@ -62,7 +63,10 @@ Workspace::Workspace(BScreen *scrn, unsigned int i) {
   screen = scrn;
   xatom = screen->getBlackbox()->getXAtom();
 
-  cascade_x = cascade_y = 32;
+  cascade_x = cascade_y = 0;
+#ifdef    XINERAMA
+  cascade_region = 0;
+#endif // XINERAMA
 
   id = i;
 
@@ -91,6 +95,16 @@ void Workspace::addWindow(BlackboxWindow *w, bool place) {
     clientmenu->update();
 
     screen->updateNetizenWindowAdd(w->getClientWindow(), id);
+
+    if (id != screen->getCurrentWorkspaceID() &&
+        screen->doFocusNew()) {
+      /*
+         not on the focused workspace, so the window is not going to get focus
+         but if the user wants new windows focused, then it should get focus
+         when this workspace does become focused.
+      */
+      lastfocus = w;
+    }
   }
 
   if (! w->isDesktop())
@@ -133,8 +147,12 @@ void Workspace::removeWindow(BlackboxWindow *w) {
   for (; it != end; ++it, ++i)
     (*it)->setWindowNumber(i);
 
-  if (i == 0)
-    cascade_x = cascade_y = 32;
+  if (i == 0) {
+    cascade_x = cascade_y = 0;
+#ifdef    XINERAMA
+    cascade_region = 0;
+#endif // XINERAMA
+  }
 }
 
 
@@ -574,9 +592,21 @@ static bool colRLBT(const Rect &first, const Rect &second) {
 }
 
 
-bool Workspace::smartPlacement(Rect& win, const Rect& availableArea) {
+bool Workspace::smartPlacement(Rect& win) {
   rectList spaces;
-  spaces.push_back(availableArea); //initially the entire screen is free
+  //initially the entire screen is free
+#ifdef    XINERAMA
+  if (screen->isXineramaActive() &&
+      screen->getBlackbox()->doXineramaPlacement()) {
+    RectList availableAreas = screen->allAvailableAreas();
+    RectList::iterator it, end = availableAreas.end();
+
+    for (it = availableAreas.begin(); it != end; ++it)
+      spaces.push_back(*it);
+  } else
+#endif // XINERAMA
+    spaces.push_back(screen->availableArea());
 
   //Find Free Spaces
   BlackboxWindowList::const_iterator wit = windowList.begin(),
@@ -651,23 +681,39 @@ bool Workspace::smartPlacement(Rect& win, const Rect& availableArea) {
 }
 
 
-bool Workspace::underMousePlacement(Rect &win, const Rect &availableArea) {
+bool Workspace::underMousePlacement(Rect &win) {
   int x, y, rx, ry;
   Window c, r;
   unsigned int m;
   XQueryPointer(screen->getBlackbox()->getXDisplay(), screen->getRootWindow(),
                 &r, &c, &rx, &ry, &x, &y, &m);
+
+  Rect area;
+#ifdef    XINERAMA
+  if (screen->isXineramaActive() &&
+      screen->getBlackbox()->doXineramaPlacement()) {
+    RectList availableAreas = screen->allAvailableAreas();
+    RectList::iterator it, end = availableAreas.end();
+
+    for (it = availableAreas.begin(); it != end; ++it)
+      if (it->contains(rx, ry)) break;
+    assert(it != end);  // the mouse isn't inside an area?
+    area = *it;
+  } else
+#endif // XINERAMA
+    area = screen->availableArea();
+  
   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();
+  if (x < area.x())
+    x = area.x();
+  if (y < area.y())
+    y = area.y();
+  if (x + win.width() > area.x() + area.width())
+    x = area.x() + area.width() - win.width();
+  if (y + win.height() > area.y() + area.height())
+    y = area.y() + area.height() - win.height();
 
   win.setX(x);
   win.setY(y);
@@ -676,49 +722,69 @@ bool Workspace::underMousePlacement(Rect &win, const Rect &availableArea) {
 }
 
 
-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)))
-    cascade_x = cascade_y = 32;
+bool Workspace::cascadePlacement(Rect &win, const int offset) {
+  Rect area;
+  
+#ifdef    XINERAMA
+  if (screen->isXineramaActive() &&
+      screen->getBlackbox()->doXineramaPlacement()) {
+    area = screen->allAvailableAreas()[cascade_region];
+  } else
+#endif // XINERAMA
+    area = screen->availableArea();
+
+  if ((static_cast<signed>(cascade_x + win.width()) > area.right() + 1) ||
+      (static_cast<signed>(cascade_y + win.height()) > area.bottom() + 1)) {
+    cascade_x = cascade_y = 0;
+#ifdef    XINERAMA
+    if (screen->isXineramaActive() &&
+        screen->getBlackbox()->doXineramaPlacement()) {
+      // go to the next xinerama region, and use its area
+      if (++cascade_region >= screen->allAvailableAreas().size())
+        cascade_region = 0;
+      area = screen->allAvailableAreas()[cascade_region];
+    }
+#endif // XINERAMA
+  }
 
-  if (cascade_x == 32) {
-    cascade_x += availableArea.x();
-    cascade_y += availableArea.y();
+  if (cascade_x == 0) {
+    cascade_x = area.x() + offset;
+    cascade_y = area.y() + offset;
   }
 
   win.setPos(cascade_x, cascade_y);
 
+  cascade_x += offset;
+  cascade_y += offset;
+
   return True;
 }
 
 
 void Workspace::placeWindow(BlackboxWindow *win) {
-  Rect availableArea(screen->availableArea()),
-    new_win(availableArea.x(), availableArea.y(),
-            win->frameRect().width(), win->frameRect().height());
+  Rect new_win(0, 0, win->frameRect().width(), win->frameRect().height());
   bool placed = False;
 
   switch (screen->getPlacementPolicy()) {
   case BScreen::RowSmartPlacement:
   case BScreen::ColSmartPlacement:
-    placed = smartPlacement(new_win, availableArea);
+    placed = smartPlacement(new_win);
     break;
   case BScreen::UnderMousePlacement:
   case BScreen::ClickMousePlacement:
-    placed = underMousePlacement(new_win, availableArea);
+    placed = underMousePlacement(new_win);
   default:
     break; // handled below
   } // switch
 
-  if (placed == False) {
-    cascadePlacement(new_win, availableArea);
-    cascade_x += win->getTitleHeight() + (screen->getBorderWidth() * 2);
-    cascade_y += win->getTitleHeight() + (screen->getBorderWidth() * 2);
-  }
+  if (placed == False)
+    cascadePlacement(new_win, (win->getTitleHeight() +
+                               screen->getBorderWidth() * 2));
+
+  if (new_win.right() > screen->availableArea().right())
+    new_win.setX(screen->availableArea().left());
+  if (new_win.bottom() > screen->availableArea().bottom())
+    new_win.setY(screen->availableArea().top());
 
-  if (new_win.right() > availableArea.right())
-    new_win.setX(availableArea.left());
-  if (new_win.bottom() > availableArea.bottom())
-    new_win.setY(availableArea.top());
   win->configure(new_win.x(), new_win.y(), new_win.width(), new_win.height());
 }
This page took 0.024695 seconds and 4 git commands to generate.