This patch provides a window attraction mechanism similar to KDE's window snap.
When moving a window if it is with SnapAttraction pixels of another window
it will position itself flush with the other window.  It is my favorite
aspect of KDE's wm so I added here (since I like everything else about
fvwm better).
SnapAttraction is a builtin with one argument.  Defaults to 0.  (KDE defaults
to 10).
diff -c -r ../fvwm-2.0.46/./fvwm/builtins.c ./fvwm/builtins.c
*** ../fvwm-2.0.46/./fvwm/builtins.c	Tue Aug 19 16:41:27 1997
--- ./fvwm/builtins.c	Wed Oct 14 11:39:38 1998
***************
*** 1253,1258 ****
--- 1253,1274 ----
    Scr.ClickTime = val1;
  }
  
+ void SetSnapAttraction(XEvent *eventp,Window w,FvwmWindow *tmp_win,
+               unsigned long context, char *action,int* Module)
+ {
+   int val1;
+   int val1_unit,n;
+ 
+   n = GetOneArgument(action, &val1, &val1_unit);
+   if(n != 1)
+   {
+     fvwm_msg(ERR,"SetSnapAttraction","SnapAttraction requires 1 argument");
+     return;
+   }
+ 
+   Scr.SnapAttraction = val1;
+ }
+ 
  void SetXOR(XEvent *eventp,Window w,FvwmWindow *tmp_win,
              unsigned long context, char *action,int* Module)
  {
diff -c -r ../fvwm-2.0.46/./fvwm/functions.c ./fvwm/functions.c
*** ../fvwm-2.0.46/./fvwm/functions.c	Mon Aug 11 13:09:29 1997
--- ./fvwm/functions.c	Wed Oct 14 11:58:13 1998
***************
*** 126,131 ****
--- 126,132 ----
    {"Send_WindowList",send_list_func, F_SEND_WINDOW_LIST,    FUNC_NO_WINDOW},
    {"SendToModule", SendStrToModule,  F_SEND_STRING,         FUNC_NO_WINDOW},
    {"set_mask",     set_mask_function,F_SET_MASK,            FUNC_NO_WINDOW},
+   {"SnapAttraction",SetSnapAttraction,F_SNAP_ATT,           FUNC_NO_WINDOW},
    {"Stick",        stick_function,   F_STICK,               FUNC_NEEDS_WINDOW},
    {"Style",        ProcessNewStyle,  F_STYLE,               FUNC_NO_WINDOW},
    {"Title",        Nop_func,         F_TITLE,               FUNC_TITLE},
diff -c -r ../fvwm-2.0.46/./fvwm/fvwm.c ./fvwm/fvwm.c
*** ../fvwm-2.0.46/./fvwm/fvwm.c	Mon Aug  4 13:53:32 1997
--- ./fvwm/fvwm.c	Wed Oct 14 11:44:09 1998
***************
*** 1223,1228 ****
--- 1223,1229 ----
  
    Scr.EdgeScrollX = Scr.EdgeScrollY = 100;
    Scr.ScrollResistance = Scr.MoveResistance = 0;
+   Scr.SnapAttraction = 0;
    Scr.OpaqueSize = 5;
    Scr.ClickTime = 150;
    Scr.ColormapFocus = COLORMAP_FOLLOWS_MOUSE;
diff -c -r ../fvwm-2.0.46/./fvwm/misc.h ./fvwm/misc.h
*** ../fvwm-2.0.46/./fvwm/misc.h	Mon Aug 11 13:10:19 1997
--- ./fvwm/misc.h	Wed Oct 14 11:42:30 1998
***************
*** 516,521 ****
--- 516,523 ----
                 unsigned long context, char *action,int* Module);
  void SetClick(XEvent *eventp,Window w,FvwmWindow *tmp_win,
                 unsigned long context, char *action,int* Module);
+ void SetSnapAttraction(XEvent *eventp,Window w,FvwmWindow *tmp_win,
+ 	       unsigned long context, char *action,int* Module);
  void NextFunc(XEvent *eventp,Window w,FvwmWindow *tmp_win,
                unsigned long context, char *action,int* Module);
  void PrevFunc(XEvent *eventp,Window w,FvwmWindow *tmp_win,
diff -c -r ../fvwm-2.0.46/./fvwm/move.c ./fvwm/move.c
*** ../fvwm-2.0.46/./fvwm/move.c	Mon Aug 11 13:53:16 1997
--- ./fvwm/move.c	Wed Oct 14 11:45:33 1998
***************
*** 109,114 ****
--- 109,119 ----
                int Height, int *FinalX, int *FinalY,Bool opaque_move,
                Bool AddWindow)
  {
+ 	Window root, parent, *children;
+ 	FvwmWindow *tmp;
+ 	unsigned int nchildren;
+ 	int i,j;
+ 	int nyt,nxl,dist,closestLeft,closestRight,closestBottom,closestTop;
    Bool finished = False;
    Bool done;
    int xl,yt,delta_x,delta_y,paged;
***************
*** 180,185 ****
--- 185,267 ----
            xl = Event.xmotion.x_root + XOffset;
            yt = Event.xmotion.y_root + YOffset;
  
+ 	/* resist based on window edges */
+ 	tmp = Scr.FvwmRoot.next;
+ 	closestTop = Scr.SnapAttraction;
+ 	closestBottom = Scr.SnapAttraction;
+ 	closestRight = Scr.SnapAttraction;
+ 	closestLeft = Scr.SnapAttraction;
+ 	nxl = xl;
+ 	nyt = yt;
+ 	while(tmp)
+ 	{
+ 		if (tmp_win != tmp)
+ 		{
+ 			if(!(	(tmp->frame_y + tmp->frame_height) < (yt) ||
+ 					(tmp->frame_y) > (yt + Height) ))
+ 			{
+ 				dist = abs(tmp->frame_x - (xl + Width)); 
+ 				if(dist < closestRight)
+ 				{
+ 					closestRight = dist;
+ 					if(((xl + Width) >= tmp->frame_x)&&
+ 						((xl + Width) < tmp->frame_x+Scr.SnapAttraction))
+ 						nxl = tmp->frame_x - Width - tmp_win->bw;
+ 					if(((xl + Width) >= tmp->frame_x-Scr.SnapAttraction)&&
+ 						((xl + Width) < tmp->frame_x))
+ 						nxl = tmp->frame_x - Width - tmp_win->bw;
+ 				}
+ 				dist = abs(tmp->frame_x + tmp->frame_width - xl);
+ 				if(dist < closestLeft)
+ 				{
+ 					closestLeft = dist;
+ 					if((xl <= tmp->frame_x + tmp->frame_width)&&
+ 						(xl > tmp->frame_x + tmp->frame_width-Scr.SnapAttraction))
+ 						nxl = tmp->frame_x + tmp->frame_width;
+ 					if((xl <= tmp->frame_x + tmp->frame_width+Scr.SnapAttraction)&&
+ 						(xl > tmp->frame_x + tmp->frame_width))
+ 						nxl = tmp->frame_x + tmp->frame_width;
+ 				}
+ 			}
+ 			if(!(	(tmp->frame_x + tmp->frame_width) < (xl) ||
+ 					(tmp->frame_x) > (xl + Width) ))
+ 			{
+ 				dist = abs(tmp->frame_y - (yt + Height)); 
+ 				if(dist < closestBottom)
+ 				{
+ 					closestBottom = dist;
+ 					if(((yt + Height) >= tmp->frame_y)&&
+ 						((yt + Height) < tmp->frame_y+Scr.SnapAttraction))
+ 						nyt = tmp->frame_y - Height - tmp_win->bw;
+ 					if(((yt + Height) >= tmp->frame_y-Scr.SnapAttraction)&&
+ 						((yt + Height) < tmp->frame_y))
+ 						nyt = tmp->frame_y - Height - tmp_win->bw;
+ 				}
+ 				dist = abs(tmp->frame_y + tmp->frame_height - yt);
+ 				if(dist < closestTop)
+ 				{
+ 					closestTop = dist;
+ 					if((yt <= tmp->frame_y + tmp->frame_height)&&
+ 						(yt > tmp->frame_y + tmp->frame_height-Scr.SnapAttraction))
+ 						nyt = tmp->frame_y + tmp->frame_height;
+ 					if((yt <= tmp->frame_y + tmp->frame_height+Scr.SnapAttraction)&&
+ 						(yt > tmp->frame_y + tmp->frame_height))
+ 						nyt = tmp->frame_y + tmp->frame_height;
+ 				}
+ 			}
+ #if 0
+ 			if(((yt + Height) >= Scr.MyDisplayHeight)&&
+ 				((yt + Height) < Scr.MyDisplayHeight+Scr.MoveResistance))
+ 				yt = Scr.MyDisplayHeight - Height - tmp_win->bw;
+ 			if((yt <= 0)&&(yt > -Scr.MoveResistance))
+ 				yt = 0;
+ #endif
+ 		}
+ 		tmp = tmp->next;
+ 	}
+ 	xl = nxl;
+ 	yt = nyt;
+ 
            /* Resist moving windows over the edge of the screen! */
            if(((xl + Width) >= Scr.MyDisplayWidth)&&
               ((xl + Width) < Scr.MyDisplayWidth+Scr.MoveResistance))
***************
*** 208,213 ****
--- 290,372 ----
            xl += XOffset;
            yt += YOffset;
  
+ 	/* resist based on window edges */
+ 	tmp = Scr.FvwmRoot.next;
+ 	closestTop = Scr.SnapAttraction;
+ 	closestBottom = Scr.SnapAttraction;
+ 	closestRight = Scr.SnapAttraction;
+ 	closestLeft = Scr.SnapAttraction;
+ 	nxl = xl;
+ 	nyt = yt;
+ 	while(tmp)
+ 	{
+ 		if (tmp_win != tmp)
+ 		{
+ 			if(!(	(tmp->frame_y + tmp->frame_height) < (yt) ||
+ 					(tmp->frame_y) > (yt + Height) ))
+ 			{
+ 				dist = abs(tmp->frame_x - (xl + Width)); 
+ 				if(dist < closestRight)
+ 				{
+ 					closestRight = dist;
+ 					if(((xl + Width) >= tmp->frame_x)&&
+ 						((xl + Width) < tmp->frame_x+Scr.SnapAttraction))
+ 						nxl = tmp->frame_x - Width - tmp_win->bw;
+ 					if(((xl + Width) >= tmp->frame_x-Scr.SnapAttraction)&&
+ 						((xl + Width) < tmp->frame_x))
+ 						nxl = tmp->frame_x - Width - tmp_win->bw;
+ 				}
+ 				dist = abs(tmp->frame_x + tmp->frame_width - xl);
+ 				if(dist < closestLeft)
+ 				{
+ 					closestLeft = dist;
+ 					if((xl <= tmp->frame_x + tmp->frame_width)&&
+ 						(xl > tmp->frame_x + tmp->frame_width-Scr.SnapAttraction))
+ 						nxl = tmp->frame_x + tmp->frame_width;
+ 					if((xl <= tmp->frame_x + tmp->frame_width+Scr.SnapAttraction)&&
+ 						(xl > tmp->frame_x + tmp->frame_width))
+ 						nxl = tmp->frame_x + tmp->frame_width;
+ 				}
+ 			}
+ 			if(!(	(tmp->frame_x + tmp->frame_width) < (xl) ||
+ 					(tmp->frame_x) > (xl + Width) ))
+ 			{
+ 				dist = abs(tmp->frame_y - (yt + Height)); 
+ 				if(dist < closestBottom)
+ 				{
+ 					closestBottom = dist;
+ 					if(((yt + Height) >= tmp->frame_y)&&
+ 						((yt + Height) < tmp->frame_y+Scr.SnapAttraction))
+ 						nyt = tmp->frame_y - Height - tmp_win->bw;
+ 					if(((yt + Height) >= tmp->frame_y-Scr.SnapAttraction)&&
+ 						((yt + Height) < tmp->frame_y))
+ 						nyt = tmp->frame_y - Height - tmp_win->bw;
+ 				}
+ 				dist = abs(tmp->frame_y + tmp->frame_height - yt);
+ 				if(dist < closestTop)
+ 				{
+ 					closestTop = dist;
+ 					if((yt <= tmp->frame_y + tmp->frame_height)&&
+ 						(yt > tmp->frame_y + tmp->frame_height-Scr.SnapAttraction))
+ 						nyt = tmp->frame_y + tmp->frame_height;
+ 					if((yt <= tmp->frame_y + tmp->frame_height+Scr.SnapAttraction)&&
+ 						(yt > tmp->frame_y + tmp->frame_height))
+ 						nyt = tmp->frame_y + tmp->frame_height;
+ 				}
+ 			}
+ #if 0
+ 			if(((yt + Height) >= Scr.MyDisplayHeight)&&
+ 				((yt + Height) < Scr.MyDisplayHeight+Scr.MoveResistance))
+ 				yt = Scr.MyDisplayHeight - Height - tmp_win->bw;
+ 			if((yt <= 0)&&(yt > -Scr.MoveResistance))
+ 				yt = 0;
+ #endif
+ 		}
+ 		tmp = tmp->next;
+ 	}
+ 	xl = nxl;
+ 	yt = nyt;
+ 
            /* Resist moving windows over the edge of the screen! */
            if(((xl + Width) >= Scr.MyDisplayWidth)&&
               ((xl + Width) < Scr.MyDisplayWidth+Scr.MoveResistance))
***************
*** 219,225 ****
              yt = Scr.MyDisplayHeight - Height - tmp_win->bw;
            if((yt <= 0)&&(yt > -Scr.MoveResistance))
              yt = 0;
- 
          /* check Paging request once and only once after outline redrawn */
          /* redraw after paging if needed - mab */
          paged=0;
--- 378,383 ----
diff -c -r ../fvwm-2.0.46/./fvwm/parse.h ./fvwm/parse.h
*** ../fvwm-2.0.46/./fvwm/parse.h	Mon Aug 11 13:10:39 1997
--- ./fvwm/parse.h	Wed Oct 14 11:41:16 1998
***************
*** 75,80 ****
--- 75,81 ----
  #define F_EXEC_SETUP            57
  #define F_CURSOR_STYLE          58
  #define F_CURRENT               59
+ #define F_SNAP_ATT              60
  
  /* Functions which require a target window */
  #define F_RESIZE		100
diff -c -r ../fvwm-2.0.46/./fvwm/screen.h ./fvwm/screen.h
*** ../fvwm-2.0.46/./fvwm/screen.h	Mon Aug  4 13:55:30 1997
--- ./fvwm/screen.h	Wed Oct 14 11:48:25 1998
***************
*** 311,316 ****
--- 311,317 ----
    int ClickTime;               /*Max button-click delay for Function built-in*/
    int ScrollResistance;        /* resistance to scrolling in desktop */
    int MoveResistance;          /* res to moving windows over viewport edge */
+   int SnapAttraction;          /* attractiveness of window edges */
    int OpaqueSize;
    int CurrentDesk;             /* The current desktop number */
    int ColormapFocus;           /* colormap focus style */
Only in .: patchfile
--
Visit the official FVWM web page at <URL:http://www.hpc.uh.edu/fvwm/>.
To unsubscribe from the list, send "unsubscribe fvwm" in the body of a
message to majordomo_at_hpc.uh.edu.
To report problems, send mail to fvwm-owner_at_hpc.uh.edu.
Received on Thu Oct 15 1998 - 11:13:45 BST