Subject: Smooth MoveResistance

From: Jonas Berlin <[email-masked]>
Date: Wed, 24 Feb 1999 13:09:06 +0200 (EET)

Hello everyone.. Just yesterday joined this list and blablabla..

.. and I successfully managed to add something.. (!)

Well. What I did was a "smoother" version o the MoveResistance feature. I
was annoyed by the fact that the MoveResistance caused the windows to
"jump" when they were moved over the border. So I started looking at the
source (I haven't looked at it at all before, so this patch could be
really stupid etc etc). Anyway, I got it working quite well. I thought
someone else could shout their opinion about whether it is useful or just
useless additional bytes of consumed memory, before I develop it any
further.

I only modified move.c, and I put everything I modified inside #if ..
#else .. #endif parts, so one could easily leave that part out. This
inserting of #if directives might be the worst idea of all, but I'm not
all that familiar with the diff, patch & cvs stuff, so I wanted to make
sure the modified parts could be easily disabled. 

The bugs are (because I didn't want to waste time on it if it is to be
rejected anyway) :

 - the MoveResistance parameter value of the EdgeResistance command
   should be greater than zero to avoid funny-looking behaviour
 - windows bigger than the screen (in either direction) don't work well
   Shouldn't be too hard to fix, though.. 

If to be used any further, an optional field of EdgeResistance would
probably do ok

EdgeResistance scrolling moving ["smooth"]

The smooth would, when specified, just switch from the ordinary to my
version of the thingy..

---

Some other ideas I've had:

Styles:
  ExtraSmartPlacement : place new windows such that as few layers of
             windows as possible (not necessarily as few windows as
             possible) get hidden

  NoSnapAttraction : Windows with this style wouldn't be taken into
             account when doing SnapAttraction

  AutoPlaceSkip : Windows with this style wouldn't be taken into
             account when deciding where to place a new window with
             SmartPlacement (or ExtraSmartPlacement :)

And then I think the required parameter for the "Restart" command is plain
stupid. In my opinion, it should be optional, and when not specified, the
default would be to restart itself without thorwing error messages. At
least personally I use the Restart command to reload the configuration
files, not to switch to another window manager (as I see no reason to..)
But of course, I could just ignore the error messages. Still I think it is
stupid..

And the fact that fvwm tries start up in a normal fashion when the
-version parameter is supplied, I find quite odd. If one uses the -version
parameter, I couldn't find much other reasons to it than that the user
just wants to find out the version and not really start the window
manager.

Finally, it could be practical to have a bit different macro specified
(when precompiling with cpp, probably m4 too) than the current
FVWM_VERSION (or actually, in addition to). I use the same configuration
files with different versions all the time (2.0.46 and up), so directives
like this are really more or less a must:
(I did it externally via the -version parameter)

#if FVWM_VERSION_INT >= 201013 /* 2.01.013 = 2.1.13 and never*/
blaablaa
#elif FVMW_VERSION_INT < 201000 /* older than 2.1 */
blaablaa
#else /* 2.1.0 .. 2.1.12 */
blaablaa
#endif

Ok enough comments from me, some of these could probably have been thrown
into bug reports, but oh well.

---

I look forward to comments about the behaviour of the "smooth" (or
whatever) version...

Now let's hope I at least got the format right (cvs diff -uc move.c)

Index: move.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/move.c,v
retrieving revision 1.28
diff -u -b -B -u -c -r1.28 move.c
*** move.c	1999/02/23 14:57:57	1.28
--- move.c	1999/02/24 10:48:36
***************
*** 458,463 ****
--- 458,470 ----
   * Move the rubberband around, return with the new window location
   *
   ****************************************************************************/
+ 
+ #define USE_SMOOTH_MOVE_RESISTANCE 1
+ /* edge resistance behaviour test v0.1 */
+ /* by Jonas Berlin <[email-masked]> */
+ /* bugs: MoveResistance must be > 0 */
+ /*       Windows bigger than screen (in some direction) don't work well */
+ 
  void moveLoop(FvwmWindow *tmp_win, int XOffset, int YOffset, int Width,
  	      int Height, int *FinalX, int *FinalY,Bool opaque_move,
  	      Bool AddWindow)
***************
*** 467,472 ****
--- 474,484 ----
    int xl,yt,delta_x,delta_y,paged;
    unsigned int button_mask = 0;
    unsigned int bw = tmp_win->bw;
+ #if USE_SMOOTH_MOVE_RESISTANCE
+   int edge_x, edge_y;
+   int diffw, diffh;
+   int whichx, whichy;
+ #endif
    FvwmWindow tmp_win_copy;
  
    /* make a copy of the tmp_win structure for sending to the pager */
***************
*** 478,483 ****
--- 490,506 ----
    xl += XOffset;
    yt += YOffset;
  
+ #if USE_SMOOTH_MOVE_RESISTANCE
+   diffw = Scr.MyDisplayWidth  - Width  - 2 * bw;
+   diffh = Scr.MyDisplayHeight - Height - 2 * bw;
+ 
+   whichx = xl < 0 ? -1 : xl > diffw ? 1 : 0;
+   whichy = yt < 0 ? -1 : yt > diffh ? 1 : 0;
+ 
+   edge_x = whichx ? Scr.MoveResistance : 0;
+   edge_y = whichy ? Scr.MoveResistance : 0;
+ #endif
+ 
    if(((!opaque_move)&&(!Scr.gs.EmulateMWM))||(AddWindow))
      MoveOutline(Scr.Root, xl, yt, Width - 1 + 2 * bw, Height - 1 + 2 * bw);
  
***************
*** 566,571 ****
--- 589,668 ----
  	  DoSnapAttract(tmp_win, Width, Height, &xl, &yt);
  
  	  /* Resist moving windows over the edge of the screen! */
+ #if USE_SMOOTH_MOVE_RESISTANCE
+ 	  if(((xl > diffw / 2) && (whichx >= 0)) || (whichx > 0))
+ 	    if(xl + edge_x >= diffw) {
+ 	      if(!edge_x) {
+ 		whichx = 1;
+ 		edge_x = Scr.MoveResistance;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset-edge_x,yt-YOffset);
+ 	      }
+ 	      if(xl < diffw) xl = diffw;
+ 	    } else {
+ 	      if(edge_x) {
+ 		xl += edge_x;
+ 		edge_x = 0;
+ 		whichx = 0;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset,yt-YOffset);
+ 	      }
+ 	    }
+ 	  else
+ 	    if(xl - edge_x <= 0) {
+ 	      if(!edge_x) {
+ 		whichx = -1;
+ 		edge_x = Scr.MoveResistance;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset+edge_x,yt-YOffset);
+ 	      }
+ 	      if(xl > 0) xl = 0;
+ 	    } else {
+ 	      if(edge_x) {
+ 		xl -= edge_x;
+ 		edge_x = 0;
+ 		whichx = 0;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset,yt-YOffset);
+ 	      }
+ 	    }
+ 	  if(((yt > diffh / 2) && (whichy >= 0)) || (whichy > 0))
+ 	    if(yt + edge_y >= diffh) {
+ 	      if(!edge_y) {
+ 		whichy = 1;
+ 		edge_y = Scr.MoveResistance;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset,yt-YOffset-edge_y);
+ 	      }
+ 	      if(yt < diffh) yt = diffh;
+ 	    } else {
+ 	      if(edge_y) {
+ 		yt += edge_y;
+ 		edge_y = 0;
+ 		whichy = 0;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset,yt-YOffset);
+ 	      }
+ 	    }
+ 	  else
+ 	    if(yt - edge_y <= 0) {
+ 	      if(!edge_y) {
+ 		whichy = -1;
+ 		edge_y = Scr.MoveResistance;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset,yt-YOffset+edge_y);
+ 	      }
+ 	      if(yt > 0) yt = 0;
+ 	    } else {
+ 	      if(edge_y) {
+ 		yt -= edge_y;
+ 		edge_y = 0;
+ 		whichy = 0;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset,yt-YOffset);
+ 	      }
+ 	    }
+ #else /* original MoveResistance */
  	  if(((xl + Width) >= Scr.MyDisplayWidth)&&
  	     ((xl + Width) < Scr.MyDisplayWidth+Scr.MoveResistance))
  	    xl = Scr.MyDisplayWidth - Width - 2 * bw;
***************
*** 576,582 ****
  	    yt = Scr.MyDisplayHeight - Height - 2 * bw;
  	  if((yt <= 0)&&(yt > -Scr.MoveResistance))
  	    yt = 0;
! 
  	  *FinalX = xl;
  	  *FinalY = yt;
  
--- 673,679 ----
  	    yt = Scr.MyDisplayHeight - Height - 2 * bw;
  	  if((yt <= 0)&&(yt > -Scr.MoveResistance))
  	    yt = 0;
! #endif
  	  *FinalX = xl;
  	  *FinalY = yt;
  
***************
*** 596,601 ****
--- 693,774 ----
  	  DoSnapAttract(tmp_win, Width, Height, &xl, &yt);
  
  	  /* Resist moving windows over the edge of the screen! */
+ #if USE_SMOOTH_MOVE_RESISTANCE
+ 	  /* this is exactly the same as the part above */
+ 	  /* (the original parts were also the same...) */
+ 	  if(((xl > diffw / 2) && (whichx >= 0)) || (whichx > 0))
+ 	    if(xl + edge_x >= diffw) {
+ 	      if(!edge_x) {
+ 		whichx = 1;
+ 		edge_x = Scr.MoveResistance;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset-edge_x,yt-YOffset);
+ 	      }
+ 	      if(xl < diffw) xl = diffw;
+ 	    } else {
+ 	      if(edge_x) {
+ 		xl += edge_x;
+ 		edge_x = 0;
+ 		whichx = 0;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset,yt-YOffset);
+ 	      }
+ 	    }
+ 	  else
+ 	    if(xl - edge_x <= 0) {
+ 	      if(!edge_x) {
+ 		whichx = -1;
+ 		edge_x = Scr.MoveResistance;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset+edge_x,yt-YOffset);
+ 	      }
+ 	      if(xl > 0) xl = 0;
+ 	    } else {
+ 	      if(edge_x) {
+ 		xl -= edge_x;
+ 		edge_x = 0;
+ 		whichx = 0;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset,yt-YOffset);
+ 	      }
+ 	    }
+ 	  if(((yt > diffh / 2) && (whichy >= 0)) || (whichy > 0))
+ 	    if(yt + edge_y >= diffh) {
+ 	      if(!edge_y) {
+ 		whichy = 1;
+ 		edge_y = Scr.MoveResistance;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset,yt-YOffset-edge_y);
+ 	      }
+ 	      if(yt < diffh) yt = diffh;
+ 	    } else {
+ 	      if(edge_y) {
+ 		yt += edge_y;
+ 		edge_y = 0;
+ 		whichy = 0;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset,yt-YOffset);
+ 	      }
+ 	    }
+ 	  else
+ 	    if(yt - edge_y <= 0) {
+ 	      if(!edge_y) {
+ 		whichy = -1;
+ 		edge_y = Scr.MoveResistance;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset,yt-YOffset+edge_y);
+ 	      }
+ 	      if(yt > 0) yt = 0;
+ 	    } else {
+ 	      if(edge_y) {
+ 		yt -= edge_y;
+ 		edge_y = 0;
+ 		whichy = 0;
+ 		XWarpPointer(dpy,None,Scr.Root,0,0,0,0,
+ 			     xl-XOffset,yt-YOffset);
+ 	      }
+ 	    }
+ #else /* original MoveResistance */
  	  if(((xl + Width) >= Scr.MyDisplayWidth)&&
  	     ((xl + Width) < Scr.MyDisplayWidth+Scr.MoveResistance))
  	    xl = Scr.MyDisplayWidth - Width - 2 * bw;
***************
*** 606,611 ****
--- 779,785 ----
  	    yt = Scr.MyDisplayHeight - Height - 2 * bw;
  	  if((yt <= 0)&&(yt > -Scr.MoveResistance))
  	    yt = 0;
+ #endif
  
  	  /* check Paging request once and only once after outline redrawn */
  	  /* redraw after paging if needed - mab */

[ Jonas Berlin ]
[ tel: +358-40-5884454 / +358-9-5483430 ]
[ Kiloberget 10 F 55, 02610 Esbo, Finland ]
[ mailto:[email-masked] ]
[ http://www.hut.fi/~jberlin ]

--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked]