]> Dogcows Code - chaz/openbox/commitdiff
PROPERLY HANDLE CLIENT BORDERS
authorDana Jansens <danakj@orodu.net>
Thu, 5 Dec 2002 13:45:00 +0000 (13:45 +0000)
committerDana Jansens <danakj@orodu.net>
Thu, 5 Dec 2002 13:45:00 +0000 (13:45 +0000)
PROPERLY HANDLE CLIENT GRAVITY
YES!#%&*#!#!
windows can be moved/resized now (and the frame will play along)!

src/client.cc
src/client.hh
src/frame.cc
src/frame.hh
src/rootwindow.cc
src/rootwindow.hh
src/screen.cc

index aef3dcbafe59287545e44203ee20cc35cf502285..07d754624ad29aacbb4b635d52d54e3548ec6572 100644 (file)
@@ -26,7 +26,7 @@ namespace ob {
 
 OBClient::OBClient(int screen, Window window)
   : otk::OtkEventHandler(),
-    _screen(screen), _window(window)
+    frame(0), _screen(screen), _window(window)
 {
   assert(screen >= 0);
   assert(window);
@@ -371,6 +371,7 @@ void OBClient::updateNormalHints()
 {
   XSizeHints size;
   long ret;
+  int oldgravity = _gravity;
 
   // defaults
   _gravity = NorthWestGravity;
@@ -388,7 +389,7 @@ void OBClient::updateNormalHints()
 
     if (size.flags & PWinGravity)
       _gravity = size.win_gravity;
-    
+
     if (size.flags & PMinSize)
       _min_size.setPoint(size.min_width, size.min_height);
     
@@ -401,6 +402,15 @@ void OBClient::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);
+  }
 }
 
 
@@ -651,6 +661,57 @@ void OBClient::setState(StateAction action, long data1, long data2)
 }
 
 
+void OBClient::toggleClientBorder(bool addborder)
+{
+  // adjust our idea of where the client is, based on its border. When the
+  // border is removed, the client should now be considered to be in a
+  // different position.
+  // when re-adding the border to the client, the same operation needs to be
+  // reversed.
+  int x = _area.x(), y = _area.y();
+  switch(_gravity) {
+  case NorthWestGravity:
+  case WestGravity:
+  case SouthWestGravity:
+    if (addborder) x += _border_width;
+    else           x -= _border_width;
+    break;
+  case NorthEastGravity:
+  case EastGravity:
+  case SouthEastGravity:
+    if (addborder) x -= _border_width * 2;
+    else           x += _border_width * 2;
+    break;
+  }
+  switch(_gravity) {
+  case NorthWestGravity:
+  case NorthGravity:
+  case NorthEastGravity:
+    if (addborder) y += _border_width;
+    else           y -= _border_width;
+    break;
+  case SouthWestGravity:
+  case SouthGravity:
+  case SouthEastGravity:
+    if (addborder) y -= _border_width * 2;
+    else           y += _border_width * 2;
+    break;
+  default:
+    // no change for StaticGravity etc.
+    break;
+  }
+  _area.setPos(x, y);
+
+  if (addborder) {
+    XSetWindowBorderWidth(otk::OBDisplay::display, _window, _border_width);
+
+    // move the client so it is back it the right spot _with_ its border!
+    XMoveWindow(otk::OBDisplay::display, _window, x, y);
+  } else
+    XSetWindowBorderWidth(otk::OBDisplay::display, _window, 0);
+}
+
+
 void OBClient::clientMessageHandler(const XClientMessageEvent &e)
 {
   otk::OtkEventHandler::clientMessageHandler(e);
@@ -738,26 +799,29 @@ 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:
-    _area.setX(_area.x() - _area.width() - w);
+    x -= w - _area.width();
     break;
   case BottomLeft:
-    _area.setY(_area.y() - _area.height() - h);
+    y -= h - _area.height();
     break;
   case BottomRight:
-    _area.setX(_area.x() - _area.width() - w);
-    _area.setY(_area.y() - _area.height() - h);
+    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
-  frame->adjust();
+  // resize the frame to match the request
+  frame->adjustSize();
+  move(x, y);
 }
 
 
@@ -765,14 +829,14 @@ void OBClient::move(int x, int y)
 {
   _area.setPos(x, y);
   // move the frame to be in the requested position
-  frame->applyGravity();
+  frame->adjustPosition();
 }
 
 
 void OBClient::configureRequestHandler(const XConfigureRequestEvent &e)
 {
   OtkEventHandler::configureRequestHandler(e);
-  
+
   // XXX: if we are iconic (or shaded? (fvwm does that)) ignore the event
 
   if (e.value_mask & CWBorderWidth)
index e07ce12df32c1e955f2075abdf1ad99641730944..37e26cb2af98a440d5dd10f4923a4516fec580ee 100644 (file)
@@ -297,10 +297,6 @@ private:
   // XXX: updateTransientFor();
 
   //! Move the client window
-  /*!
-    This shouldnt be used to move the window internally! It will apply
-    window gravity after moving the window.
-  */
   void move(int x, int y);
   
   //! Resizes the client window, anchoring it in a given corner
@@ -409,8 +405,13 @@ public:
   */
   inline bool floating() const { return _floating; }
 
-  //! Returns the client's requested border width (not used by the wm)
-  inline int borderWidth() const { return _border_width; }
+  //! Removes or reapplies the client's border to its window
+  /*!
+    Used when managing and unmanaging a window.
+    @param addborder true if adding the border to the client; false if removing
+                     from the client
+  */
+  void toggleClientBorder(bool addborder);
 
   //! Returns the position and size of the client relative to the root window
   inline const otk::Rect &area() const { return _area; }
index aa1e868f14b36d850d1745821632814cb195120a..15404f93d68d66b4beb505504ab34e9be4e97063 100644 (file)
@@ -104,7 +104,6 @@ void OBFrame::setStyle(otk::Style *style)
 
   if (replace) {
     // XXX: do shit here whatever
-    // XXX: save the position based on gravity
   }
   
   _style = style;
@@ -125,12 +124,15 @@ void OBFrame::setStyle(otk::Style *style)
                    _style->getBorderColor()->pixel());
   
   // if !replace, then adjust() will get called after the client is grabbed!
-  if (replace)
-    adjust(); // size/position everything
+  if (replace) {
+    // size/position everything
+    adjustSize();
+    adjustPosition();
+  }
 }
 
 
-void OBFrame::adjust()
+void OBFrame::adjustSize()
 {
   // XXX: only if not overridden or something!!! MORE LOGIC HERE!!
   _decorations = _client->decorations();
@@ -311,6 +313,14 @@ void OBFrame::adjust()
 }
 
 
+void OBFrame::adjustPosition()
+{
+  int x, y;
+  clientGravity(x, y);
+  move(x, y);
+}
+
+
 void OBFrame::adjustShape()
 {
 #ifdef SHAPE
@@ -365,15 +375,15 @@ void OBFrame::grabClient()
                   _plate.getWindow(), 0, 0);
   _client->ignore_unmaps++;
 
-  // select the event mask on the client's parent
-  //XSelectInput(otk::OBDisplay::display, _plate.getWindow(),
-  //             SubstructureRedirectMask);
+  // select the event mask on the client's parent (to receive config req's)
+  XSelectInput(otk::OBDisplay::display, _plate.getWindow(),
+               SubstructureRedirectMask);
 
   // map the client so it maps when the frame does
   XMapWindow(otk::OBDisplay::display, _client->window());
 
-  adjust();
-  applyGravity();
+  adjustSize();
+  adjustPosition();
 }
 
 
@@ -399,69 +409,115 @@ void OBFrame::releaseClient(bool remap)
 }
 
 
-void OBFrame::applyGravity()
+void OBFrame::clientGravity(int &x, int &y)
 {
-  int x, y;
-  // apply horizontal window gravity
+  x = _client->area().x();
+  y = _client->area().y();
+
+  // horizontal
   switch (_client->gravity()) {
   default:
   case NorthWestGravity:
   case SouthWestGravity:
   case WestGravity:
-    x = _client->area().x();
     break;
 
   case NorthGravity:
   case SouthGravity:
   case CenterGravity:
-    x = _client->area().x() - (_size.left + _size.right) / 2;
+    x -= (_size.left + _size.right) / 2;
     break;
 
   case NorthEastGravity:
   case SouthEastGravity:
   case EastGravity:
-    x = _client->area().x() - _size.left - _size.right + 2;
+    x -= _size.left + _size.right;
     break;
 
   case ForgetGravity:
   case StaticGravity:
-    x = _client->area().x() - _size.left;
+    x -= _size.left;
     break;
   }
 
-  // apply vertical window gravity
+  // vertical
   switch (_client->gravity()) {
   default:
   case NorthWestGravity:
   case NorthEastGravity:
   case NorthGravity:
-    y = _client->area().y();
     break;
 
   case CenterGravity:
   case EastGravity:
   case WestGravity:
-    y = _client->area().y() - (_size.top + _size.bottom) / 2;
+    y -= (_size.top + _size.bottom) / 2;
     break;
 
   case SouthWestGravity:
   case SouthEastGravity:
   case SouthGravity:
-    y = _client->area().y() - _size.top - _size.bottom + 2;
+    y -= _size.top + _size.bottom;
     break;
 
   case ForgetGravity:
   case StaticGravity:
-    y = _client->area().y() - _size.top;
+    y -= _size.top;
     break;
   }
-  move(x, y);
 }
 
 
-void OBFrame::reverseGravity()
+void OBFrame::frameGravity(int &x, int &y)
 {
-  move(_client->area().x() - _size.left, _client->area().y() - _size.top);
+  x = getRect().x();
+  y = getRect().y();
+  
+  // horizontal
+  switch (_client->gravity()) {
+  default:
+  case NorthWestGravity:
+  case WestGravity:
+  case SouthWestGravity:
+    break;
+  case NorthGravity:
+  case CenterGravity:
+  case SouthGravity:
+    x += (_size.left + _size.right) / 2;
+    break;
+  case NorthEastGravity:
+  case EastGravity:
+  case SouthEastGravity:
+    x += _size.left + _size.right;
+    break;
+  case StaticGravity:
+  case ForgetGravity:
+    x += _size.left;
+    break;
+  }
+
+  // vertical
+  switch (_client->gravity()) {
+  default:
+  case NorthWestGravity:
+  case WestGravity:
+  case SouthWestGravity:
+    break;
+  case NorthGravity:
+  case CenterGravity:
+  case SouthGravity:
+    y += (_size.top + _size.bottom) / 2;
+    break;
+  case NorthEastGravity:
+  case EastGravity:
+  case SouthEastGravity:
+    y += _size.top + _size.bottom;
+    break;
+  case StaticGravity:
+  case ForgetGravity:
+    y += _size.top;
+    break;
+  }
 }
 
 
index 1816ad011ef17f39b30ebe6fc66100dd2977c073..7248c71fdb268831c99da864f3f30cf569c2d014 100644 (file)
@@ -75,6 +75,9 @@ private:
   */
   void releaseClient(bool remap);
 
+  //! Shape the frame window to the client window
+  void adjustShape();
+
 public:
   //! Constructs an OBFrame object, and reparents the client to itself
   /*!
@@ -88,18 +91,25 @@ public:
   //! Set the style to decorate the frame with
   virtual void setStyle(otk::Style *style);
 
-  //! Update the frame to match the client
-  void adjust();
-  //! Shape the frame window to the client window
-  void adjustShape();
+  //! Update the frame's size to match the client
+  void adjustSize();
+  //! Update the frame's position to match the client
+  void adjustPosition();
 
-  //! Applies gravity for the client's gravity, moving the frame to the
-  //! appropriate place
-  void applyGravity();
+  //! Applies gravity to the client's position to find where the frame should
+  //! be positioned.
+  /*!
+    @return The proper coordinates for the frame, based on the client.
+  */
+  void clientGravity(int &x, int &y);
+
+  //! Reversly applies gravity to the frame's position to find where the client
+  //! should be positioned.
+  /*!
+    @return The proper coordinates for the client, based on the frame.
+  */
+  void frameGravity(int &x, int &y);
 
-  //! Reversely applies gravity for the client's gravity, moving the frame so
-  //! that the client is in its pre-gravity position
-  void reverseGravity();
 };
 
 }
index 23361761c3f6674d347b24e32c23c0493308bf56..3fccc44a12418f5a3b3b2ef630fc4f758eee2522 100644 (file)
@@ -108,25 +108,4 @@ void OBRootWindow::mapRequestHandler(const XMapRequestEvent &e)
   }
 }
 
-
-void OBRootWindow::configureRequestHandler(const XConfigureRequestEvent &e)
-{
-  OtkEventHandler::configureRequestHandler(e);
-
-  // when configure requests come to the root window, just pass them on
-  XWindowChanges xwc;
-
-  xwc.x = e.x;
-  xwc.y = e.y;
-  xwc.width = e.width;
-  xwc.height = e.height;
-  xwc.border_width = e.border_width;
-  xwc.sibling = e.above;
-  xwc.stack_mode = e.detail;
-
-  XConfigureWindow(otk::OBDisplay::display, e.window,
-                   e.value_mask, &xwc);
-}
-
-
 }
index 35cda699cae79de10e9b80d1748e0fcfe08bfc80..d78f4ff7e069e18933ea739c06f78cffaa43c99d 100644 (file)
@@ -62,7 +62,6 @@ public:
   virtual void propertyHandler(const XPropertyEvent &e);
   virtual void clientMessageHandler(const XClientMessageEvent &e);
   virtual void mapRequestHandler(const XMapRequestEvent &);
-  virtual void configureRequestHandler(const XConfigureRequestEvent &e);
 };
 
 }
index 22d5d1be43567f610c9ec08a546f0eaf38df70f3..d40a2a3a537a0ec86f9227953e35d3a19252ef00 100644 (file)
@@ -354,7 +354,7 @@ void OBScreen::manageWindow(Window window)
   Openbox::instance->registerHandler(window, client);
 
   // we dont want a border on the client
-  XSetWindowBorderWidth(otk::OBDisplay::display, window, 0);
+  client->toggleClientBorder(false);
   
   // specify that if we exit, the window should not be destroyed and should be
   // reparented back to root automatically
@@ -399,10 +399,9 @@ void OBScreen::unmanageWindow(OBClient *client)
   XSelectInput(otk::OBDisplay::display, client->window(), NoEventMask);
 
   frame->hide();
-  
-  // we dont want a border on the client
-  XSetWindowBorderWidth(otk::OBDisplay::display, client->window(),
-                        client->borderWidth());
+
+  // give the client its border back
+  client->toggleClientBorder(true);
 
   delete client->frame;
   client->frame = 0;
This page took 0.037572 seconds and 4 git commands to generate.