Subject: SnapAttraction Oops (attached patch didnt fly)

From: [email-masked]
Date: Tue, 1 Dec 1998 17:10:38 -0800

Oops, the patch wasnt attached to my last email, here it is:

diff -Naur fvwm-2.1.2/fvwm/builtins.c fvwm_linux/fvwm/builtins.c
--- fvwm-2.1.2/fvwm/builtins.c	Fri Nov 20 05:51:11 1998
+++ fvwm_linux/fvwm/builtins.c	Tue Dec  1 13:13:15 1998
@@ -1268,7 +1268,9 @@
 {
   int val1;
   int val1_unit,n;
+  char *token = NULL;
 
+#if 0
   n = GetOneArgument(action, &val1, &val1_unit);
   if(n != 1)
   {
@@ -1277,6 +1279,56 @@
   }
 
   Scr.SnapAttraction = val1;
+#endif
+
+  action = GetNextToken(action, &token);
+  if(token == NULL)
+  {
+    fvwm_msg(ERR,"SetSnapAttraction",
+      "SnapAttraction requires at least 1 argument");
+    return;
+  }
+
+  sscanf(token,"%d", &(Scr.SnapAttraction));
+
+  free(token);
+
+  action = GetNextToken(action, &token);
+
+  if(token == NULL)
+  {
+    return;
+  }
+  
+  if(StrEquals(token,"All"))
+    { Scr.SnapMode = 0; }
+  if(StrEquals(token,"SameType"))
+    { Scr.SnapMode = 1; }
+  if(StrEquals(token,"Icons"))
+    { Scr.SnapMode = 2; }
+  if(StrEquals(token,"Windows"))
+    { Scr.SnapMode = 3; }
+
+  free(token);
+}
+
+void SetSnapGrid(XEvent *eventp,Window w,FvwmWindow *tmp_win,
+              unsigned long context, char *action,int* Module)
+{
+  int val1, val2;
+  int val1_unit,val2_unit,n;
+
+  n = GetTwoArguments(action, &val1, &val2, &val1_unit, &val2_unit);
+  if(n != 2)
+  {
+    fvwm_msg(ERR,"SetSnapGrid","SetSnapGrid requires 2 arguments");
+    return;
+  }
+
+  Scr.SnapGridX = val1;
+  if(Scr.SnapGridX < 1) { Scr.SnapGridX = 1;}
+  Scr.SnapGridY = val2;
+  if(Scr.SnapGridY < 1) { Scr.SnapGridY = 1;}
 }
 
 void SetXOR(XEvent *eventp,Window w,FvwmWindow *tmp_win,
diff -Naur fvwm-2.1.2/fvwm/functions.c fvwm_linux/fvwm/functions.c
--- fvwm-2.1.2/fvwm/functions.c	Fri Nov 20 05:51:14 1998
+++ fvwm_linux/fvwm/functions.c	Thu Nov 26 21:24:35 1998
@@ -143,6 +143,7 @@
   {"SetMenuDelay", set_menudelay,    F_SET_MENUDELAY,	    FUNC_NO_WINDOW},
   {"SetMenustyle", SetMenuStyle,     F_SET_MENUSTYLE,       FUNC_NO_WINDOW},
   {"SnapAttraction",SetSnapAttraction,F_SNAP_ATT,           FUNC_NO_WINDOW},
+  {"SnapGrid",     SetSnapGrid,      F_SNAP_GRID,           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 -Naur fvwm-2.1.2/fvwm/fvwm.c fvwm_linux/fvwm/fvwm.c
--- fvwm-2.1.2/fvwm/fvwm.c	Fri Nov 20 05:51:14 1998
+++ fvwm_linux/fvwm/fvwm.c	Fri Nov 27 12:36:53 1998
@@ -1253,7 +1253,10 @@
 
   Scr.EdgeScrollX = Scr.EdgeScrollY = 100;
   Scr.ScrollResistance = Scr.MoveResistance = 0;
-  Scr.SnapAttraction = 0;
+  Scr.SnapAttraction = -1;
+  Scr.SnapMode = 0;
+  Scr.SnapGridX = 1;
+  Scr.SnapGridY = 1;
   Scr.OpaqueSize = 5;
   Scr.ClickTime = 150;
   Scr.ColormapFocus = COLORMAP_FOLLOWS_MOUSE;
diff -Naur fvwm-2.1.2/fvwm/fvwm2.1 fvwm_linux/fvwm/fvwm2.1
--- fvwm-2.1.2/fvwm/fvwm2.1	Fri Nov 20 05:51:14 1998
+++ fvwm_linux/fvwm/fvwm2.1	Tue Dec  1 13:30:16 1998
@@ -1871,10 +1871,48 @@
 If the letter "p" is appended to each coordinate (horizontal and/or
 vertical), then the scroll amount will be measured in pixels.
 
-.IP "SnapAttraction \fIproximity\fP"
-If during an interactive move the window comes within \fIproximity\fP
-pixels of another the window will be moved to make the borders
-adjoin. The default of zero means that no snapping will happen.
+.IP "SnapAttraction \fIproximity behavior\fP"
+If during an interactive move the window (or icon) comes within \fIproximity\fP
+pixels of another the window (or icon) will be moved to make the borders
+adjoin. The default of -1 means that no snapping will happen.  A setting of
+0 does indeed snap when the distance is zero pixels.  This is relevent when
+the \fISnapGrid\fP option is used.
+
+The \fIbehavior\fP argument is optional and may be set to one of the four
+following values:
+.in +.5i
+All
+.in +.3i
+Windows snap to both other windows and other icons.  Icons snap to both other
+windows and other icons.
+.in -.3i
+SameType
+.in +.3i
+Windows snap to only other windows.  Icons snap to only other icons.
+.in -.3i
+Windows
+.in +.3i
+Windows snap to only other windows.  Icons do not snap.
+.in -.3i
+Icons
+.in +.3i
+Icons snap to only other icons.  Windows do not snap.
+.in -.3i
+.in -.5i
+
+The default SnapAttraction setting for behavior is "All".
+
+.IP "SnapGrid \fIx-grid-size y-grid-size\fP"
+During an interactive move a window (or icon) will be positioned such that 
+its location (top left corner) will be coincindent with the nearest grid point.
+The default \fIx-grid-size\fP and \fIy-grid-size\fP setting are both 1, which 
+is effectively no grid all.  An interactive move with both \fISnapGrid\fP
+and \fISnapAttraction\fP in effect will result in the window being moved to be
+adjacent to the nearest window border (if within snap proximity) or grid 
+position.  In other words, the window will move the shortest distance possible
+to satisfy both \fISnapGrid\fP and \fISnapAttraction\fP.  Note that the X and 
+Y coordinates are not coupled.  For example, a window may snap to another window
+on the X axis while snapping to a grid point on the Y axis.
 
 .IP "SendToModule \fImodulename string\fP"
 Sends an arbitrary string (no quotes required) to all modules matching
diff -Naur fvwm-2.1.2/fvwm/misc.h fvwm_linux/fvwm/misc.h
--- fvwm-2.1.2/fvwm/misc.h	Fri Nov 20 05:51:15 1998
+++ fvwm_linux/fvwm/misc.h	Thu Nov 26 21:21:15 1998
@@ -518,6 +518,8 @@
 	       unsigned long context, char *action,int* Module);
 void SetSnapAttraction(XEvent *eventp,Window w,FvwmWindow *tmp_win,
 			unsigned long context, char *action,int* Module);
+void SetSnapGrid(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 -Naur fvwm-2.1.2/fvwm/move.c fvwm_linux/fvwm/move.c
--- fvwm-2.1.2/fvwm/move.c	Fri Nov 20 05:51:16 1998
+++ fvwm_linux/fvwm/move.c	Tue Dec  1 13:13:12 1998
@@ -243,6 +243,13 @@
   move_window_doit(eventp,w,tmp_win,context,action,Module,FALSE,TRUE);
 }
 
+typedef struct _FvwmMoveable
+{
+	int w;
+	int h;
+	int x;
+	int y;
+} FvwmMoveable;
 
 /****************************************************************************
  *
@@ -262,6 +269,7 @@
   Bool done;
   int xl,yt,delta_x,delta_y,paged;
   unsigned int button_mask = 0;
+  FvwmMoveable self, other;
   
   XQueryPointer(dpy, Scr.Root, &JunkRoot, &JunkChild,&xl, &yt,
 		&JunkX, &JunkY, &button_mask);
@@ -354,89 +362,157 @@
 	  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 && !(tmp->flags&ICONIFIED) &&
-		  (tmp_win->Desk == tmp->Desk))
+	/* START OF SNAPATTRACTION BLOCK, mirrored in MotionNotify */
+	/* resist based on window edges */
+	tmp = Scr.FvwmRoot.next;
+	closestTop = Scr.SnapAttraction;
+	closestBottom = Scr.SnapAttraction;
+	closestRight = Scr.SnapAttraction;
+	closestLeft = Scr.SnapAttraction;
+	nxl = -1;
+	nyt = -1;
+	self.x = xl;
+	self.y = yt;
+	if(tmp_win->flags&ICONIFIED)
+	{
+		self.w = Width;
+		self.h = Height;
+	}
+	else
+	{
+		self.w = Width + tmp_win->bw;
+		self.h = Height + tmp_win->bw;
+	}
+	while(Scr.SnapAttraction >= 0 && tmp)
+	{
+		if(Scr.SnapMode == 0)  /* All */
+		{
+			/* NOOP */
+		}
+		if(Scr.SnapMode == 1)  /* SameType */
 		{
-		  if(!((tmp->frame_y + tmp->frame_height) < (yt) ||
-		       (tmp->frame_y) > (yt + Height) ))
-		    {
-		      dist = abs(tmp->frame_x - (xl + Width));
-		      if(dist < closestRight)
+			if( (tmp->flags&ICONIFIED) != (tmp_win->flags&ICONIFIED) )
+				{ tmp = tmp->next; continue; }
+		}
+		if(Scr.SnapMode == 2)  /* Icons */
+		{
+			if( !(tmp->flags&ICONIFIED) || !(tmp_win->flags&ICONIFIED) )
+				{ tmp = tmp->next; continue; }
+		}
+		if(Scr.SnapMode == 3)  /* Windows */
+		{
+			if( (tmp->flags&ICONIFIED) || (tmp_win->flags&ICONIFIED) )
+				{ tmp = tmp->next; continue; }
+		}
+		if (tmp_win != tmp && (tmp_win->Desk == tmp->Desk))
+		{
+			if(tmp->flags&ICONIFIED)
 			{
-			  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;
+				if(tmp->icon_p_height > 0)
+				{
+					other.w = tmp->icon_p_width;
+					other.h = tmp->icon_p_height;
+				}
+				else
+				{
+					other.w = tmp->icon_w_width;
+					other.h = tmp->icon_w_height;
+				}
+				other.x = tmp->icon_x_loc;
+				other.y = tmp->icon_y_loc;
 			}
-		      dist = abs(tmp->frame_x + tmp->frame_width - xl);
-		      if(dist < closestLeft)
+			else
 			{
-			  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;
+				other.w = tmp->frame_width + 2 * tmp->bw;
+				other.h = tmp->frame_height + 2 * tmp->bw;
+				other.x = tmp->frame_x;
+				other.y = tmp->frame_y;
 			}
-		    }
-		  if(!(   (tmp->frame_x + tmp->frame_width) < (xl) ||
-			  (tmp->frame_x) > (xl + Width) ))
-		    {
-		      dist = abs(tmp->frame_y - (yt + Height));
-		      if(dist < closestBottom)
+			if(!((other.y + other.h) < (yt) ||
+				(other.y) > (yt + self.h) ))
 			{
-			  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(other.x - (xl + self.w));
+				if(dist < closestRight)
+				{
+					closestRight = dist;
+					if(((xl + self.w) >= other.x)&&
+						((xl + self.w) < other.x+Scr.SnapAttraction))
+						nxl = other.x - self.w;
+
+					if(((xl + self.w) >= other.x
+						- Scr.SnapAttraction)&&
+						((xl + self.w) < other.x))
+						nxl = other.x - self.w;
+				}
+				dist = abs(other.x + other.w - xl);
+				if(dist < closestLeft)
+				{
+					closestLeft = dist;
+					if((xl <= other.x + other.w)&&
+						(xl > other.x + other.w
+						- Scr.SnapAttraction))
+						nxl = other.x + other.w;
+					if((xl <= other.x + other.w
+						+ Scr.SnapAttraction)&&
+						(xl > other.x + other.w))
+						nxl = other.x + other.w;
+				}
 			}
-		      dist = abs(tmp->frame_y + tmp->frame_height - yt);
-		      if(dist < closestTop)
+			if(!(   (other.x + other.w) < (xl) ||
+				(other.x) > (xl + self.w) ))
 			{
-			  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;
+				dist = abs(other.y - (yt + self.h));
+				if(dist < closestBottom)
+				{
+					closestBottom = dist;
+					if(((yt + self.h) >= other.y)&&
+						((yt + self.h) < other.y+Scr.SnapAttraction))
+						nyt = other.y - self.h;
+					if(((yt + self.h) >= other.y
+						- Scr.SnapAttraction)&&
+						((yt + self.h) < other.y))
+						nyt = other.y - self.h;
+				}
+				dist = abs(other.y + other.h - yt);
+				if(dist < closestTop)
+				{
+					closestTop = dist;
+					if((yt <= other.y + other.h)&&
+						(yt > other.y + other.h
+						- Scr.SnapAttraction))
+						nyt = other.y + other.h;
+					if((yt <= other.y + other.h
+						+ Scr.SnapAttraction)&&
+						(yt > other.y + other.h))
+						nyt = other.y + other.h;
+				}
 			}
-		    }
-#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;
+		}
+		tmp = tmp->next;
+	}
+	if(nxl == -1)
+	{
+		if(xl != xl  / Scr.SnapGridX * Scr.SnapGridX)
+		{
+			xl = (xl+Scr.SnapGridX/2) / Scr.SnapGridX * Scr.SnapGridX;
+		}
+	}
+	else
+	{
+		xl = nxl;
+	}
+	if(nyt == -1)
+	{
+		if(yt != yt  / Scr.SnapGridY * Scr.SnapGridY)
+		{
+			yt = (yt+Scr.SnapGridY/2) / Scr.SnapGridY * Scr.SnapGridY;
+		}
+	}
+	else
+	{
+		yt = nyt;
+	}
+	/* END OF SNAPATTRACTION BLOCK, mirrored in MotionNotify */
 	  
 	  /* Resist moving windows over the edge of the screen! */
 	  if(((xl + Width) >= Scr.MyDisplayWidth)&&
@@ -466,85 +542,157 @@
 	  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 && !(tmp->flags&ICONIFIED) &&
-	       (tmp_win->Desk == tmp->Desk))
-	   {
-	     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;
+	/* START OF SNAPATTRACTION BLOCK, mirrored in ButtonRelease */
+	/* resist based on window edges */
+	tmp = Scr.FvwmRoot.next;
+	closestTop = Scr.SnapAttraction;
+	closestBottom = Scr.SnapAttraction;
+	closestRight = Scr.SnapAttraction;
+	closestLeft = Scr.SnapAttraction;
+	nxl = -1;
+	nyt = -1;
+	self.x = xl;
+	self.y = yt;
+	if(tmp_win->flags&ICONIFIED)
+	{
+		self.w = Width;
+		self.h = Height;
+	}
+	else
+	{
+		self.w = Width + tmp_win->bw;
+		self.h = Height + tmp_win->bw;
+	}
+	while(Scr.SnapAttraction >= 0 && tmp)
+	{
+		if(Scr.SnapMode == 0)  /* All */
+		{
+			/* NOOP */
+		}
+		if(Scr.SnapMode == 1)  /* SameType */
+		{
+			if( (tmp->flags&ICONIFIED) != (tmp_win->flags&ICONIFIED) )
+				{ tmp = tmp->next; continue; }
+		}
+		if(Scr.SnapMode == 2)  /* Icons */
+		{
+			if( !(tmp->flags&ICONIFIED) || !(tmp_win->flags&ICONIFIED) )
+				{ tmp = tmp->next; continue; }
+		}
+		if(Scr.SnapMode == 3)  /* Windows */
+		{
+			if( (tmp->flags&ICONIFIED) || (tmp_win->flags&ICONIFIED) )
+				{ tmp = tmp->next; continue; }
+		}
+		if (tmp_win != tmp && (tmp_win->Desk == tmp->Desk))
+		{
+			if(tmp->flags&ICONIFIED)
+			{
+				if(tmp->icon_p_height > 0)
+				{
+					other.w = tmp->icon_p_width;
+					other.h = tmp->icon_p_height;
+				}
+				else
+				{
+					other.w = tmp->icon_w_width;
+					other.h = tmp->icon_w_height;
+				}
+				other.x = tmp->icon_x_loc;
+				other.y = tmp->icon_y_loc;
+			}
+			else
+			{
+				other.w = tmp->frame_width + 2 * tmp->bw;
+				other.h = tmp->frame_height + 2 * tmp->bw;
+				other.x = tmp->frame_x;
+				other.y = tmp->frame_y;
+			}
+			if(!((other.y + other.h) < (yt) ||
+				(other.y) > (yt + self.h) ))
+			{
+				dist = abs(other.x - (xl + self.w));
+				if(dist < closestRight)
+				{
+					closestRight = dist;
+					if(((xl + self.w) >= other.x)&&
+						((xl + self.w) < other.x+Scr.SnapAttraction))
+						nxl = other.x - self.w;
+
+					if(((xl + self.w) >= other.x
+						- Scr.SnapAttraction)&&
+						((xl + self.w) < other.x))
+						nxl = other.x - self.w;
+				}
+				dist = abs(other.x + other.w - xl);
+				if(dist < closestLeft)
+				{
+					closestLeft = dist;
+					if((xl <= other.x + other.w)&&
+						(xl > other.x + other.w
+						- Scr.SnapAttraction))
+						nxl = other.x + other.w;
+					if((xl <= other.x + other.w
+						+ Scr.SnapAttraction)&&
+						(xl > other.x + other.w))
+						nxl = other.x + other.w;
+				}
+			}
+			if(!(   (other.x + other.w) < (xl) ||
+				(other.x) > (xl + self.w) ))
+			{
+				dist = abs(other.y - (yt + self.h));
+				if(dist < closestBottom)
+				{
+					closestBottom = dist;
+					if(((yt + self.h) >= other.y)&&
+						((yt + self.h) < other.y+Scr.SnapAttraction))
+						nyt = other.y - self.h;
+					if(((yt + self.h) >= other.y
+						- Scr.SnapAttraction)&&
+						((yt + self.h) < other.y))
+						nyt = other.y - self.h;
+				}
+				dist = abs(other.y + other.h - yt);
+				if(dist < closestTop)
+				{
+					closestTop = dist;
+					if((yt <= other.y + other.h)&&
+						(yt > other.y + other.h
+						- Scr.SnapAttraction))
+						nyt = other.y + other.h;
+					if((yt <= other.y + other.h
+						+ Scr.SnapAttraction)&&
+						(yt > other.y + other.h))
+						nyt = other.y + other.h;
+				}
+			}
+		}
+		tmp = tmp->next;
+	}
+	if(nxl == -1)
+	{
+		if(xl != xl  / Scr.SnapGridX * Scr.SnapGridX)
+		{
+			xl = (xl+Scr.SnapGridX/2) / Scr.SnapGridX * Scr.SnapGridX;
+		}
+	}
+	else
+	{
+		xl = nxl;
+	}
+	if(nyt == -1)
+	{
+		if(yt != yt  / Scr.SnapGridY * Scr.SnapGridY)
+		{
+			yt = (yt+Scr.SnapGridY/2) / Scr.SnapGridY * Scr.SnapGridY;
+		}
+	}
+	else
+	{
+		yt = nyt;
+	}
+	/* END OF SNAPATTRACTION BLOCK, mirrored in ButtonRelease */
 	 
 	 /* Resist moving windows over the edge of the screen! */
 	 if(((xl + Width) >= Scr.MyDisplayWidth)&&
diff -Naur fvwm-2.1.2/fvwm/parse.h fvwm_linux/fvwm/parse.h
--- fvwm-2.1.2/fvwm/parse.h	Fri Nov 20 05:51:16 1998
+++ fvwm_linux/fvwm/parse.h	Thu Nov 26 21:22:50 1998
@@ -84,7 +84,8 @@
     F_SET_MENUSTYLE,
     F_CHANGE_MENUSTYLE,
     F_DESTROY_MENUSTYLE,
-    F_SNAP_ATT, /* 65 */
+    F_SNAP_ATT, 
+    F_SNAP_GRID, /* 66 */
 /* Functions which require a target window */
     F_RESIZE = 100,
     F_RAISE,
diff -Naur fvwm-2.1.2/fvwm/screen.h fvwm_linux/fvwm/screen.h
--- fvwm-2.1.2/fvwm/screen.h	Fri Nov 20 05:51:17 1998
+++ fvwm_linux/fvwm/screen.h	Fri Nov 27 11:59:31 1998
@@ -305,6 +305,9 @@
   int ScrollResistance;        /* resistance to scrolling in desktop */
   int MoveResistance;          /* res to moving windows over viewport edge */
   int SnapAttraction;          /* attractiveness of window edges */
+  int SnapMode;                /* mode of snap attraction */
+  int SnapGridX;               /* snap grid X size */
+  int SnapGridY;               /* snap grid Y size */
   int OpaqueSize;
   int CurrentDesk;             /* The current desktop number */
   int ColormapFocus;           /* colormap focus style */
--
Visit the official FVWM web page at <URL:http://www.hpc.uh.edu/fvwm/>.
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].