]> Dogcows Code - chaz/openbox/blobdiff - openbox/frame.c
fix window gravity when there is a border width
[chaz/openbox] / openbox / frame.c
index 96e93ba0ad1612128bd7e8346b1cf396d97d5bf6..b6b6ac9322a9e4d4a1b057136448c65e04238e3f 100644 (file)
@@ -353,6 +353,11 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
         } else
             self->width = self->client->area.width + self->cbwidth_x * 2;
 
+        /* some elements are sized based of the width, so don't let them have
+           negative values */
+        self->width = MAX(self->width,
+                          (ob_rr_theme->grip_width + self->bwidth) * 2 + 1);
+
         STRUT_SET(self->size,
                   self->cbwidth_x + (!self->max_horz ? self->bwidth : 0),
                   self->cbwidth_y + self->bwidth,
@@ -371,6 +376,13 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
 
         if (!fake) {
             if (self->bwidth) {
+                gint titlesides;
+
+                /* height of titleleft and titleright */
+                titlesides = (!self->max_horz ?
+                              ob_rr_theme->grip_width :
+                              self->size.top - self->bwidth);
+
                 XMoveResizeWindow(ob_display, self->titletop,
                                   ob_rr_theme->grip_width + self->bwidth, 0,
                                   /* width + bwidth*2 - bwidth*2 - grips*2 */
@@ -388,27 +400,29 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
                                   ob_rr_theme->grip_width + self->bwidth,
                                   self->bwidth);
 
-                XMoveResizeWindow(ob_display, self->titleleft,
-                                  0, self->bwidth,
-                                  self->bwidth,
-                                  (!self->max_horz ?
-                                   ob_rr_theme->grip_width :
-                                   self->size.top - self->bwidth));
-                XMoveResizeWindow(ob_display, self->titleright,
-                                  self->client->area.width +
-                                  self->size.left + self->size.right -
-                                  self->bwidth,
-                                  self->bwidth,
-                                  self->bwidth,
-                                  (!self->max_horz ?
-                                   ob_rr_theme->grip_width :
-                                   self->size.top - self->bwidth));
+                if (titlesides > 0) {
+                    XMoveResizeWindow(ob_display, self->titleleft,
+                                      0, self->bwidth,
+                                      self->bwidth,
+                                      titlesides);
+                    XMoveResizeWindow(ob_display, self->titleright,
+                                      self->client->area.width +
+                                      self->size.left + self->size.right -
+                                      self->bwidth,
+                                      self->bwidth,
+                                      self->bwidth,
+                                      titlesides);
+
+                    XMapWindow(ob_display, self->titleleft);
+                    XMapWindow(ob_display, self->titleright);
+                } else {
+                    XUnmapWindow(ob_display, self->titleleft);
+                    XUnmapWindow(ob_display, self->titleright);
+                }
 
                 XMapWindow(ob_display, self->titletop);
                 XMapWindow(ob_display, self->titletopleft);
                 XMapWindow(ob_display, self->titletopright);
-                XMapWindow(ob_display, self->titleleft);
-                XMapWindow(ob_display, self->titleright);
 
                 if (self->decorations & OB_FRAME_DECOR_TITLEBAR &&
                     self->rbwidth)
@@ -441,19 +455,17 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
 
                 if (self->decorations & OB_FRAME_DECOR_GRIPS) {
                     XMoveResizeWindow(ob_display, self->topresize,
-                                      ob_rr_theme->grip_width + self->bwidth,
+                                      ob_rr_theme->grip_width,
                                       0,
                                       self->width - ob_rr_theme->grip_width *2,
                                       ob_rr_theme->paddingy + 1);
 
-                    XMoveWindow(ob_display, self->tltresize, self->bwidth, 0);
-                    XMoveWindow(ob_display, self->tllresize, self->bwidth, 0);
+                    XMoveWindow(ob_display, self->tltresize, 0, 0);
+                    XMoveWindow(ob_display, self->tllresize, 0, 0);
                     XMoveWindow(ob_display, self->trtresize,
-                                self->bwidth + self->width -
-                                ob_rr_theme->grip_width, 0);
+                                self->width - ob_rr_theme->grip_width, 0);
                     XMoveWindow(ob_display, self->trrresize,
-                                self->bwidth + self->width -
-                                ob_rr_theme->paddingx - 1, 0);
+                                self->width - ob_rr_theme->paddingx - 1, 0);
 
                     XMapWindow(ob_display, self->topresize);
                     XMapWindow(ob_display, self->tltresize);
@@ -683,7 +695,9 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
                         self->cbwidth_y);
 
             /* when the client has StaticGravity, it likes to move around. */
-            XMoveWindow(ob_display, self->client->window, 0, 0);
+            XMoveWindow(ob_display, self->client->window,
+                        -self->client->border_width,
+                        -self->client->border_width);
         }
     }
 
@@ -696,7 +710,7 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
                    self->client->area.height +
                    self->size.top + self->size.bottom));
 
-    if (moved || resized) {
+    if ((moved || resized) && !fake) {
         /* find the new coordinates, done after setting the frame.size, for
            frame_client_gravity. */
         self->area.x = self->client->area.x;
@@ -745,22 +759,31 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
     if (resized && (self->decorations & OB_FRAME_DECOR_TITLEBAR))
         XResizeWindow(ob_display, self->label, self->label_width,
                       ob_rr_theme->label_height);
+
 }
 
 static void frame_adjust_cursors(ObFrame *self)
 {
     if ((self->functions & OB_CLIENT_FUNC_RESIZE) !=
         (self->client->functions & OB_CLIENT_FUNC_RESIZE) ||
-        ((self->max_horz && self->max_vert) !=
-         (self->client->max_horz && self->client->max_vert)))
+        self->max_horz != self->client->max_horz ||
+        self->max_vert != self->client->max_vert)
     {
         gboolean r = (self->client->functions & OB_CLIENT_FUNC_RESIZE) &&
             !(self->client->max_horz && self->client->max_vert);
+        gboolean topbot = !self->client->max_vert;
         XSetWindowAttributes a;
 
-        a.cursor = ob_cursor(r ? OB_CURSOR_NORTH : OB_CURSOR_NONE);
+        /* these ones turn off when max vert */
+        a.cursor = ob_cursor(r && topbot ? OB_CURSOR_NORTH : OB_CURSOR_NONE);
         XChangeWindowAttributes(ob_display, self->topresize, CWCursor, &a);
         XChangeWindowAttributes(ob_display, self->titletop, CWCursor, &a);
+        a.cursor = ob_cursor(r && topbot ? OB_CURSOR_SOUTH : OB_CURSOR_NONE);
+        XChangeWindowAttributes(ob_display, self->handle, CWCursor, &a);
+        XChangeWindowAttributes(ob_display, self->handletop, CWCursor, &a);
+        XChangeWindowAttributes(ob_display, self->handlebottom, CWCursor, &a);
+
+        /* these ones don't */
         a.cursor = ob_cursor(r ? OB_CURSOR_NORTHWEST : OB_CURSOR_NONE);
         XChangeWindowAttributes(ob_display, self->tltresize, CWCursor, &a);
         XChangeWindowAttributes(ob_display, self->tllresize, CWCursor, &a);
@@ -775,10 +798,6 @@ static void frame_adjust_cursors(ObFrame *self)
         XChangeWindowAttributes(ob_display, self->left, CWCursor, &a);
         a.cursor = ob_cursor(r ? OB_CURSOR_EAST : OB_CURSOR_NONE);
         XChangeWindowAttributes(ob_display, self->right, CWCursor, &a);
-        a.cursor = ob_cursor(r ? OB_CURSOR_SOUTH : OB_CURSOR_NONE);
-        XChangeWindowAttributes(ob_display, self->handle, CWCursor, &a);
-        XChangeWindowAttributes(ob_display, self->handletop, CWCursor, &a);
-        XChangeWindowAttributes(ob_display, self->handlebottom, CWCursor, &a);
         a.cursor = ob_cursor(r ? OB_CURSOR_SOUTHWEST : OB_CURSOR_NONE);
         XChangeWindowAttributes(ob_display, self->lgrip, CWCursor, &a);
         XChangeWindowAttributes(ob_display, self->handleleft, CWCursor, &a);
@@ -825,8 +844,14 @@ void frame_adjust_icon(ObFrame *self)
 
 void frame_grab_client(ObFrame *self)
 {
+    /* DO NOT map the client window here. we used to do that, but it is bogus.
+       we need to set up the client's dimensions and everything before we
+       send a mapnotify or we create race conditions.
+    */
+
     /* reparent the client to the frame */
-    XReparentWindow(ob_display, self->client->window, self->plate, 0, 0);
+    XReparentWindow(ob_display, self->client->window, self->plate,
+                    -self->client->border_width, -self->client->border_width);
 
     /*
       When reparenting the client window, it is usually not mapped yet, since
@@ -843,9 +868,6 @@ void frame_grab_client(ObFrame *self)
        req's) the ButtonPress is to catch clicks on the client border */
     XSelectInput(ob_display, self->plate, PLATE_EVENTMASK);
 
-    /* map the client so it maps when the frame does */
-    XMapWindow(ob_display, self->client->window);
-
     /* set all the windows for the frame in the window_map */
     g_hash_table_insert(window_map, &self->window, self->client);
     g_hash_table_insert(window_map, &self->plate, self->client);
@@ -1207,7 +1229,7 @@ ObFrameContext frame_context(ObClient *client, Window win, gint x, gint y)
        is fully maximized, then treat it like they clicked in the
        button that is there */
     if (self->max_horz && self->max_vert &&
-        (win == self->title ||
+        (win == self->title || win == self->titletop ||
          win == self->titleleft || win == self->titletopleft ||
          win == self->titleright || win == self->titletopright))
     {
@@ -1223,6 +1245,9 @@ ObFrameContext frame_context(ObClient *client, Window win, gint x, gint y)
         /* title is a border width in from the edge */
         if (win == self->title)
             fx += self->bwidth;
+        /* titletop is a bit to the right */
+        else if (win == self->titletop)
+            fx += ob_rr_theme->grip_width + self->bwidth;
         /* titletopright is way to the right edge */
         else if (win == self->titletopright)
             fx += self->area.width - (ob_rr_theme->grip_width + self->bwidth);
@@ -1254,6 +1279,10 @@ ObFrameContext frame_context(ObClient *client, Window win, gint x, gint y)
            context */
         return OB_FRAME_CONTEXT_TITLEBAR;
     }
+    else if (self->max_vert &&
+             (win == self->titletop || win == self->topresize))
+        /* can't resize vertically when max vert */
+        return OB_FRAME_CONTEXT_TITLEBAR;
 
     if (win == self->window)            return OB_FRAME_CONTEXT_FRAME;
     if (win == self->label)             return OB_FRAME_CONTEXT_TITLEBAR;
@@ -1306,18 +1335,21 @@ void frame_client_gravity(ObFrame *self, gint *x, gint *y, gint w, gint h)
     case NorthGravity:
     case SouthGravity:
     case CenterGravity:
-        *x -= (self->size.left + w) / 2;
+        /* the middle of the client will be the middle of the frame */
+        *x -= (self->size.right - self->size.left) / 2;
         break;
 
     case NorthEastGravity:
     case SouthEastGravity:
     case EastGravity:
-        *x -= (self->size.left + self->size.right + w) - 1;
+        /* the right side of the client will be the right side of the frame */
+        *x -= self->size.right + self->size.left - self->client->border_width*2;
         break;
 
     case ForgetGravity:
     case StaticGravity:
-        *x -= self->size.left;
+        /* the client's position won't move */
+        *x -= self->size.left - self->client->border_width;
         break;
     }
 
@@ -1332,18 +1364,21 @@ void frame_client_gravity(ObFrame *self, gint *x, gint *y, gint w, gint h)
     case CenterGravity:
     case EastGravity:
     case WestGravity:
-        *y -= (self->size.top + h) / 2;
+        /* the middle of the client will be the middle of the frame */
+        *y -= (self->size.bottom - self->size.top) / 2;
         break;
 
     case SouthWestGravity:
     case SouthEastGravity:
     case SouthGravity:
-        *y -= (self->size.top + self->size.bottom + h) - 1;
+        /* the bottom of the client will be the bottom of the frame */
+        *y -= self->size.bottom + self->size.top - self->client->border_width*2;
         break;
 
     case ForgetGravity:
     case StaticGravity:
-        *y -= self->size.top;
+        /* the client's position won't move */
+        *y -= self->size.top - self->client->border_width;
         break;
     }
 }
@@ -1360,16 +1395,19 @@ void frame_frame_gravity(ObFrame *self, gint *x, gint *y, gint w, gint h)
     case NorthGravity:
     case CenterGravity:
     case SouthGravity:
-        *x += (self->size.left + w) / 2;
+        /* the middle of the client will be the middle of the frame */
+        *x += (self->size.right - self->size.left) / 2;
         break;
     case NorthEastGravity:
     case EastGravity:
     case SouthEastGravity:
-        *x += (self->size.left + self->size.right + w) - 1;
+        /* the right side of the client will be the right side of the frame */
+        *x += self->size.right + self->size.left - self->client->border_width*2;
         break;
     case StaticGravity:
     case ForgetGravity:
-        *x += self->size.left;
+        /* the client's position won't move */
+        *x += self->size.left - self->client->border_width;
         break;
     }
 
@@ -1383,16 +1421,19 @@ void frame_frame_gravity(ObFrame *self, gint *x, gint *y, gint w, gint h)
     case WestGravity:
     case CenterGravity:
     case EastGravity:
-        *y += (self->size.top + h) / 2;
+        /* the middle of the client will be the middle of the frame */
+        *y += (self->size.bottom - self->size.top) / 2;
         break;
     case SouthWestGravity:
     case SouthGravity:
     case SouthEastGravity:
-        *y += (self->size.top + self->size.bottom + h) - 1;
+        /* the bottom of the client will be the bottom of the frame */
+        *y += self->size.bottom + self->size.top - self->client->border_width*2;
         break;
     case StaticGravity:
     case ForgetGravity:
-        *y += self->size.top;
+        /* the client's position won't move */
+        *y += self->size.top - self->client->border_width;
         break;
     }
 }
This page took 0.027993 seconds and 4 git commands to generate.