]> Dogcows Code - chaz/openbox/blobdiff - src/client.cc
add new actions from the ewmh spec
[chaz/openbox] / src / client.cc
index 9667a6f941a383864d732a1a0d3e9cb3692cc6ae..e8a6b84bd14028f96b0e7e08147a09c454a7b9e3 100644 (file)
@@ -60,7 +60,8 @@ Client::Client(int screen, Window window)
   getShaped();
 
   updateProtocols();
-  updateNormalHints();
+  getGravity(); // get the attribute gravity
+  updateNormalHints(); // this may override the attribute gravity
   updateWMHints();
   updateTitle();
   updateIconTitle();
@@ -91,6 +92,17 @@ Client::~Client()
 }
 
 
+void Client::getGravity()
+{
+  XWindowAttributes wattrib;
+  Status ret;
+
+  ret = XGetWindowAttributes(**otk::display, _window, &wattrib);
+  assert(ret != BadWindow);
+  _gravity = wattrib.win_gravity;
+}
+
+
 void Client::getDesktop()
 {
   // defaults to the current desktop
@@ -222,7 +234,7 @@ void Client::setupDecorAndFunctions()
     }
   }
 
-  // XXX: changeAllowedActions();
+  changeAllowedActions();
 }
 
 
@@ -378,7 +390,6 @@ void Client::updateNormalHints()
   int oldgravity = _gravity;
 
   // defaults
-  _gravity = NorthWestGravity;
   _size_inc.setPoint(1, 1);
   _base_size.setPoint(0, 0);
   _min_size.setPoint(0, 0);
@@ -391,8 +402,18 @@ void Client::updateNormalHints()
   if (XGetWMNormalHints(**otk::display, _window, &size, &ret)) {
     _positioned = (size.flags & (PPosition|USPosition));
 
-    if (size.flags & PWinGravity)
+    if (size.flags & PWinGravity) {
       _gravity = size.win_gravity;
+      
+      // if the client has a frame, i.e. has already been mapped and is
+      // changing its gravity
+      if (frame && _gravity != oldgravity) {
+        // move our idea of the client's position based on its new gravity
+        int x, y;
+        frame->frameGravity(x, y);
+        _area.setPos(x, y);
+      }
+    }
 
     if (size.flags & PMinSize)
       _min_size.setPoint(size.min_width, size.min_height);
@@ -406,15 +427,6 @@ void Client::updateNormalHints()
     if (size.flags & PResizeInc)
       _size_inc.setPoint(size.width_inc, size.height_inc);
   }
-
-  // if the client has a frame, i.e. has already been mapped and is
-  // changing its gravity
-  if (frame && _gravity != oldgravity) {
-    // move our idea of the client's position based on its new gravity
-    int x, y;
-    frame->frameGravity(x, y);
-    _area.setPos(x, y);
-  }
 }
 
 
@@ -756,6 +768,7 @@ void Client::toggleClientBorder(bool addborder)
   // reversed.
   int x = _area.x(), y = _area.y();
   switch(_gravity) {
+  default:
   case NorthWestGravity:
   case WestGravity:
   case SouthWestGravity:
@@ -766,8 +779,17 @@ void Client::toggleClientBorder(bool addborder)
     if (addborder) x -= _border_width * 2;
     else           x += _border_width * 2;
     break;
+  case NorthGravity:
+  case SouthGravity:
+  case CenterGravity:
+  case ForgetGravity:
+  case StaticGravity:
+    if (addborder) x -= _border_width;
+    else           x += _border_width;
+    break;
   }
   switch(_gravity) {
+  default:
   case NorthWestGravity:
   case NorthGravity:
   case NorthEastGravity:
@@ -778,8 +800,13 @@ void Client::toggleClientBorder(bool addborder)
     if (addborder) y -= _border_width * 2;
     else           y += _border_width * 2;
     break;
-  default:
-    // no change for StaticGravity etc.
+  case WestGravity:
+  case EastGravity:
+  case CenterGravity:
+  case ForgetGravity:
+  case StaticGravity:
+    if (addborder) y -= _border_width;
+    else           y += _border_width;
     break;
   }
   _area.setPos(x, y);
@@ -874,7 +901,14 @@ void Client::shapeHandler(const XShapeEvent &e)
 #endif
 
 
-void Client::resize(Corner anchor, int w, int h, int x, int y)
+void Client::resize(Corner anchor, int w, int h)
+{
+  if (!(_functions & Func_Resize)) return;
+  internal_resize(anchor, w, h);
+}
+
+
+void Client::internal_resize(Corner anchor, int w, int h, int x, int y)
 {
   w -= _base_size.x(); 
   h -= _base_size.y();
@@ -936,11 +970,18 @@ void Client::resize(Corner anchor, int w, int h, int x, int y)
 
   // resize the frame to match the request
   frame->adjustSize();
-  move(x, y);
+  internal_move(x, y);
 }
 
 
 void Client::move(int x, int y)
+{
+  if (!(_functions & Func_Move)) return;
+  internal_move(x, y);
+}
+
+
+void Client::internal_move(int x, int y)
 {
   _area.setPos(x, y);
 
@@ -1031,6 +1072,30 @@ void Client::changeState()
 }
 
 
+void Client::changeAllowedActions(void)
+{
+  Atom actions[7];
+  int num = 0;
+
+  actions[num++] = otk::Property::atoms.net_wm_action_shade;
+  actions[num++] = otk::Property::atoms.net_wm_action_change_desktop;
+
+  if (_functions & Func_Close)
+    actions[num++] = otk::Property::atoms.net_wm_action_close;
+  if (_functions & Func_Move)
+        actions[num++] = otk::Property::atoms.net_wm_action_move;
+  if (_functions & Func_Resize)
+        actions[num++] = otk::Property::atoms.net_wm_action_resize;
+  if (_functions & Func_Maximize) {
+    actions[num++] = otk::Property::atoms.net_wm_action_maximize_horz;
+    actions[num++] = otk::Property::atoms.net_wm_action_maximize_vert;
+  }
+
+  otk::Property::set(_window, otk::Property::atoms.net_wm_allowed_actions,
+                     otk::Property::atoms.atom, actions, num);
+}
+
+
 void Client::shade(bool shade)
 {
   if (shade == _shaded) return; // already done
@@ -1152,13 +1217,13 @@ void Client::configureRequestHandler(const XConfigureRequestEvent &e)
     if (e.value_mask & (CWX | CWY)) {
       int x = (e.value_mask & CWX) ? e.x : _area.x();
       int y = (e.value_mask & CWY) ? e.y : _area.y();
-      resize(corner, w, h, x, y);
+      internal_resize(corner, w, h, x, y);
     } else // if JUST resizing...
-      resize(corner, w, h);
+      internal_resize(corner, w, h);
   } else if (e.value_mask & (CWX | CWY)) { // if JUST moving...
     int x = (e.value_mask & CWX) ? e.x : _area.x();
     int y = (e.value_mask & CWY) ? e.y : _area.y();
-    move(x, y);
+    internal_move(x, y);
   }
 
   if (e.value_mask & CWStackMode) {
This page took 0.023869 seconds and 4 git commands to generate.