]> Dogcows Code - chaz/openbox/commitdiff
add support for desktop layouts specified by pagers
authorDana Jansens <danakj@orodu.net>
Mon, 10 Feb 2003 16:12:33 +0000 (16:12 +0000)
committerDana Jansens <danakj@orodu.net>
Mon, 10 Feb 2003 16:12:33 +0000 (16:12 +0000)
scripts/callbacks.py
scripts/defaults.py
src/screen.cc
src/screen.hh

index 6c33bc7792696f83617469984824faaf366cf5d7..f7cb37c1e7e19a03a6b7a29a2277f98b550cfe19 100644 (file)
@@ -209,7 +209,71 @@ def prev_desktop(data, no_wrap=0):
         d = n - 1
     change_desktop(data, d)
 
-def send_to_desktop(data, num):
+def up_desktop(data, num=1):
+    """Switches to the desktop vertically above the current one. This is based
+       on the desktop layout chosen by an EWMH compliant pager. Optionally, num
+       can be specified to move more than one row at a time."""
+    screen = ob.openbox.screen(data.screen)
+    d = screen.desktop()
+    n = screen.numDesktops()
+    l = screen.desktopLayout()
+
+    target = d - num * l.columns
+    if target < 0:
+        target += l.rows * l.columns
+    while target >= n:
+        target -= l.columns
+    change_desktop(data, target)
+
+def down_desktop(data, num=1):
+    """Switches to the desktop vertically below the current one. This is based
+       on the desktop layout chosen by an EWMH compliant pager. Optionally, num
+       can be specified to move more than one row at a time."""
+    screen = ob.openbox.screen(data.screen)
+    d = screen.desktop()
+    n = screen.numDesktops()
+    l = screen.desktopLayout()
+
+    target = d + num * l.columns
+    if target >= n:
+        target -= l.rows * l.columns
+    while target < 0:
+        target += l.columns
+    change_desktop(data, target)
+
+def left_desktop(data, num=1):
+    """Switches to the desktop horizotally left of the current one. This is
+       based on the desktop layout chosen by an EWMH compliant pager.
+       Optionally, num can be specified to move more than one column at a
+       time."""
+    screen = ob.openbox.screen(data.screen)
+    d = screen.desktop()
+    n = screen.numDesktops()
+    l = screen.desktopLayout()
+
+    rowstart = d - d % l.columns
+    target = d - num
+    while target < rowstart:
+        target += l.columns
+    change_desktop(data, target)
+
+def right_desktop(data, num=1):
+    """Switches to the desktop horizotally right of the current one. This is
+       based on the desktop layout chosen by an EWMH compliant pager.
+       Optionally, num can be specified to move more than one column at a
+       time."""
+    screen = ob.openbox.screen(data.screen)
+    d = screen.desktop()
+    n = screen.numDesktops()
+    l = screen.desktopLayout()
+
+    rowstart = d - d % l.columns
+    target = d + num
+    while target >= rowstart + l.columns:
+        target -= l.columns
+    change_desktop(data, target)
+
+def send_to_desktop(data, num=1):
     """Sends a client to a specified desktop"""
     if not data.client: return
     ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
index 04143e115bc4ba63acdcd9899cbf5b94bc14ba8f..98c57ce5dd2c3e60525e6e9cf595d0bc1a26d766 100644 (file)
@@ -53,9 +53,13 @@ ob.kbind(["C-2"], ob.KeyContext.All, lambda(d): callbacks.change_desktop(d, 1))
 ob.kbind(["C-3"], ob.KeyContext.All, lambda(d): callbacks.change_desktop(d, 2))
 ob.kbind(["C-4"], ob.KeyContext.All, lambda(d): callbacks.change_desktop(d, 3))
 ob.kbind(["C-A-Right"], ob.KeyContext.All,
-         lambda(d): callbacks.next_desktop(d))
+         lambda(d): callbacks.right_desktop(d))
 ob.kbind(["C-A-Left"], ob.KeyContext.All,
-         lambda(d): callbacks.prev_desktop(d))
+         lambda(d): callbacks.left_desktop(d))
+ob.kbind(["C-A-Up"], ob.KeyContext.All,
+         lambda(d): callbacks.up_desktop(d))
+ob.kbind(["C-A-Down"], ob.KeyContext.All,
+         lambda(d): callbacks.down_desktop(d))
 
 ob.kbind(["C-S-A-Right"], ob.KeyContext.All,
          lambda(d): callbacks.send_to_next_desktop(d))
index a2514276d8cdb805081849e297cf835ba9f80282..b556e7acdc3e02d4b1868d753f8c74180d9c3d56 100644 (file)
@@ -123,6 +123,8 @@ Screen::Screen(int screen)
   // the manageExising() function
   changeClientList();  // initialize the client lists, which will be empty
 
+  updateDesktopLayout();
+
   // register this class as the event handler for the root window
   openbox->registerHandler(_info->rootWindow(), this);
 
@@ -198,6 +200,65 @@ void Screen::manageExisting()
   XFree(children);
 }
 
+void Screen::updateDesktopLayout()
+{
+  //const unsigned long _NET_WM_ORIENTATION_HORZ = 0;
+  const unsigned long _NET_WM_ORIENTATION_VERT = 1;
+  //const unsigned long _NET_WM_TOPLEFT = 0;
+  const unsigned long _NET_WM_TOPRIGHT = 1;
+  const unsigned long _NET_WM_BOTTOMRIGHT = 2;
+  const unsigned long _NET_WM_BOTTOMLEFT = 3;
+  
+  // defaults
+  _layout.orientation = DesktopLayout::Horizontal;
+  _layout.start_corner = DesktopLayout::TopLeft;
+  _layout.rows = 1;
+  _layout.columns = _num_desktops;
+
+  unsigned long *data, num = 4;
+  if (otk::Property::get(_info->rootWindow(),
+                         otk::Property::atoms.net_desktop_layout,
+                         otk::Property::atoms.cardinal,
+                         &num, &data)) {
+    if (num >= 4) {
+      if (data[0] == _NET_WM_ORIENTATION_VERT)
+        _layout.orientation = DesktopLayout::Vertical;
+      if (data[3] == _NET_WM_TOPRIGHT)
+        _layout.start_corner = DesktopLayout::TopRight;
+      else if (data[3] == _NET_WM_BOTTOMRIGHT)
+        _layout.start_corner = DesktopLayout::BottomRight;
+      else if (data[3] == _NET_WM_BOTTOMLEFT)
+        _layout.start_corner = DesktopLayout::BottomLeft;
+
+      // fill in a zero rows/columns
+      if (!(data[1] == 0 && data[2] == 0)) { // both 0's is bad data..
+        if (data[1] == 0) {
+          data[1] = (_num_desktops + _num_desktops % data[2]) / data[2];
+        } else if (data[2] == 0) {
+          data[2] = (_num_desktops + _num_desktops % data[1]) / data[1];
+        }
+        _layout.columns = data[1];
+        _layout.rows = data[2];
+      }
+
+      // bounds checking
+      if (_layout.orientation == DesktopLayout::Horizontal) {
+        if (_layout.rows > _num_desktops) _layout.rows = _num_desktops;
+        if (_layout.columns > (_num_desktops + _num_desktops % _layout.rows) /
+            _layout.rows)
+          _layout.columns = (_num_desktops + _num_desktops % _layout.rows) /
+            _layout.rows;
+      } else {
+        if (_layout.columns > _num_desktops) _layout.columns = _num_desktops;
+        if (_layout.rows > (_num_desktops + _num_desktops % _layout.columns) /
+            _layout.columns)
+          _layout.rows = (_num_desktops + _num_desktops % _layout.columns) /
+            _layout.columns;
+      }
+    }
+    delete [] data;
+  }
+}
 
 void Screen::updateStruts()
 {
@@ -770,6 +831,9 @@ void Screen::changeNumDesktops(unsigned int num)
   _struts.resize(_num_desktops + 1);
   updateStruts();
 
+  // the number of rows/columns will differ
+  updateDesktopLayout();
+
   // change our desktop if we're on one that no longer exists!
   if (_desktop >= _num_desktops)
     changeDesktop(_num_desktops - 1);
@@ -836,6 +900,8 @@ void Screen::propertyHandler(const XPropertyEvent &e)
 
   if (e.atom == otk::Property::atoms.net_desktop_names)
     updateDesktopNames();
+  else if (e.atom == otk::Property::atoms.net_desktop_layout)
+    updateDesktopLayout();
 }
 
 
index 9b3618c92df787735c769cee5a584fa9e29480a4..adccf180128af8d7ef83942a0da1648ec97e1e54 100644 (file)
@@ -24,6 +24,16 @@ namespace ob {
 
 class Client;
 
+struct DesktopLayout {
+  enum Corner { TopLeft, TopRight, BottomRight, BottomLeft };
+  enum Direction { Horizontal, Vertical };
+
+  Direction orientation;
+  Corner start_corner;
+  unsigned int rows;
+  unsigned int columns;
+};
+
 //! Manages a single screen
 /*!
 */
@@ -58,9 +68,6 @@ private:
   //! Information about this screen
   const otk::ScreenInfo *_info;
   
-  //! Is the root colormap currently installed?
-  bool _root_cmap_installed;
-
   //! Area usable for placement etc (total - struts), one per desktop,
   //! plus one extra for windows on all desktops
   RectList _area;
@@ -88,6 +95,8 @@ private:
   //! The names of all desktops
   otk::Property::StringVect _desktop_names;
 
+  DesktopLayout _layout;
+
   //! Calculate the Screen::_area member
   void calcArea();
   //! Set the list of supported NETWM atoms on the root window
@@ -112,6 +121,9 @@ private:
   //! Get desktop names from the root window property
   void updateDesktopNames();
 
+  //! Gets the layout of the desktops from the root window property
+  void updateDesktopLayout();
+
   //! Changes to the specified desktop, displaying windows on it and hiding
   //! windows on the others.
   /*!
@@ -158,6 +170,8 @@ public:
   */
   const otk::Rect& area(unsigned int desktop) const;
 
+  const DesktopLayout& desktopLayout() const { return _layout; }
+
   //! Update's the screen's combined strut of all the clients.
   /*!
     Clients should call this whenever they change their strut.
This page took 0.036011 seconds and 4 git commands to generate.