]> Dogcows Code - chaz/openbox/blobdiff - src/screen.cc
free the colors on shutdown
[chaz/openbox] / src / screen.cc
index a2514276d8cdb805081849e297cf835ba9f80282..039d82050fa770004a9f2ff93ef877ba7353d33d 100644 (file)
@@ -2,6 +2,15 @@
 
 #include "config.h"
 
+#include "screen.hh"
+#include "client.hh"
+#include "openbox.hh"
+#include "frame.hh"
+#include "bindings.hh"
+#include "python.hh"
+#include "otk/display.hh"
+#include "otk/property.hh"
+
 extern "C" {
 #ifdef    HAVE_UNISTD_H
 #  include <sys/types.h>
@@ -12,15 +21,6 @@ extern "C" {
 #define _(str) gettext(str)
 }
 
-#include "screen.hh"
-#include "client.hh"
-#include "openbox.hh"
-#include "frame.hh"
-#include "bindings.hh"
-#include "python.hh"
-#include "otk/display.hh"
-#include "otk/property.hh"
-
 #include <vector>
 #include <algorithm>
 #include <cstdio>
@@ -111,6 +111,12 @@ Screen::Screen(int screen)
 
   changeDesktop(0); // set the hint
 
+  // don't start in showing-desktop mode
+  _showing_desktop = false;
+  otk::Property::set(_info->rootWindow(),
+                     otk::Property::atoms.net_showing_desktop,
+                     otk::Property::atoms.cardinal, 0);
+
   // create the window which gets focus when no clients get it
   XSetWindowAttributes attr;
   attr.override_redirect = true;
@@ -123,6 +129,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 +206,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()
 {
@@ -336,13 +403,13 @@ void Screen::changeSupportedAtoms()
     otk::Property::atoms.net_client_list_stacking,
     otk::Property::atoms.net_desktop_names,
     otk::Property::atoms.net_close_window,
+    otk::Property::atoms.net_desktop_layout,
+    otk::Property::atoms.net_showing_desktop,
     otk::Property::atoms.net_wm_name,
     otk::Property::atoms.net_wm_visible_name,
     otk::Property::atoms.net_wm_icon_name,
     otk::Property::atoms.net_wm_visible_icon_name,
-/*
     otk::Property::atoms.net_wm_desktop,
-*/
     otk::Property::atoms.net_wm_strut,
     otk::Property::atoms.net_wm_window_type,
     otk::Property::atoms.net_wm_window_type_desktop,
@@ -684,9 +751,6 @@ void Screen::raiseWindow(Client *client)
   const ClientList::iterator end = _stacking.end();
 
   // the stacking list is from highest to lowest
-//  for (;it != end, ++it) {
-//    if ((*it)->layer() <= client->layer() && m != *it) break;
-//  }
   for (; it != end && ((*it)->layer() > client->layer() || m == *it); ++it);
 
   /*
@@ -770,6 +834,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);
@@ -800,6 +867,11 @@ void Screen::setDesktopName(unsigned int i, const otk::ustring &name)
                      otk::Property::utf8, newnames);
 }
 
+otk::ustring Screen::desktopName(unsigned int i) const
+{
+  if (i >= _num_desktops) return "";
+  return _desktop_names[i];
+}
 
 const otk::Rect& Screen::area(unsigned int desktop) const {
   assert(desktop < _num_desktops || desktop == 0xffffffff);
@@ -817,6 +889,41 @@ void Screen::installColormap(bool install) const
     XUninstallColormap(**otk::display, _info->colormap());
 }
 
+void Screen::showDesktop(bool show)
+{
+  if (show == _showing_desktop) return; // no change
+
+  // save the window focus, and restore it when leaving the show-desktop mode
+  static Window saved_focus = 0;
+  if (show) {
+    Client *c = openbox->focusedClient();
+    if (c) saved_focus = c->window();
+  }
+  
+  _showing_desktop = show;
+
+  ClientList::iterator it, end = clients.end();
+  for (it = clients.begin(); it != end; ++it) {
+    if ((*it)->type() == Client::Type_Desktop) {
+      if (show)
+        (*it)->focus();
+    } else
+      (*it)->showhide();
+  }
+
+  if (!show) {
+    Client *f = openbox->focusedClient();
+    if (!f || f->type() == Client::Type_Desktop) {
+      Client *c = openbox->findClient(saved_focus);
+      if (c) c->focus();
+    }
+  }
+
+  otk::Property::set(_info->rootWindow(),
+                     otk::Property::atoms.net_showing_desktop,
+                     otk::Property::atoms.cardinal,
+                     show ? 1 : 0);
+}
 
 void Screen::propertyHandler(const XPropertyEvent &e)
 {
@@ -836,6 +943,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();
 }
 
 
@@ -849,6 +958,8 @@ void Screen::clientMessageHandler(const XClientMessageEvent &e)
     changeDesktop(e.data.l[0]);
   } else if (e.message_type == otk::Property::atoms.net_number_of_desktops) {
     changeNumDesktops(e.data.l[0]);
+  } else if (e.message_type == otk::Property::atoms.net_showing_desktop) {
+    showDesktop(e.data.l[0] != 0);
   }
 }
 
@@ -866,8 +977,11 @@ void Screen::mapRequestHandler(const XMapRequestEvent &e)
 #ifdef DEBUG
     printf("DEBUG: MAP REQUEST CAUGHT IN SCREEN. IGNORED.\n");
 #endif
-  } else
+  } else {
+    if (_showing_desktop)
+      showDesktop(false); // leave showing-the-desktop mode
     manageWindow(e.window);
+  }
 }
 
 }
This page took 0.024754 seconds and 4 git commands to generate.