]> Dogcows Code - chaz/openbox/blobdiff - src/client.cc
if a dock has the 'below' state set, then it goes in the normal window layer
[chaz/openbox] / src / client.cc
index ddecfc62b7cd48e6d26cd6be04c6da962f09d443..2bb157806bce3ac5d26980e48958d68ea245bfab 100644 (file)
@@ -44,16 +44,17 @@ OBClient::OBClient(int screen, Window window)
   
   getArea();
   getDesktop();
+  // XXX: updateTransientFor();
   getType();
 
   // set the decorations and functions
+  _decorations = Decor_Titlebar | Decor_Handle | Decor_Border |
+    Decor_Iconify | Decor_Maximize;
+  _functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize;
   switch (_type) {
   case Type_Normal:
     // normal windows retain all of the possible decorations and
     // functionality
-    _decorations = Decor_Titlebar | Decor_Handle | Decor_Border |
-                   Decor_Iconify | Decor_Maximize;
-    _functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize;
 
   case Type_Dialog:
     // dialogs cannot be maximized
@@ -85,12 +86,13 @@ OBClient::OBClient(int screen, Window window)
   updateProtocols();
   updateNormalHints();
   updateWMHints();
-  // XXX: updateTransientFor();
   updateTitle();
   updateIconTitle();
   updateClass();
+  updateStrut();
 
   calcLayer();
+  changeState();
 }
 
 
@@ -313,9 +315,12 @@ void OBClient::getShaped()
 
 void OBClient::calcLayer() {
   if (_iconic) _layer = OBScreen::Layer_Icon;
-  else if (_type == Type_Desktop) _layer = OBScreen::Layer_Desktop;
-  else if (_type == Type_Dock) _layer = OBScreen::Layer_Top;
   else if (_fullscreen) _layer = OBScreen::Layer_Fullscreen;
+  else if (_type == Type_Desktop) _layer = OBScreen::Layer_Desktop;
+  else if (_type == Type_Dock) {
+    if (!_below) _layer = OBScreen::Layer_Top;
+    else _layer = OBScreen::Layer_Normal;
+  }
   else if (_above) _layer = OBScreen::Layer_Above;
   else if (_below) _layer = OBScreen::Layer_Below;
   else _layer = OBScreen::Layer_Normal;
@@ -338,7 +343,8 @@ void OBClient::updateProtocols()
       if (proto[i] == property->atom(otk::OBProperty::wm_delete_window)) {
         _decorations |= Decor_Close;
         _functions |= Func_Close;
-        // XXX: update the decor?
+        if (frame)
+          frame->adjustSize(); // update the decorations
       } else if (proto[i] == property->atom(otk::OBProperty::wm_take_focus))
         // if this protocol is requested, then the window will be notified
         // by the window manager whenever it receives focus
@@ -485,6 +491,29 @@ void OBClient::updateClass()
 }
 
 
+void OBClient::updateStrut()
+{
+  unsigned long num = 4;
+  unsigned long *data;
+  if (!Openbox::instance->property()->get(_window,
+                                          otk::OBProperty::net_wm_strut,
+                                          otk::OBProperty::Atom_Cardinal,
+                                          &num, &data))
+    return;
+
+  if (num == 4) {
+    _strut.left = data[0];
+    _strut.right = data[1];
+    _strut.top = data[2];
+    _strut.bottom = data[3];
+    
+    Openbox::instance->screen(_screen)->updateStrut();
+  }
+
+  delete [] data;
+}
+
+
 void OBClient::propertyHandler(const XPropertyEvent &e)
 {
   otk::OtkEventHandler::propertyHandler(e);
@@ -517,6 +546,8 @@ void OBClient::propertyHandler(const XPropertyEvent &e)
   else if (e.atom == property->atom(otk::OBProperty::wm_protocols))
     updateProtocols();
   // XXX: transient for hint
+  else if (e.atom == property->atom(otk::OBProperty::net_wm_strut))
+    updateStrut();
   // XXX: strut hint
 }
 
@@ -784,21 +815,23 @@ void OBClient::clientMessageHandler(const XClientMessageEvent &e)
              property->atom(otk::OBProperty::net_active_window)) {
     focus();
     Openbox::instance->screen(_screen)->restack(true, this); // raise
+  } else {
   }
 }
 
 
-#if defined(SHAPE) || defined(DOXYGEN_IGNORE)
+#if defined(SHAPE)
 void OBClient::shapeHandler(const XShapeEvent &e)
 {
   otk::OtkEventHandler::shapeHandler(e);
   
   _shaped = e.shaped;
+  frame->adjustShape();
 }
 #endif
 
 
-void OBClient::resize(Corner anchor, int w, int h)
+void OBClient::resize(Corner anchor, int w, int h, int x, int y)
 {
   w -= _base_size.x(); 
   h -= _base_size.y();
@@ -831,23 +864,27 @@ void OBClient::resize(Corner anchor, int w, int h)
   w += _base_size.x();
   h += _base_size.y();
 
-  int x = _area.x(), y = _area.y();  
-  switch (anchor) {
-  case TopLeft:
-    break;
-  case TopRight:
-    x -= w - _area.width();
-    break;
-  case BottomLeft:
-    y -= h - _area.height();
-    break;
-  case BottomRight:
-    x -= w - _area.width();
-    y -= h - _area.height();
-    break;
+  if (x == INT_MIN || y == INT_MIN) {
+    x = _area.x();
+    y = _area.y();
+    switch (anchor) {
+    case TopLeft:
+      break;
+    case TopRight:
+      x -= w - _area.width();
+      break;
+    case BottomLeft:
+      y -= h - _area.height();
+      break;
+    case BottomRight:
+      x -= w - _area.width();
+      y -= h - _area.height();
+      break;
+    }
   }
 
   _area.setSize(w, h);
+
   XResizeWindow(otk::OBDisplay::display, _window, w, h);
 
   // resize the frame to match the request
@@ -859,6 +896,7 @@ void OBClient::resize(Corner anchor, int w, int h)
 void OBClient::move(int x, int y)
 {
   _area.setPos(x, y);
+
   // move the frame to be in the requested position
   frame->adjustPosition();
 }
@@ -873,6 +911,9 @@ void OBClient::close()
 
   // XXX: itd be cool to do timeouts and shit here for killing the client's
   //      process off
+  // like... if the window is around after 5 seconds, then the close button
+  // turns a nice red, and if this function is called again, the client is
+  // explicitly killed.
 
   ce.xclient.type = ClientMessage;
   ce.xclient.message_type =  property->atom(otk::OBProperty::wm_protocols);
@@ -928,6 +969,24 @@ void OBClient::changeState()
   
 }
 
+
+void OBClient::setStackLayer(int l)
+{
+  if (l == 0)
+    _above = _below = false;  // normal
+  else if (l > 0) {
+    _above = true;
+    _below = false; // above
+  } else {
+    _above = false;
+    _below = true;  // below
+  }
+  changeState();
+  calcLayer();
+  Openbox::instance->screen(_screen)->restack(true, this); // raise
+}
+
+
 void OBClient::shade(bool shade)
 {
   if (shade == _shaded) return; // already done
@@ -1044,10 +1103,14 @@ void OBClient::configureRequestHandler(const XConfigureRequestEvent &e)
       corner = TopLeft;
     }
 
-    resize(corner, w, h);
-  }
-
-  if (e.value_mask & (CWX | CWY)) {
+    // if moving AND resizing ...
+    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);
+    } else // if JUST resizing...
+      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);
This page took 0.029862 seconds and 4 git commands to generate.