Title: Configurable Smooth Edge Resistance
Released for: 0.19.3
Notes: Adds edge resistance.  This is, IMHO, smoother then traditional edge
       resistance.  Regular edge resistance feels kind of like snap-to-grid,
       it's jumpy.  This instead makes it feel like you are being slowed
       down when you hit the edge.  Allows resistance to be configured with
       the EdgeResistance key (default 0=no resistance).  Config goes in
       ~/GNUstep/Defaults/WindowMaker.
Author: David Wang <dwang@cisco.com> -- Edge resistance
        Andrew Turner <daerr@mint.net> -- Modified to make movement smoother. Made it configure itself via proplist
Format: diff

diff -rc WindowMaker-0.19.3/src/WindowMaker.h WindowMaker-0.19.3-patched/src/WindowMaker.h
*** WindowMaker-0.19.3/src/WindowMaker.h	Wed Sep  9 05:40:39 1998
--- WindowMaker-0.19.3-patched/src/WindowMaker.h	Fri Sep 11 12:33:43 1998
***************
*** 199,204 ****
--- 199,206 ----
      
      char opaque_move;		       /* update window position during */
  				       /* move */
+     int edge_resistance;	       /* number of pixels of edge */
+ 				       /* resistance, 0 for none */
  
      char wrap_menus;		       /* wrap menus at edge of screen */
      char scrollable_menus;	       /* let them be scrolled */
diff -rc WindowMaker-0.19.3/src/defaults.c WindowMaker-0.19.3-patched/src/defaults.c
*** WindowMaker-0.19.3/src/defaults.c	Wed Sep  9 05:40:40 1998
--- WindowMaker-0.19.3-patched/src/defaults.c	Fri Sep 11 12:33:43 1998
***************
*** 278,283 ****
--- 278,286 ----
      {"OpaqueMove",	"NO",			NULL,
  	  &wPreferences.opaque_move,	getBool,	NULL
      },
+     {"EdgeResistance",	"0",			NULL,
+     	  &wPreferences.edge_resistance,	getInt,		NULL
+     },
      {"DisableSound",	"NO",			NULL,
  	  &wPreferences.no_sound,	getBool,	NULL
      },
diff -rc WindowMaker-0.19.3/src/moveres.c WindowMaker-0.19.3-patched/src/moveres.c
*** WindowMaker-0.19.3/src/moveres.c	Wed Sep  9 05:47:54 1998
--- WindowMaker-0.19.3-patched/src/moveres.c	Fri Sep 11 16:09:41 1998
***************
*** 387,403 ****
  #define unmapGeometryDisplay(w) \
  XUnmapWindow(dpy, (w)->screen_ptr->geometry_display);
  
  
  static void
! doWindowMove(WWindow *wwin, LinkedList *list, int dx, int dy)
  {
      WWindow *tmpw;
      int x, y;
      int scr_width = wwin->screen_ptr->scr_width;
      int scr_height = wwin->screen_ptr->scr_height;
!     
      if (!list) {
! 	wWindowMove(wwin, wwin->frame_x + dx, wwin->frame_y + dy);
      } else {
  	while (list) {
  	    tmpw = list->head;
--- 387,455 ----
  #define unmapGeometryDisplay(w) \
  XUnmapWindow(dpy, (w)->screen_ptr->geometry_display);
  
+ static void
+ checkEdgeResistance(WWindow *wwin, int *winx, int *winy, int off_x, int off_y)
+ {
+     int scr_width = wwin->screen_ptr->scr_width;
+     int scr_height = wwin->screen_ptr->scr_height;
+     int x = *winx;
+     int y = *winy;
+     int edge_resistance = wPreferences.edge_resistance;
+ 
+     x -= off_x;
+     y -= off_y;
+ 
+     if ((x + wwin->frame->core->width) >= (scr_width - 2)) {
+       if ((x + wwin->frame->core->width) < ((scr_width - 2) 
+           + edge_resistance)) {
+         x = scr_width - wwin->frame->core->width - 2;
+       } else {
+         x -= edge_resistance;
+       }
+     }
+ 
+     if (x <= 0) {
+       if (x > -edge_resistance) {
+         x = 0;
+       } else {
+         x += edge_resistance;
+       }
+     }
+ 
+     if ((y + wwin->frame->core->height) >= (scr_height - 1)) {
+       if ((y + wwin->frame->core->height) < ((scr_height - 1)
+           + edge_resistance)) {
+         y = scr_height - wwin->frame->core->height - 1;
+       } else {
+         y -= edge_resistance;
+       }
+     }
+ 
+     if (y <=0) {
+       if (y > -edge_resistance) {
+         y = 0;
+       } else {
+         y += edge_resistance;
+       }
+     }
+ 
+ 
+     *winx = x;
+     *winy = y;
+ }
  
  static void
! doWindowMove(WWindow *wwin, int single_win_x, int single_win_y,
!              LinkedList *list, int dx, int dy, int off_x, int off_y)
  {
      WWindow *tmpw;
      int x, y;
      int scr_width = wwin->screen_ptr->scr_width;
      int scr_height = wwin->screen_ptr->scr_height;
! 
      if (!list) {
!         checkEdgeResistance(wwin, &single_win_x, &single_win_y, off_x, off_y);
!         wWindowMove(wwin, single_win_x, single_win_y);
      } else {
  	while (list) {
  	    tmpw = list->head;
***************
*** 454,460 ****
  
  
  static void
! drawFrames(WWindow *wwin, LinkedList *list, int dx, int dy)
  {
      WWindow *tmpw;
      int scr_width = wwin->screen_ptr->scr_width;
--- 506,512 ----
  
  
  static void
! drawFrames(WWindow *wwin, LinkedList *list, int dx, int dy, int off_x, int off_y)
  {
      WWindow *tmpw;
      int scr_width = wwin->screen_ptr->scr_width;
***************
*** 462,468 ****
      int x, y;
      
      if (!list) {
! 	drawTransparentFrame(wwin, wwin->frame_x + dx, wwin->frame_y + dy,
  			     wwin->frame->core->width, 
  			     wwin->frame->core->height);
  	
--- 514,525 ----
      int x, y;
      
      if (!list) {
! 
!         x = wwin->frame_x + dx;
!         y = wwin->frame_y + dy;
! 
!         checkEdgeResistance(wwin, &x, &y, off_x, off_y);
! 	drawTransparentFrame(wwin, x, y,
  			     wwin->frame->core->width, 
  			     wwin->frame->core->height);
  	
***************
*** 565,575 ****
--- 622,639 ----
      int x = wwin->frame_x;
      int y = wwin->frame_y;
      int ox, oy, orig_x, orig_y;
+     int off_x, off_y;
      short count = 0;		/* for automatic workspace creation */
      int started = 0;
      int warped = 0;
      /* This needs not to change while moving, else bad things can happen */
      int opaque_move = wPreferences.opaque_move;
+     int XOffset, YOffset, origDragX, origDragY;
+ 
+     origDragX = wwin->frame_x;
+     origDragY = wwin->frame_y;
+     XOffset = origDragX - ev->xbutton.x_root;
+     YOffset = origDragY - ev->xbutton.y_root;
      
      if (!wwin->flags.selected) {
  	/* this window is not selected, unselect others and move only wwin */
***************
*** 577,582 ****
--- 641,649 ----
      }
      orig_x = ox = ev->xbutton.x_root;
      orig_y = oy = ev->xbutton.y_root;
+     off_x = x; off_y = y;
+     checkEdgeResistance(wwin, &off_x, &off_y, 0, 0);
+     off_x = (off_x-x); off_y = (off_y-y);
  #ifdef DEBUG
      puts("Moving window");
  #endif
***************
*** 584,592 ****
      shiftr = XKeysymToKeycode(dpy, XK_Shift_R);
      while (1) {
  	if (warped) {
! 	    int junk;
! 	    Window junkw;
! 	    
  	    /* XWarpPointer() doesn't seem to generate Motion events, so
  	     we've got to simulate them */
  	    XQueryPointer(dpy, root, &junkw, &junkw, &event.xmotion.x_root,
--- 651,659 ----
      shiftr = XKeysymToKeycode(dpy, XK_Shift_R);
      while (1) {
  	if (warped) {
!             int junk;
!             Window junkw;
!     
  	    /* XWarpPointer() doesn't seem to generate Motion events, so
  	     we've got to simulate them */
  	    XQueryPointer(dpy, root, &junkw, &junkw, &event.xmotion.x_root,
***************
*** 612,624 ****
  		&& started) {
  		if (!opaque_move)
  		    drawFrames(wwin, wSelectedWindows,
! 			       ox - orig_x, oy - orig_y);
  		
  		cyclePositionDisplay(wwin, x, y, w, h);
  		
  		if (!opaque_move) {
  		    drawFrames(wwin, wSelectedWindows,
! 			       ox - orig_x, oy - orig_y);
  		    showPosition(wwin, x, y);
  		}
  	    }
--- 679,691 ----
  		&& started) {
  		if (!opaque_move)
  		    drawFrames(wwin, wSelectedWindows,
! 			       ox - orig_x, oy - orig_y, off_x, off_y);
  		
  		cyclePositionDisplay(wwin, x, y, w, h);
  		
  		if (!opaque_move) {
  		    drawFrames(wwin, wSelectedWindows,
! 			       ox - orig_x, oy - orig_y, off_x, off_y);
  		    showPosition(wwin, x, y);
  		}
  	    }
***************
*** 627,640 ****
  	 case MotionNotify:
  	    if (started) {
  		if (!opaque_move)
! 		    drawFrames(wwin, wSelectedWindows, ox-orig_x, oy-orig_y);
  		else
! 		    doWindowMove(wwin, wSelectedWindows,
! 				 event.xmotion.x_root - ox,
! 				 event.xmotion.y_root - oy);
! 		x += event.xmotion.x_root - ox;
! 		y += event.xmotion.y_root - oy;
! 		
  		if (!wSelectedWindows) {
  		    if (wPreferences.move_display == WDIS_FRAME_CENTER)
  			moveGeometryDisplayCentered(scr, x + w/2, y + h/2);
--- 694,713 ----
  	 case MotionNotify:
  	    if (started) {
  		if (!opaque_move)
! 		    drawFrames(wwin, wSelectedWindows, ox-orig_x, oy-orig_y, off_x, off_y);
  		else
! 		    doWindowMove(wwin, event.xmotion.x_root + XOffset,
!                                  event.xmotion.y_root + YOffset,
!                                  wSelectedWindows,
!  				 event.xmotion.x_root - ox,
! 				 event.xmotion.y_root - oy,
! 				 off_x, off_y);
! 
! 		x = event.xmotion.x_root + XOffset;
! 		y = event.xmotion.y_root + YOffset;
! 
!                 checkEdgeResistance(wwin, &x, &y, off_x, off_y);
! 
  		if (!wSelectedWindows) {
  		    if (wPreferences.move_display == WDIS_FRAME_CENTER)
  			moveGeometryDisplayCentered(scr, x + w/2, y + h/2);
***************
*** 722,728 ****
  	    oy = event.xmotion.y_root;
  	    
  	    if (started && !opaque_move)
! 		drawFrames(wwin, wSelectedWindows, ox - orig_x, oy - orig_y);
  	    
  	    showPosition(wwin, x, y);
  	    break;
--- 795,801 ----
  	    oy = event.xmotion.y_root;
  	    
  	    if (started && !opaque_move)
! 		drawFrames(wwin, wSelectedWindows, ox - orig_x, oy - orig_y, off_x, off_y);
  	    
  	    showPosition(wwin, x, y);
  	    break;
***************
*** 737,746 ****
  	    if (started) {
  		if (!opaque_move) {
  		    drawFrames(wwin, wSelectedWindows,
! 			       ox - orig_x, oy - orig_y);
  		    XSync(dpy, 0);
! 		    doWindowMove(wwin, wSelectedWindows,
! 				 ox - orig_x, oy - orig_y);
  		}
  #ifndef CONFIGURE_WINDOW_WHILE_MOVING
  		wWindowSynthConfigureNotify(wwin);
--- 810,822 ----
  	    if (started) {
  		if (!opaque_move) {
  		    drawFrames(wwin, wSelectedWindows,
! 			       ox - orig_x, oy - orig_y, off_x, off_y);
  		    XSync(dpy, 0);
! 		    doWindowMove(wwin, event.xmotion.x_root + XOffset,
!                                  event.xmotion.y_root + YOffset,
!                                  wSelectedWindows,
! 				 ox - orig_x, oy - orig_y, 
! 				 off_x, off_y);
  		}
  #ifndef CONFIGURE_WINDOW_WHILE_MOVING
  		wWindowSynthConfigureNotify(wwin);
***************
*** 764,775 ****
  	    
  	 default:
  	    if (started && !opaque_move) {
! 		drawFrames(wwin, wSelectedWindows, ox - orig_x, oy - orig_y);
  		XUngrabServer(dpy);
  		WMHandleEvent(&event);
  		XSync(dpy, False);
  		XGrabServer(dpy);
! 		drawFrames(wwin, wSelectedWindows, ox - orig_x, oy - orig_y);
  	    } else {
  		WMHandleEvent(&event);
  	    }
--- 840,851 ----
  	    
  	 default:
  	    if (started && !opaque_move) {
! 		drawFrames(wwin, wSelectedWindows, ox - orig_x, oy - orig_y, off_x, off_y);
  		XUngrabServer(dpy);
  		WMHandleEvent(&event);
  		XSync(dpy, False);
  		XGrabServer(dpy);
! 		drawFrames(wwin, wSelectedWindows, ox - orig_x, oy - orig_y, off_x, off_y);
  	    } else {
  		WMHandleEvent(&event);
  	    }
