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;