On Sun 29 Jan 2006 at 12:59:31 +0200, Nadav Har'El wrote:
> And now for a real bug in ctwm 3.7: "f.resize" has become (since ctwm 3.5)
> screwed up, when you map it to the window borders, as I like. For example,
> if you map:
> 
>       Button1 =       : frame         : f.resize
> 
> you should be able to go to the top border, click and drag it up, to make
> the window slightly taller in that direction. This used to work beautifully,
> but now it does a completely non-sensical thing: when you try to drag the
> top border, the *bottom* border is moved! Note that dragging the other
> borders (bottom, right and left) works just as it should.

I wonder if this is related to my fixes in detecting if the mouse is in
the border. I also see it, and I have AutoRelativeResize turned on. I
also see the same problem if I try to resize from the left: then the
right side gets resized.

If I turn AutoRelativeResize off the problem disappears.
AutoRelativeResize works ok though if you start resizing from inside the
window, if you have a mapping for that.

    Button3 = m4 : window|icon : f.function "resize-or-raise"

I added some print statement to the function StartResize(), and it seems
that even if it is called with from3dborder=True, it *also* has
fromtitlebar=True. That is at least confusing, and it seems to make the
logic inside more complicated. 

Ok, I think I found the problem. A case of signed integer underflow: the
top border has "negative" position, and when divided by the 1/3 size of
the window height, which is unsigned, the negative value is converted to
a large unsigned value first. The result is that ctwm thinks you are
way, way down below the windown and hence resizes the bottom border.

I also changed the TopCursor detection; if you have squeezed title bars
you should now see a proper top resize cursor when you are in the top
border outside the title bar.

Can you try the attached patch?

> Thanks in advance,
> Nadav Har'El.
-Olaf.
-- 
___ Olaf 'Rhialto' Seibert      -- You author it, and I'll reader it.
\X/ rhialto/at/xs4all.nl        -- Cetero censeo "authored" delendum esse.
# 
# patch "menus.c"
#  from [016e3ed72ca5cd55d54fce3b97fa1c5f81c3428e]
#    to [84e2770bfb9ff91d7b06805bb4c724dc78b8db15]
# 
# patch "resize.c"
#  from [4c3b16b9e5b7be9cebea454fc65d73dd60aba717]
#    to [eac387f9efc8ad7967585234f86ef5beed2000c1]
# 
# patch "util.c"
#  from [ffc14c9ce235cc633333e0c011d62918934a0f0e]
#    to [eb554f7ee3fa79eba86c64e16c17587bec1864e5]
# 
--- menus.c
+++ menus.c
@@ -2395,9 +2395,9 @@
            /*
             * see if this is being done from the titlebar
             */
-           fromtitlebar = 
+           from3dborder = (eventp->xbutton.window == tmp_win->frame);
+           fromtitlebar = !from3dborder &&
              belongs_to_twm_window (tmp_win, eventp->xbutton.window);
-           from3dborder = (eventp->xbutton.window == tmp_win->frame) ? True : 
False;
            
            /* Save pointer position so we can tell if it was moved or
               not during the resize. */
@@ -2407,15 +2407,15 @@
            StartResize (eventp, tmp_win, fromtitlebar, from3dborder);
            
            do {
-             XMaskEvent(dpy,
+               XMaskEvent(dpy,
                           ButtonPressMask | ButtonReleaseMask |
                           EnterWindowMask | LeaveWindowMask |
                           ButtonMotionMask | VisibilityChangeMask | 
ExposureMask, &Event);
                
                if (fromtitlebar && Event.type == ButtonPress) {
-                 fromtitlebar = False;
+                   fromtitlebar = False;
                    continue;
-                 }
+               }
                
                if (Event.type == MotionNotify) {
                  /* discard any extra motion events before a release */
--- resize.c
+++ resize.c
@@ -126,10 +126,25 @@
          return;
     }
 
-    h = ((x - dragx) / (dragWidth < 3 ? 1 : (dragWidth / 3)));
-    v = ((y - dragy - tmp_win->title_height) / 
-        (dragHeight < 3 ? 1 : (dragHeight / 3)));
+#ifdef DEBUG
+    printf("x=%d, y=%d ", x, y);
+    printf("title_height=%d, ",  tmp_win->title_height);
+    printf("dragx=%d, dragy=%d\n", dragx, dragy);
+    printf("    dragWidth=%d, dragHeight=%d, ", dragWidth, dragHeight);
+#endif
+    /*
+     * Determine in which of the 9 "quadrants" of the window we are.
+     * Cast the values to signed int: if the numerator is negative
+     * we don't want them converted to unsigned due to the default
+     * promotion rules: that would produce a very large quotient.
+     */
+    h = (int)(x - dragx) / (int)(dragWidth < 3 ? 1 : (dragWidth / 3));
+    v = (int)(y - dragy - tmp_win->title_height) / 
+        (int)(dragHeight < 3 ? 1 : (dragHeight / 3));
        
+#ifdef DEBUG
+    printf("h=%d, v=%d ", h, v);
+#endif
     if (h <= 0) {
        clampLeft = 1;
        clampDX = (x - dragx);
@@ -145,6 +160,10 @@
        clampBottom = 1;
        clampDY = (y - dragy - dragHeight);
     }
+#ifdef DEBUG
+    printf("clampLeft=%d, clampRight=%d, clampTop=%d, clampBottom=%d\n",
+           clampLeft,clampRight,clampTop,clampBottom);
+#endif
 }
 
 
@@ -168,6 +187,10 @@
     unsigned int junkbw, junkDepth;
     Cursor     cursor;
 
+#ifdef DEBUG
+    printf("StartResize: fromtitlebar: %d, from3dborder: %d\n",
+           fromtitlebar, from3dborder);
+#endif
     cursor = (Scr->BorderCursors && tmp_win->curcurs) ? tmp_win->curcurs : 
Scr->ResizeCursor;
     ResizeWindow = tmp_win->frame;
     if (! Scr->OpaqueResize || resizeWhenAdd) XGrabServer(dpy);
@@ -180,7 +203,7 @@
         GrabModeAsync, GrabModeAsync, grabwin, cursor, CurrentTime);
 
     XGetGeometry(dpy, (Drawable) tmp_win->frame, &junkRoot,
-        &dragx, &dragy, (unsigned int *)&dragWidth, (unsigned int 
*)&dragHeight, &junkbw,
+        &dragx, &dragy, &dragWidth, &dragHeight, &junkbw,
                  &junkDepth);
     dragx += tmp_win->frame_bw;
     dragy += tmp_win->frame_bw;
@@ -191,7 +214,7 @@
     clampTop = clampBottom = clampLeft = clampRight = clampDX = clampDY = 0;
 
     if (Scr->AutoRelativeResize && (from3dborder || !fromtitlebar))
-      do_auto_clamp (tmp_win, evp);
+       do_auto_clamp (tmp_win, evp);
 
     Scr->SizeStringOffset = SIZE_HINDENT;
     XResizeWindow (dpy, Scr->SizeWindow,
--- util.c
+++ util.c
@@ -3122,7 +3122,7 @@
        else cursor = RightCursor;
     }
     else
-    if (y < wd) {
+    if (y < h) {       /* also include title bar in top border area */
        if (x < h) cursor = TopLeftCursor;
        else
        if (x >= fw - h) cursor = TopRightCursor;

Reply via email to