]> Dogcows Code - chaz/openbox/commitdiff
xinerama support for window placement
authorDana Jansens <danakj@orodu.net>
Mon, 22 Jul 2002 04:29:40 +0000 (04:29 +0000)
committerDana Jansens <danakj@orodu.net>
Mon, 22 Jul 2002 04:29:40 +0000 (04:29 +0000)
src/Screen.cc
src/Screen.hh
src/Util.cc
src/Util.hh
src/Workspace.cc
src/Workspace.hh
src/blackbox.cc
src/blackbox.hh

index 60cd8e09bfee6f7ab9fad63b9c981cfbb32eeace..fc6979d814668d599405030f0c24c8a86a672d85 100644 (file)
@@ -2074,16 +2074,12 @@ const Rect& BScreen::availableArea(void) const {
 }
 
 
-RectList BScreen::allAvailableAreas(void) const {
 #ifdef    XINERAMA
-  if (isXineramaActive())
-    return xineramaUsableArea;
-#endif // XINERAMA
-
-  RectList list;
-  list.push_back(availableArea());
-  return list;
+RectList BScreen::allAvailableAreas(void) const {
+  assert(isXineramaActive());
+  return xineramaUsableArea;
 }
+#endif // XINERAMA
 
 
 void BScreen::updateAvailableArea(void) {
index 06548d415aa0351d82ebbcbaa66954e20de2c0bb..87d11c68cbfe9f8daaa6770ed21d7adc7f0e1835 100644 (file)
@@ -312,7 +312,9 @@ public:
   // allAvailableAreas should be used whenever possible instead of this function
   // as then Xinerama will work correctly.
   const Rect& availableArea(void) const;
+#ifdef    XINERAMA
   RectList allAvailableAreas(void) const;
+#endif // XINERAMA
   void updateAvailableArea(void);
   void addStrut(Strut *strut);
   void removeStrut(Strut *strut);
index 1b521aafb6f872259e2eff92e64a7486194e55a3..d80834447971b425750bd5ee44dc04665eac95f1 100644 (file)
@@ -141,6 +141,18 @@ bool Rect::intersects(const Rect &a) const {
 }
 
 
+bool Rect::contains(int __x, int __y) const {
+  return __x >= _x1 && __x <= _x2 &&
+         __y >= _y1 && __y <= _y2;
+}
+
+
+bool Rect::contains(const Rect& a) const {
+  return a._x1 >= _x1 && a._x2 <= _x2 &&
+         a._y1 >= _y1 && a._y2 <= _y2;
+}
+
+
 string expandTilde(const string& s) {
   if (s[0] != '~') return s;
 
index d70eabc8e7807687116ef94f8055a63129092735..46d8f339daf1d5dde846a53aa7c0f2682efc7eff 100644 (file)
@@ -72,6 +72,8 @@ public:
   inline bool valid(void) const { return _x2 > _x1 && _y2 > _y1; }
 
   bool intersects(const Rect &a) const;
+  bool contains(int __x, int __y) const;
+  bool contains(const Rect &a) const;
 
 private:
   int _x1, _y1, _x2, _y2;
index 0a95c24f04e644a76d2f98cc2f59e69e41fc8995..8a62d1b0c2a1b4ce420c5ebd490f69d7ce15420c 100644 (file)
@@ -584,9 +584,22 @@ 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();
+    assert(availableAreas.size() > 0);
+    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(),
@@ -661,23 +674,40 @@ 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();
+    assert(availableAreas.size() > 0);
+    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);
@@ -686,7 +716,9 @@ bool Workspace::underMousePlacement(Rect &win, const Rect &availableArea) {
 }
 
 
-bool Workspace::cascadePlacement(Rect &win, const Rect &availableArea) {
+bool Workspace::cascadePlacement(Rect &win) {
+  const Rect &availableArea = screen->availableArea();
+
   if ((cascade_x > static_cast<signed>(availableArea.width() / 2)) ||
       (cascade_y > static_cast<signed>(availableArea.height() / 2)))
     cascade_x = cascade_y = 32;
@@ -703,32 +735,29 @@ bool Workspace::cascadePlacement(Rect &win, const Rect &availableArea) {
 
 
 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);
+    cascadePlacement(new_win);
     cascade_x += win->getTitleHeight() + (screen->getBorderWidth() * 2);
     cascade_y += win->getTitleHeight() + (screen->getBorderWidth() * 2);
   }
 
-  if (new_win.right() > availableArea.right())
-    new_win.setX(availableArea.left());
-  if (new_win.bottom() > availableArea.bottom())
-    new_win.setY(availableArea.top());
+  // make sure the placement was valid
+  assert(screen->availableArea().contains(new_win));
+
   win->configure(new_win.x(), new_win.y(), new_win.width(), new_win.height());
 }
index 09dc277908c93cceb8a642192b3c57e850dfacf1..18933accd6648903fa6fc995c6b04c4975a844f2 100644 (file)
@@ -63,9 +63,9 @@ private:
                        StackVector::iterator &stack);
 
   void placeWindow(BlackboxWindow *win);
-  bool cascadePlacement(Rect& win, const Rect& availableArea);
-  bool smartPlacement(Rect& win, const Rect& availableArea);
-  bool underMousePlacement(Rect& win, const Rect& availableArea);
+  bool cascadePlacement(Rect& win);
+  bool smartPlacement(Rect& win);
+  bool underMousePlacement(Rect& win);
 
 public:
   Workspace(BScreen *scrn, unsigned int i = 0);
index 8dc7db838ff04656c43e2f3060176a055ec47347..d30c01edf47e65273da9ac991b4b478b3d301b98 100644 (file)
@@ -1164,6 +1164,32 @@ void Blackbox::shutdown(void) {
 }
 
 
+#ifdef    XINERAMA
+void Blackbox::saveXineramaPlacement(bool x) {
+  resource.xinerama_placement = x;
+  config.setValue("session.xineramaSupport.windowPlacement",
+                  resource.xinerama_placement);
+  reconfigure();  // make sure all screens get this change
+}
+
+
+void Blackbox::saveXineramaMaximizing(bool x) {
+  resource.xinerama_maximize = x;
+  config.setValue("session.xineramaSupport.windowMaximizing",
+                  resource.xinerama_maximize);
+  reconfigure();  // make sure all screens get this change
+}
+
+
+void Blackbox::saveXineramaSnapping(bool x) {
+  resource.xinerama_snap = x;
+  config.setValue("session.xineramaSupport.windowSnapping",
+                  resource.xinerama_snap);
+  reconfigure();  // make sure all screens get this change
+}
+#endif // XINERAMA
+
+  
 /*
  * Save all values as they are so that the defaults will be written to the rc
  * file
@@ -1182,6 +1208,12 @@ void Blackbox::save_rc(void) {
   config.setValue("session.styleFile", resource.style_file);
   config.setValue("session.titlebarLayout", resource.titlebar_layout);
   
+#ifdef    XINERAMA
+  saveXineramaPlacement(resource.xinerama_placement);
+  saveXineramaMaximizing(resource.xinerama_maximize);
+  saveXineramaSnapping(resource.xinerama_snap);
+#endif // XINERAMA
+
   std::for_each(screenList.begin(), screenList.end(),
                 std::mem_fun(&BScreen::save_rc));
  
@@ -1228,10 +1260,28 @@ void Blackbox::load_rc(void) {
   
   if (! config.getValue("session.titlebarLayout", resource.titlebar_layout))
     resource.titlebar_layout = "ILMC";
+
+#ifdef    XINERAMA
+  if (! config.getValue("session.xineramaSupport.windowPlacement",
+                        resource.xinerama_placement))
+    resource.xinerama_placement = true;
+
+  if (! config.getValue("session.xineramaSupport.windowMaximizing",
+                        resource.xinerama_maximize))
+    resource.xinerama_maximize = true;
+
+  if (! config.getValue("session.xineramaSupport.windowSnapping",
+                        resource.xinerama_snap))
+    resource.xinerama_snap = true;
+#endif // XINERAMA
 }
 
 
 void Blackbox::reconfigure(void) {
+  // don't reconfigure while saving the initial rc file, it's a waste and it
+  // breaks somethings (workspace names)
+  if (isStartup()) return;
+
   reconfigure_wait = True;
 
   if (! timer->isTiming()) timer->start();
index a6e689d7666d386b18ffe3cbef6d1a5a640bb8a8..6a6a22d1c3fc5d22fa9e5ed77a51a38147f25998 100644 (file)
@@ -115,6 +115,10 @@ private:
     timeval auto_raise_delay;
     unsigned long cache_life, cache_max;
     std::string titlebar_layout;
+
+#ifdef    XINERAMA
+    bool xinerama_placement, xinerama_maximize, xinerama_snap;
+#endif // XINERAMA
   } resource;
 
   typedef std::map<Window, BlackboxWindow*> WindowLookup;
@@ -181,6 +185,19 @@ public:
   Toolbar *searchToolbar(Window);
   Slit *searchSlit(Window);
 
+#ifdef    XINERAMA
+  inline bool doXineramaPlacement(void) const
+    { return resource.xinerama_placement; }
+  inline bool doXineramaMaximizing(void) const
+    { return resource.xinerama_maximize; }
+  inline bool doXineramaSnapping(void) const
+    { return resource.xinerama_snap; }
+
+  void saveXineramaPlacement(bool x);
+  void saveXineramaMaximizing(bool x);
+  void saveXineramaSnapping(bool x);
+#endif // XINERAMA
+  
   void saveMenuSearch(Window window, Basemenu *data);
   void saveSystrayWindowSearch(Window window, BScreen *screen);
   void saveWindowSearch(Window window, BlackboxWindow *data);
This page took 0.035177 seconds and 4 git commands to generate.