From f1c5cef83af91631dec217ccca26099390dbeb5d Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <fourdan.olivier@wanadoo.fr>
Date: Tue, 21 Nov 2006 20:47:48 +0000
Subject: [PATCH] Be more permissive with resizes towards struts (Bug #2597,
 bis), optimize shape use.

(Old svn revision: 23925)
---
 src/client.c    | 25 +++++++++------------
 src/frame.c     | 42 +++++++++++++++++++---------------
 src/placement.c | 60 ++++++++++++++++++++++++-------------------------
 3 files changed, 64 insertions(+), 63 deletions(-)

diff --git a/src/client.c b/src/client.c
index b296c49af..a1fdff643 100644
--- a/src/client.c
+++ b/src/client.c
@@ -740,11 +740,11 @@ clientConfigure (Client * c, XWindowChanges * wc, unsigned long mask, unsigned s
         }
     }
 
-    clientConfigureWindows (c, wc, mask, flags);
     if (resized || (flags & CFG_FORCE_REDRAW))
     {
         frameDraw (c, (flags & CFG_FORCE_REDRAW));
     }
+    clientConfigureWindows (c, wc, mask, flags);
 
     if ((flags & CFG_NOTIFY) ||
         ((flags & CFG_REQUEST) && !(moved || resized)) ||
@@ -4272,31 +4272,26 @@ clientResizeEventFilter (XEvent * xevent, gpointer data)
             c->x = c->x - (c->width - passdata->oldw);
             frame_x = frameX (c);
         }
-#if 0
-        if (move_top && !clientCkeckTitle (c))
+        if (move_top)
         {
-            c->x = prev_x;
-            c->width = prev_width;
+            if (!clientCkeckTitle (c) && (frame_y < screen_info->margins [STRUTS_TOP]))
+            {
+                c->x = prev_x;
+                c->width = prev_width;
+            }
         }
-#endif
+
         clientSetHeight (c, c->height);
         if (!FLAG_TEST (c->flags, CLIENT_FLAG_SHADED) && move_top)
         {
             c->y = c->y - (c->height - passdata->oldh);
             frame_y = frameY (c);
         }
-#if 0
-        if (move_top && !clientCkeckTitle (c))
-        {
-            c->y = prev_y;
-            c->height = prev_height;
-        }
-#endif
         if (move_top)
         {
             if ((c->y > disp_max_y - min_visible)
-                || (c->y > screen_info->height
-                           - screen_info->margins [STRUTS_BOTTOM] - min_visible))
+                || (c->y > screen_info->height - screen_info->margins [STRUTS_BOTTOM] - min_visible)
+                || (!clientCkeckTitle (c) && (frame_y < screen_info->margins [STRUTS_TOP])))
             {
                 c->y = prev_y;
                 c->height = prev_height;
diff --git a/src/frame.c b/src/frame.c
index 845182ade..99a9d87a1 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -585,7 +585,7 @@ frameSetShape (Client * c, int state, FramePixmap * frame_pix, int button_x[BUTT
 {
     ScreenInfo *screen_info;
     DisplayInfo *display_info;
-    Window temp;
+    Window shape_win;
     XRectangle rect;
     xfwmPixmap *my_pixmap;
     int i;
@@ -601,7 +601,7 @@ frameSetShape (Client * c, int state, FramePixmap * frame_pix, int button_x[BUTT
         return;
     }
 
-    temp = XCreateSimpleWindow (display_info->dpy, c->frame, 0, 0, frameWidth (c), frameHeight (c), 0, 0, 0);
+    shape_win = XCreateSimpleWindow (display_info->dpy, c->frame, 0, 0, frameWidth (c), frameHeight (c), 0, 0, 0);
 
     if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
     {
@@ -609,12 +609,19 @@ frameSetShape (Client * c, int state, FramePixmap * frame_pix, int button_x[BUTT
         rect.y = 0;
         rect.width  = frameWidth (c);
         rect.height = frameHeight (c);
-        XShapeCombineRectangles (display_info->dpy, temp, ShapeBounding, 0, 0, &rect, 1,
-                                 ShapeSubtract, 0);
+        XShapeCombineRectangles (display_info->dpy, shape_win, ShapeBounding, 0, 0, &rect, 1, ShapeSubtract, Unsorted);
+    }
+    else if (!FLAG_TEST (c->flags, CLIENT_FLAG_HAS_SHAPE))
+    {
+        rect.x = frameLeft (c);
+        rect.y = frameTop (c);
+        rect.width  = c->width;
+        rect.height = c->height;
+        XShapeCombineRectangles (display_info->dpy, shape_win, ShapeBounding, 0, 0, &rect, 1, ShapeSet, Unsorted);
     }
     else
     {
-        XShapeCombineShape (display_info->dpy, temp, ShapeBounding, frameLeft (c),
+        XShapeCombineShape (display_info->dpy, shape_win, ShapeBounding, frameLeft (c),
                             frameTop (c), c->window, ShapeBounding, ShapeSet);
     }
     if (frame_pix)
@@ -728,20 +735,20 @@ frameSetShape (Client * c, int state, FramePixmap * frame_pix, int button_x[BUTT
         {
             if (xfwmWindowVisible (&c->sides[SIDE_LEFT]))
             {
-                XShapeCombineShape (display_info->dpy, temp, ShapeBounding, 0, frameTop (c),
+                XShapeCombineShape (display_info->dpy, shape_win, ShapeBounding, 0, frameTop (c),
                                     MYWINDOW_XWINDOW (c->sides[SIDE_LEFT]), ShapeBounding, ShapeUnion);
             }
 
             if (xfwmWindowVisible (&c->sides[SIDE_RIGHT]))
             {
-                XShapeCombineShape (display_info->dpy, temp, ShapeBounding, frameWidth (c) - frameRight (c), frameTop (c),
+                XShapeCombineShape (display_info->dpy, shape_win, ShapeBounding, frameWidth (c) - frameRight (c), frameTop (c),
                                     MYWINDOW_XWINDOW (c->sides[SIDE_RIGHT]), ShapeBounding, ShapeUnion);
             }
         }
 
         if (xfwmWindowVisible (&c->title))
         {
-            XShapeCombineShape (display_info->dpy, temp, ShapeBounding,
+            XShapeCombineShape (display_info->dpy, shape_win, ShapeBounding,
                                 frameTopLeftWidth (c, state), 0,
                                 MYWINDOW_XWINDOW (c->title), ShapeBounding, ShapeUnion);
         }
@@ -749,13 +756,13 @@ frameSetShape (Client * c, int state, FramePixmap * frame_pix, int button_x[BUTT
         if (xfwmWindowVisible (&c->corners[CORNER_TOP_LEFT]))
         {
 
-            XShapeCombineShape (display_info->dpy, temp, ShapeBounding, 0, 0,
+            XShapeCombineShape (display_info->dpy, shape_win, ShapeBounding, 0, 0,
                                 MYWINDOW_XWINDOW (c->corners[CORNER_TOP_LEFT]), ShapeBounding, ShapeUnion);
         }
 
         if (xfwmWindowVisible (&c->sides[SIDE_BOTTOM]))
         {
-            XShapeCombineShape (display_info->dpy, temp, ShapeBounding,
+            XShapeCombineShape (display_info->dpy, shape_win, ShapeBounding,
                                 screen_info->corners[CORNER_BOTTOM_LEFT][state].width,
                                 frameHeight (c) - frameBottom (c),
                                 MYWINDOW_XWINDOW (c->sides[SIDE_BOTTOM]), ShapeBounding, ShapeUnion);
@@ -763,14 +770,14 @@ frameSetShape (Client * c, int state, FramePixmap * frame_pix, int button_x[BUTT
 
         if (xfwmWindowVisible (&c->corners[CORNER_BOTTOM_LEFT]))
         {
-            XShapeCombineShape (display_info->dpy, temp, ShapeBounding, 0,
+            XShapeCombineShape (display_info->dpy, shape_win, ShapeBounding, 0,
                                 frameHeight (c) - screen_info->corners[CORNER_BOTTOM_LEFT][state].height,
                                 MYWINDOW_XWINDOW (c->corners[CORNER_BOTTOM_LEFT]), ShapeBounding, ShapeUnion);
         }
 
         if (xfwmWindowVisible (&c->corners[CORNER_BOTTOM_RIGHT]))
         {
-            XShapeCombineShape (display_info->dpy, temp, ShapeBounding,
+            XShapeCombineShape (display_info->dpy, shape_win, ShapeBounding,
                                 frameWidth (c) - screen_info->corners[CORNER_BOTTOM_RIGHT][state].width,
                                 frameHeight (c) - screen_info->corners[CORNER_BOTTOM_RIGHT][state].height,
                                 MYWINDOW_XWINDOW (c->corners[CORNER_BOTTOM_RIGHT]), ShapeBounding, ShapeUnion);
@@ -778,7 +785,7 @@ frameSetShape (Client * c, int state, FramePixmap * frame_pix, int button_x[BUTT
 
         if (xfwmWindowVisible (&c->corners[CORNER_TOP_RIGHT]))
         {
-            XShapeCombineShape (display_info->dpy, temp, ShapeBounding,
+            XShapeCombineShape (display_info->dpy, shape_win, ShapeBounding,
                                 frameWidth (c) - frameTopRightWidth (c, state),
                                 0, MYWINDOW_XWINDOW (c->corners[CORNER_TOP_RIGHT]), ShapeBounding, ShapeUnion);
         }
@@ -787,21 +794,20 @@ frameSetShape (Client * c, int state, FramePixmap * frame_pix, int button_x[BUTT
         {
             if (xfwmWindowVisible (&c->buttons[i]))
             {
-                XShapeCombineShape (display_info->dpy, temp, ShapeBounding, button_x[i],
+                XShapeCombineShape (display_info->dpy, shape_win, ShapeBounding, button_x[i],
                                     (frameTop (c) - screen_info->buttons[i][state].height + 1) / 2,
                                     MYWINDOW_XWINDOW (c->buttons[i]), ShapeBounding, ShapeUnion);
             }
         }
     }
-
     rect.x = 0;
     rect.y = 0;
     rect.width  = frameWidth (c);
     rect.height = frameHeight (c);
-    XShapeCombineRectangles (display_info->dpy, temp, ShapeBounding, 0, 0, &rect, 1, ShapeIntersect, 0);
-    XShapeCombineShape (display_info->dpy, c->frame, ShapeBounding, 0, 0, temp, ShapeBounding, ShapeSet);
+    XShapeCombineRectangles (display_info->dpy, shape_win, ShapeBounding, 0, 0, &rect, 1, ShapeIntersect, Unsorted);
+    XShapeCombineShape (display_info->dpy, c->frame, ShapeBounding, 0, 0, shape_win, ShapeBounding, ShapeSet);
 
-    XDestroyWindow (display_info->dpy, temp);
+    XDestroyWindow (display_info->dpy, shape_win);
 }
 
 void
diff --git a/src/placement.c b/src/placement.c
index b776bf471..76fcb981f 100644
--- a/src/placement.c
+++ b/src/placement.c
@@ -41,35 +41,6 @@ static unsigned long overlapY (int y0, int y1, int ty0, int ty1);
 static unsigned long overlap (int x0, int y0, int x1, int y1,
                               int tx0, int ty0, int tx1, int ty1);
 
-static unsigned long
-clientStrutAreaOverlap (int x, int y, int w, int h, Client * c)
-{
-    unsigned long sigma = 0;
-
-    if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_STRUT)
-        && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
-    {
-        sigma = overlap (x, y, x + w, y + h,
-                         0, c->struts[STRUTS_LEFT_START_Y],
-                         c->struts[STRUTS_LEFT],
-                         c->struts[STRUTS_LEFT_END_Y])
-              + overlap (x, y, x + w, y + h,
-                         c->screen_info->width - c->struts[STRUTS_RIGHT],
-                         c->struts[STRUTS_RIGHT_START_Y],
-                         c->screen_info->width, c->struts[STRUTS_RIGHT_END_Y])
-              + overlap (x, y, x + w, y + h,
-                         c->struts[STRUTS_TOP_START_X], 0,
-                         c->struts[STRUTS_TOP_END_X],
-                         c->struts[STRUTS_TOP])
-              + overlap (x, y, x + w, y + h,
-                         c->struts[STRUTS_BOTTOM_START_X],
-                         c->screen_info->height - c->struts[STRUTS_BOTTOM],
-                         c->struts[STRUTS_BOTTOM_END_X],
-                         c->screen_info->height);
-    }
-    return sigma;
-}
-
 /* Compute rectangle overlap area */
 
 static unsigned long
@@ -115,6 +86,35 @@ overlap (int x0, int y0, int x1, int y1, int tx0, int ty0, int tx1, int ty1)
     return (overlapX (x0, x1, tx0, tx1) * overlapY (y0, y1, ty0, ty1));
 }
 
+static unsigned long
+clientStrutAreaOverlap (int x, int y, int w, int h, Client * c)
+{
+    unsigned long sigma = 0;
+
+    if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_STRUT)
+        && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
+    {
+        sigma = overlap (x, y, x + w, y + h,
+                         0, c->struts[STRUTS_LEFT_START_Y],
+                         c->struts[STRUTS_LEFT],
+                         c->struts[STRUTS_LEFT_END_Y])
+              + overlap (x, y, x + w, y + h,
+                         c->screen_info->width - c->struts[STRUTS_RIGHT],
+                         c->struts[STRUTS_RIGHT_START_Y],
+                         c->screen_info->width, c->struts[STRUTS_RIGHT_END_Y])
+              + overlap (x, y, x + w, y + h,
+                         c->struts[STRUTS_TOP_START_X], 0,
+                         c->struts[STRUTS_TOP_END_X],
+                         c->struts[STRUTS_TOP])
+              + overlap (x, y, x + w, y + h,
+                         c->struts[STRUTS_BOTTOM_START_X],
+                         c->screen_info->height - c->struts[STRUTS_BOTTOM],
+                         c->struts[STRUTS_BOTTOM_END_X],
+                         c->screen_info->height);
+    }
+    return sigma;
+}
+
 void
 clientMaxSpace (ScreenInfo *screen_info, int *x, int *y, int *w, int *h)
 {
@@ -193,7 +193,7 @@ clientCkeckTitle (Client * c)
     screen_info = c->screen_info;
     for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++)
     {
-        if ((c2 != c) && clientStrutAreaOverlap(frame_x, frame_y, frame_width, frame_top, c2))
+        if ((c2 != c) && clientStrutAreaOverlap (frame_x, frame_y, frame_width, frame_top, c2))
         {
             return FALSE;
         }
-- 
GitLab