Subject: Version 2 of resize patch

From: Tim Phipps <[email-masked]>
Date: Wed, 14 Oct 1998 15:26:25 +0100

Hi All,
	here's version 2 of the patch I made to resizing.  It changes
WarpToWindow so that WarpToWindow 100 100 puts the pointer right on the
edge rather than 1 pixel in (I think the fudge factors were put in to
keep the pointer inside the 3-d shadows of a border but there's an
off-by-one error and they should be IFDEF'd). I didn't notice it was
doing this until I tried to alter DoResize to start a resize if on the
edge, hopefully no one will complain.

Resize.c is also altered so that you don't need to move the pointer
outside the window to start the resizing, you have to move it onto the
edge so it won't look much different when using the mouse but it does
allow the following key bindings to work better:

DestroyFunc my_resize_dir
AddToFunc my_resize_dir "I" Echo my_resize_dir $w $0 $1
+ "I" Raise
+ "I" WarpToWindow $0 $1
+ "I" Resize
Key KP_7        WTSF    M       my_resize_dir   0   0
Key KP_8        WTSF    M       my_resize_dir  50   0
Key KP_9        WTSF    M       my_resize_dir 100   0
Key KP_6        WTSF    M       my_resize_dir 100  50
Key KP_3        WTSF    M       my_resize_dir 100 100
Key KP_2        WTSF    M       my_resize_dir  50 100
Key KP_1        WTSF    M       my_resize_dir   0 100
Key KP_4        WTSF    M       my_resize_dir   0  50

i.e. hit alt-some-number and the pointer goes to the appropriate edge
and resize starts.  You can move the pointer inwards straight off to
make a window smaller. It works very nicely with the keypad-resize patch
I posted earlier.

Other fixes:
*) The rubberband is kept outside the pointer so you don't get spurious
focus changes on completion.
*) Esc aborts and returns the pointer if the move was started from a
key-press.
*) An extra XFlush was removed

Apply to 2.0.47d.

Cheers,
Tim.

--- builtins.c.orig	Wed Oct 14 13:08:33 1998
+++ builtins.c	Wed Oct 14 13:30:15 1998
@@ -272,19 +272,19 @@
 
   if(t->flags & ICONIFIED)
   {
-    x = t->icon_xl_loc + t->icon_w_width/2 + 2;
-    y = t->icon_y_loc + t->icon_p_height + ICON_HEIGHT/2 + 2;
+    x = t->icon_xl_loc + t->icon_w_width/2;
+    y = t->icon_y_loc + t->icon_p_height + ICON_HEIGHT/2;
   }
   else
   {
     if (x_unit != Scr.MyDisplayWidth)
-      x = t->frame_x + 2 + warp_x;
+      x = t->frame_x + warp_x;
     else
-      x = t->frame_x + 2 + (t->frame_width - 4) * warp_x / 100;
+      x = t->frame_x + (t->frame_width - 1) * warp_x / 100;
     if (y_unit != Scr.MyDisplayHeight) 
-      y = t->frame_y + 2 + warp_y;
+      y = t->frame_y + warp_y;
     else
-      y = t->frame_y + 2 + (t->frame_height - 4) * warp_y / 100;
+      y = t->frame_y + (t->frame_height - 1) * warp_y / 100;
   }
   if (warp_x >= 0 && warp_y >= 0) {
     XWarpPointer(dpy, None, Scr.Root, 0, 0, 0, 0, x, y);
--- resize.c.orig	Wed Oct 14 14:29:24 1998
+++ resize.c	Wed Oct 14 14:54:33 1998
@@ -26,6 +26,8 @@
 static int dragy;       /* in resize operations */
 static int dragWidth;
 static int dragHeight;
+static int constrainx;
+static int constrainy;
 
 static int origx;
 static int origy;
@@ -46,7 +48,7 @@
 		   unsigned long context, char *action,int *Module) 
 {
   Bool finished = FALSE, done = FALSE, abort = FALSE;
-  int x,y,delta_x,delta_y;
+  int x,y,delta_x,delta_y,stashed_x,stashed_y;
   Window ResizeWindow;
   Bool flags;
   int val1, val2, val1_unit,val2_unit,n;
@@ -88,7 +90,7 @@
       dragWidth += (2*tmp_win->boundary_width);
       dragHeight += (tmp_win->title_height + 2*tmp_win->boundary_width);
  
-
+      constrainx = constrainy = 0; /* size will be less or equal to requested */
       ConstrainSize (tmp_win, &dragWidth, &dragHeight);
       SetupFrame (tmp_win, tmp_win->frame_x, 
 		  tmp_win->frame_y ,dragWidth, dragHeight,FALSE);
@@ -97,13 +99,14 @@
       return;
     }
 
+  /* Fudge factors so that interactive resize keeps the window outline always
+     outside the pointer.  If the outline is always inside the pointer and
+     there is another PointerFocus window underneath the pointer at the end of
+     the resize the focus will be changed to the window underneath - bad karma */
+  constrainx = tmp_win->hints.width_inc - 1;
+  constrainy = tmp_win->hints.height_inc - 1;
+
   InstallRootColormap();
-  if (menuFromFrameOrWindowOrTitlebar) 
-    {
-      /* warp the pointer to the cursor position from before menu appeared*/
-      /* FIXGJB: XWarpPointer(dpy, None, Scr.Root, 0, 0, 0, 0, Stashed_X,Stashed_Y); */
-      XFlush(dpy);
-    }
 
   if(!GrabEm(MOVE))
     {
@@ -172,6 +175,15 @@
   MoveOutline (Scr.Root, dragx - tmp_win->bw, dragy - tmp_win->bw, 
 	       dragWidth + 2 * tmp_win->bw,
 	       dragHeight + 2 * tmp_win->bw);
+  /* kick off resizing without requiring any motion if invoked with a key press */
+  if (eventp->type == KeyPress)
+    {
+      XQueryPointer(dpy, Scr.Root, &JunkRoot, &JunkChild,
+                    &stashed_x,&stashed_y,&JunkX, &JunkY, &JunkMask);
+      DoResize(stashed_x, stashed_y, tmp_win);  
+    }
+  else
+    stashed_x = stashed_y = -1;
 
   /* loop to resize */
   while(!finished)
@@ -205,6 +217,9 @@
 	    {
 	      abort = TRUE;
 	      finished = TRUE;
+	      /* return pointer if aborted resize was invoked with key */
+	      if (stashed_x >= 0)
+	        XWarpPointer(dpy, None, Scr.Root, 0, 0, 0, 0, stashed_x,stashed_y);
 	    }
 	  done = TRUE;
 	  break;
@@ -439,10 +454,10 @@

     /*
-     * Second, fit to base + N * inc
+     * Second, fit to base + N * inc (<= or >= depending on resize type)
      */
-    dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth;
-    dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight;
+    dwidth = ((dwidth - baseWidth + constrainx) / xinc * xinc) + baseWidth;
+    dheight = ((dheight - baseHeight + constrainy) / yinc * yinc) + baseHeight;

     /*