Subject: Edge avoidance in window placement [patch]

From: Daniel L Speyer <[email-masked]>
Date: Sun, 24 Feb 2002 02:12:28 -0500 (EST)

Hello,

I've been developing some user-interface stuff on top of Fvwm and I found
it useful to be able to push the screen borders inward in window
placement.  The idea is that you can create a high-level toolbar (e.g. a
windows taskbar or mac menu clone) on a side of the screen and have
windows avoid it, even if Fvwm doesn't know there's anything special about
it.

The patch creates a command PlacementEdgeAvoid which sets the thickness of
the avoid-spaces on each side.  The syntax is 
PlacementEdgeAvoid left_width top_width right_width bottom_width
where each width is an integer measured in pixels.

Various placement schemes have their own edge-avoidance, which I have left
alone (therefore the two values add).  I have done this on the logic that
if it was bad to put a window too close to the top of the screen, it's bad
to put it that close to the bottom of the menubar at the top of the
screen.

I hope this patch proves useful to others (it has to me).  Feel free to
contact me with comments, questions, ideas or flames.

--Daniel Speyer
If you *don't* consider sharing information to be morally equivalent to 
kidnapping and murder on the high seas, you probably shouldn't use the
phrase "software piracy."
diff -u -r fvwm-2.4.5/fvwm/commands.h fvwm-2.4.5-mine/fvwm/commands.h
--- fvwm-2.4.5/fvwm/commands.h	Wed Sep  5 12:39:56 2001
+++ fvwm-2.4.5-mine/fvwm/commands.h	Sun Feb 24 01:15:37 2002
@@ -119,6 +119,7 @@
 void CMD_PipeRead(F_CMD_ARGS);
 void CMD_PixmapPath(F_CMD_ARGS);
 void CMD_PlaceAgain(F_CMD_ARGS);
+void CMD_PlacementEdgeAvoid(F_CMD_ARGS);
 void CMD_PointerKey(F_CMD_ARGS);
 void CMD_Popup(F_CMD_ARGS);
 void CMD_Prev(F_CMD_ARGS);
diff -u -r fvwm-2.4.5/fvwm/functions.c fvwm-2.4.5-mine/fvwm/functions.c
--- fvwm-2.4.5/fvwm/functions.c	Thu Jan 17 07:32:08 2002
+++ fvwm-2.4.5-mine/fvwm/functions.c	Sun Feb 24 01:19:51 2002
@@ -194,6 +194,7 @@
   CMD_ENTRY("piperead", CMD_PipeRead, F_READ, 0),
   CMD_ENTRY("pixmappath", CMD_PixmapPath, F_PIXMAP_PATH, 0),
   CMD_ENTRY("placeagain", CMD_PlaceAgain, F_PLACEAGAIN, FUNC_NEEDS_WINDOW),
+  CMD_ENTRY("placementedgeavoid", CMD_PlacementEdgeAvoid, F_PLACEMENT_EDGE_AVOID, 0),
   CMD_ENTRY("pointerkey", CMD_PointerKey, F_POINTERKEY, 0),
   CMD_ENTRY("popup", CMD_Popup, F_POPUP, 0),
   CMD_ENTRY("prev", CMD_Prev, F_PREV, 0),
diff -u -r fvwm-2.4.5/fvwm/functions.h fvwm-2.4.5-mine/fvwm/functions.h
--- fvwm-2.4.5/fvwm/functions.h	Wed Sep  5 12:39:56 2001
+++ fvwm-2.4.5-mine/fvwm/functions.h	Sun Feb 24 01:20:13 2002
@@ -149,6 +149,7 @@
   F_OPAQUE,
   F_PICK,
   F_PIXMAP_PATH,
+  F_PLACEMENT_EDGE_AVOID,
   F_POINTERKEY,
   F_POPUP,
   F_PREV,
diff -u -r fvwm-2.4.5/fvwm/placement.c fvwm-2.4.5-mine/fvwm/placement.c
--- fvwm-2.4.5/fvwm/placement.c	Sun Dec  9 09:00:08 2001
+++ fvwm-2.4.5-mine/fvwm/placement.c	Sun Feb 24 01:14:56 2002
@@ -54,6 +54,12 @@
 #define MAX(A,B) ((A)>(B)? (A):(B))
 #endif
 
+static int PageEdgeAvoid_left=0;
+static int PageEdgeAvoid_top=0;
+static int PageEdgeAvoid_right=0;
+static int PageEdgeAvoid_bottom=0;
+
+
 static int get_next_x(
   FvwmWindow *t, rectangle *screen_g,
   int x, int y, int pdeltax, int pdeltay, int use_percent);
@@ -66,11 +72,30 @@
   FvwmWindow *t, rectangle *screen_g,
   int *x, int *y, int pdeltax, int pdeltay, int use_percent);
 
+void CMD_PlacementEdgeAvoid(F_CMD_ARGS)
+{
+  int val[4];
+  int n;
+
+  n = GetIntegerArguments(action, NULL, val, 4);
+  if (n != 4)
+  {
+    fvwm_msg(ERR, "PlacementEdgeAvoid",
+	     "PlacementEdgeAvoid require 4 arguments");
+    return;
+  }
+  PageEdgeAvoid_left = val[0];
+  PageEdgeAvoid_top = val[1];
+  PageEdgeAvoid_right = val[2];
+  PageEdgeAvoid_bottom = val[3];
+}
+
+
 static int SmartPlacement(
   FvwmWindow *t, rectangle *screen_g,
   int width, int height, int *x, int *y, int pdeltax, int pdeltay)
 {
-  int PageLeft   = screen_g->x - pdeltax;
+  int PageLeft   = screen_g->x - pdeltax + 50;
   int PageTop    = screen_g->y - pdeltay;
   int PageRight  = PageLeft + screen_g->width;
   int PageBottom = PageTop + screen_g->height;
@@ -586,6 +611,10 @@
   PageTop    = screen_g.y - pdeltay;
   PageRight  = PageLeft + screen_g.width;
   PageBottom = PageTop + screen_g.height;
+  PageLeft   += PageEdgeAvoid_left;
+  PageRight  -= PageEdgeAvoid_right;
+  PageTop    += PageEdgeAvoid_top;
+  PageBottom -= PageEdgeAvoid_bottom;
   yt = PageTop;
 
   /* Don't alter the existing desk location during Capture/Recapture.  */