]> Dogcows Code - chaz/openbox/commitdiff
keep track of struts for each desktop
authorDana Jansens <danakj@orodu.net>
Mon, 10 Feb 2003 06:50:19 +0000 (06:50 +0000)
committerDana Jansens <danakj@orodu.net>
Mon, 10 Feb 2003 06:50:19 +0000 (06:50 +0000)
scripts/motion.py
scripts/windowplacement.py
src/actions.cc
src/actions.hh
src/client.cc
src/client.hh
src/screen.cc
src/screen.hh

index 2d6939c519c6f4416d98abe370d79550ca1a960c..e0a1d3522fbe6c3e1cb9f55136157f1e272e79fc 100644 (file)
@@ -106,7 +106,7 @@ def _do_move():
         w = _client.area().width() + fs.left + fs.right
         h = _client.area().height() + fs.top + fs.bottom
         # use the area based on the struts
-        area = ob.openbox.screen(_screen).area()
+        area = ob.openbox.screen(_screen).area(_client.desktop())
         l = area.left()
         r = area.right() - w + 1
         t = area.top()
index e7ba187ded2741ddb230748e5ce71b899227a55a..a319c7b1b78c5c10e45c7e434b3b2ec8ce8b4d28 100644 (file)
@@ -25,7 +25,7 @@ def random(data):
     if data.client.positionRequested(): return
     client_area = data.client.area()
     frame_size = data.client.frame.size()
-    screen_area = ob.openbox.screen(data.screen).area()
+    screen_area = ob.openbox.screen(data.screen).area(data.client.desktop())
     width = screen_area.width() - (client_area.width() +
                                    frame_size.left + frame_size.right)
     height = screen_area.height() - (client_area.height() + 
@@ -44,7 +44,7 @@ def cascade(data):
     if data.client.positionRequested(): return
     client_area = data.client.area()
     frame_size = data.client.frame.size()
-    screen_area = ob.openbox.screen(data.screen).area()
+    screen_area = ob.openbox.screen(data.screen).area(data.client.desktop())
     width = screen_area.width() - (client_area.width() +
                                    frame_size.left + frame_size.right)
     height = screen_area.height() - (client_area.height() + 
index 3eb292158bf257f0a908a2587d73e03953e96b62..3a7ff36982898fee3d18e8f1dc3013afc8fdb8e4 100644 (file)
@@ -42,6 +42,7 @@ void Actions::insertPress(const XButtonEvent &e)
     _posqueue[i] = _posqueue[i-1];
   }
   _posqueue[0] = a;
+  a->win = e.window;
   a->button = e.button;
   a->pos = otk::Point(e.x_root, e.y_root);
 
@@ -274,6 +275,8 @@ void Actions::motionHandler(const XMotionEvent &e)
 
   if (!e.same_screen) return; // this just gets stupid
 
+  if (e.window != _posqueue[0]->win) return;
+  
   MouseContext::MC context;
   EventHandler *h = openbox->findHandler(e.window);
   Frame *f = dynamic_cast<Frame*>(h);
@@ -287,7 +290,7 @@ void Actions::motionHandler(const XMotionEvent &e)
     return; // not a valid mouse context
 
   int x_root = e.x_root, y_root = e.y_root;
-  
+
   // compress changes to a window into a single change
   XEvent ce;
   while (XCheckTypedWindowEvent(**otk::display, e.window, e.type, &ce)) {
index f18696a10526426da996cf74f5f42bc94f56b03e..c2de2b683a99ad582812de60baee019f8787993f 100644 (file)
@@ -35,6 +35,7 @@ public:
   };
   
   struct ButtonPressAction {
+    Window win;
     unsigned int button;
     otk::Point pos;
     otk::Rect clientarea;
index 091b095e64767bcccf13ca9d7c9af98109667235..b495a71cc91535fd2681b055f8bf3ce0c0d462b1 100644 (file)
@@ -45,7 +45,7 @@ Client::Client(int screen, Window window)
   _positioned = false;
   _disabled_decorations = 0;
   _group = None;
-  _desktop = 0;
+  _desktop = _old_desktop = 0;
   
   getArea();
   getDesktop();
@@ -638,7 +638,7 @@ void Client::updateStrut()
     // updating here is pointless while we're being mapped cuz we're not in
     // the screen's client list yet
     if (frame)
-      openbox->screen(_screen)->updateStrut();
+      openbox->screen(_screen)->updateStruts();
   }
 
   delete [] data;
@@ -748,7 +748,8 @@ void Client::setDesktop(long target)
   if (!(target >= 0 || target == (signed)0xffffffff ||
         target == ICONIC_DESKTOP))
     return;
-  
+
+  _old_desktop = _desktop;
   _desktop = target;
 
   // set the desktop hint, but not if we're iconifying
@@ -781,8 +782,10 @@ void Client::setDesktop(long target)
     }
     changeState();
   }
-  
+
+  changeAllowedActions();
   frame->adjustState();
+  openbox->screen(_screen)->updateStruts();
 }
 
 
@@ -1301,6 +1304,7 @@ void Client::changeAllowedActions(void)
 
 void Client::remaximize()
 {
+  printf("REMAXIMIZE!!!!!!!!!!!!!!!!!!!\n");
   int dir;
   if (_max_horz && _max_vert)
     dir = 0;
@@ -1391,7 +1395,8 @@ void Client::maximize(bool max, int dir, bool savearea)
     if (dir == 2 && !_max_vert) return;
   }
 
-  const otk::Rect &a = openbox->screen(_screen)->area();
+  const otk::Rect &a = openbox->screen(_screen)->area(_iconic ?
+                                                      _old_desktop : _desktop);
   int x = frame->area().x(), y = frame->area().y(),
     w = _area.width(), h = _area.height();
   
@@ -1536,7 +1541,9 @@ void Client::fullscreen(bool fs, bool savearea)
       delete dimensions;
     } else {
       // pick some fallbacks...
-      const otk::Rect &a = openbox->screen(_screen)->area();
+      const otk::Rect &a = openbox->screen(_screen)->area(_iconic ?
+                                                          _old_desktop :
+                                                          _desktop);
       x = a.x() + a.width() / 4;
       y = a.y() + a.height() / 4;
       w = a.width() / 2;
index b7efefa2dabd01294b0afc62154f1319fba5ebbc..0505c36154675e2cfcb3bb07158687835597021b 100644 (file)
@@ -190,6 +190,10 @@ private:
   //! The desktop on which the window resides (0xffffffff for all desktops)
   long _desktop;
 
+  //! The last desktop to which the window belonged, mostly useful when the
+  //! window is iconified, to see where it used to be.
+  long _old_desktop;
+
   //! Normal window title
   otk::ustring  _title;
   //! Window title when iconifiged
index 2c49c6cc5c16684cbfaae773af7b9271a5156a2d..081b68d1a1367c7503c2094250783ee787ff7579 100644 (file)
@@ -122,7 +122,6 @@ Screen::Screen(int screen)
   // these may be further updated if any pre-existing windows are found in
   // the manageExising() function
   changeClientList();  // initialize the client lists, which will be empty
-  calcArea();          // initialize the available working area
 
   // register this class as the event handler for the root window
   openbox->registerHandler(_info->rootWindow(), this);
@@ -200,26 +199,48 @@ void Screen::manageExisting()
 }
 
 
-void Screen::updateStrut()
+void Screen::updateStruts()
 {
-  _strut.left = _strut.right = _strut.top = _strut.bottom = 0;
+  struct ApplyStrut {
+    void operator()(otk::Strut &self, const otk::Strut &other) {
+      self.left = std::max(self.left, other.left);
+      self.right = std::max(self.right, other.right);
+      self.top = std::max(self.top, other.top);
+      self.bottom = std::max(self.bottom, other.bottom);
+    }
+  } apply;
 
-  ClientList::iterator it, end = clients.end();
+  StrutList::iterator sit, send = _struts.end();
+  // reset them all
+  for (sit = _struts.begin(); sit != send; ++sit)
+    sit->left = sit->right = sit->top = sit->bottom = 0;
+
+  ClientList::const_iterator it, end = clients.end();
   for (it = clients.begin(); it != end; ++it) {
+    long desk = (*it)->desktop();
     const otk::Strut &s = (*it)->strut();
-    _strut.left = std::max(_strut.left, s.left);
-    _strut.right = std::max(_strut.right, s.right);
-    _strut.top = std::max(_strut.top, s.top);
-    _strut.bottom = std::max(_strut.bottom, s.bottom);
+
+    if (desk == (signed) 0xffffffff)
+      for (unsigned int i = 0, e = _struts.size(); i < e; ++i)
+        apply(_struts[i], s);
+    else if ((unsigned)desk < _struts.size())
+      apply(_struts[desk], s);
+    else if (desk == Client::ICONIC_DESKTOP)
+      continue; // skip for the 'all desktops' strut
+    else
+      assert(false); // invalid desktop otherwise..
+    // apply to the 'all desktops' strut
+    apply(_struts.back(), s);
   }
-  calcArea();
+  changeWorkArea();
 }
 
 
-void Screen::calcArea()
+void Screen::changeWorkArea()
 {
-  otk::Rect old_area = _area;
-
+  unsigned long *dims = new unsigned long[4 * _num_desktops];
+  for (long i = 0; i < _num_desktops + 1; ++i) {
+    otk::Rect old_area = _area[i];
 /*
 #ifdef    XINERAMA
   // reset to the full areas
@@ -228,10 +249,12 @@ void Screen::calcArea()
 #endif // XINERAMA
 */
   
-  _area = otk::Rect(_strut.left, _strut.top,
-                    _info->size().width() - (_strut.left + _strut.right),
-                    _info->size().height() - (_strut.top + _strut.bottom));
-
+    _area[i] = otk::Rect(_struts[i].left, _struts[i].top,
+                         _info->size().width() - (_struts[i].left +
+                                                  _struts[i].right),
+                         _info->size().height() - (_struts[i].top +
+                                                   _struts[i].bottom));
+    
 /*
 #ifdef    XINERAMA
   if (isXineramaActive()) {
@@ -254,15 +277,31 @@ void Screen::calcArea()
   }
 #endif // XINERAMA
 */
-  if (old_area != _area) {
-    // the area has changed, adjust all the maximized windows
-    ClientList::iterator it, end = clients.end();
-    for (it = clients.begin(); it != end; ++it)
-      (*it)->remaximize();
-  }
+    if (old_area != _area[i]) {
+      // the area has changed, adjust all the maximized windows
+      ClientList::iterator it, end = clients.end();
+      for (it = clients.begin(); it != end; ++it)
+        if (i < _num_desktops) {
+          if ((*it)->desktop() == i)
+            (*it)->remaximize();
+        } else {
+          // the 'all desktops' size
+          if ((*it)->desktop() == (signed) 0xffffffff)
+            (*it)->remaximize();
+        }
+    }
 
-  changeWorkArea();
+    // don't set these for the 'all desktops' area
+    if (i < _num_desktops) {
+      dims[(i * 4) + 0] = _area[i].x();
+      dims[(i * 4) + 1] = _area[i].y();
+      dims[(i * 4) + 2] = _area[i].width();
+      dims[(i * 4) + 3] = _area[i].height();
+    }
+  }
+  otk::Property::set(_info->rootWindow(), otk::Property::atoms.net_workarea,
+                     otk::Property::atoms.cardinal, dims, 4 * _num_desktops);
+  delete [] dims;
 }
 
 
@@ -411,20 +450,6 @@ void Screen::changeStackingList()
 }
 
 
-void Screen::changeWorkArea() {
-  unsigned long *dims = new unsigned long[4 * _num_desktops];
-  for (long i = 0; i < _num_desktops; ++i) {
-    dims[(i * 4) + 0] = _area.x();
-    dims[(i * 4) + 1] = _area.y();
-    dims[(i * 4) + 2] = _area.width();
-    dims[(i * 4) + 3] = _area.height();
-  }
-  otk::Property::set(_info->rootWindow(), otk::Property::atoms.net_workarea,
-                     otk::Property::atoms.cardinal, dims, 4 * _num_desktops);
-  delete [] dims;
-}
-
-
 void Screen::manageWindow(Window window)
 {
   Client *client = 0;
@@ -526,7 +551,7 @@ void Screen::manageWindow(Window window)
   clients.push_back(client);
   // once the client is in the list, update our strut to include the new
   // client's (it is good that this happens after window placement!)
-  updateStrut();
+  updateStruts();
   // this puts into the stacking order, then raises it
   _stacking.push_back(client);
   raiseWindow(client);
@@ -592,7 +617,7 @@ void Screen::unmanageWindow(Client *client)
 
   // once the client is out of the list, update our strut to remove it's
   // influence
-  updateStrut();
+  updateStruts();
 
   // unset modal before dropping our focus
   client->_modal = false;
@@ -750,12 +775,14 @@ void Screen::changeNumDesktops(long num)
                      viewport, _num_desktops * 2);
   delete [] viewport;
 
-  // update the work area hint
-  changeWorkArea();
+  // change our struts/area to match
+  _area.resize(_num_desktops + 1);
+  _struts.resize(_num_desktops + 1);
+  updateStruts();
 
   // change our desktop if we're on one that no longer exists!
-  if (_desktop >= num)
-    changeDesktop(num - 1);
+  if (_desktop >= _num_desktops)
+    changeDesktop(_num_desktops - 1);
 }
 
 
@@ -786,6 +813,15 @@ void Screen::setDesktopName(long i, const otk::ustring &name)
 }
 
 
+const otk::Rect& Screen::area(long desktop) const {
+  assert(desktop >= 0 || desktop == (signed) 0xffffffff);
+  assert(desktop < _num_desktops || desktop == (signed) 0xffffffff);
+  if (desktop >= 0 && desktop < _num_desktops)
+    return _area[desktop];
+  else
+    return _area[_num_desktops];
+}
+
 void Screen::installColormap(bool install) const
 {
   if (install)
index 9244bb2d594ad88593100ad83d56376939cb03e0..16a4225b37697a11f514fde644662d76cbbdcb74 100644 (file)
@@ -30,7 +30,9 @@ class Client;
 class Screen : public otk::EventHandler {
 public:
   //! Holds a list of otk::Strut objects
-  typedef std::list<otk::Strut*> StrutList;
+  typedef std::vector<otk::Strut> StrutList;
+  //! Holds a list of otk::Rect objects
+  typedef std::vector<otk::Rect> RectList;
 
   static const unsigned long event_mask = ColormapChangeMask |
                                           EnterWindowMask |
@@ -59,11 +61,13 @@ private:
   //! Is the root colormap currently installed?
   bool _root_cmap_installed;
 
-  //! Area usable for placement etc (total - struts)
-  otk::Rect _area;
+  //! Area usable for placement etc (total - struts), one per desktop,
+  //! plus one extra for windows on all desktops
+  RectList _area;
 
-  //! Combined strut from all of the clients' struts
-  otk::Strut _strut;
+  //! Combined strut from all of the clients' struts, one per desktop,
+  //! plus one extra for windows on all desktops
+  StrutList _struts;
 
   //!  An offscreen window which gets focus when nothing else has it
   Window _focuswindow;
@@ -139,8 +143,6 @@ public:
     used.
   */
   inline bool managed() const { return _managed; }
-  //! Returns the area of the screen not reserved by applications' Struts
-  inline const otk::Rect &area() const { return _area; }
   //!  An offscreen window which gets focus when nothing else has it
   inline Window focuswindow() const { return _focuswindow; }
   //! Returns the desktop being displayed
@@ -148,11 +150,19 @@ public:
   //! Returns the number of desktops
   inline long numDesktops() const { return _num_desktops; }
 
+  //! Returns the area of the screen not reserved by applications' Struts
+  /*!
+    @param desktop The desktop number of the area to retrieve for. A value of
+                   0xffffffff will return an area that combines all struts
+                   on all desktops.
+  */
+  const otk::Rect& area(long desktop) const;
+
   //! Update's the screen's combined strut of all the clients.
   /*!
     Clients should call this whenever they change their strut.
   */
-  void updateStrut();
+  void updateStruts();
 
   //! Manage any pre-existing windows on the screen
   void manageExisting();
This page took 0.044023 seconds and 4 git commands to generate.