Subject: FVWM: [patch] feature request - remember the page position on all desks

From: Jindrich Makovicka <[email-masked]>
Date: Wed, 06 Oct 2004 18:39:02 +0200

Hello,

would it be possible to make fvwm remember the page positions on all 
desktops, somehow like in the attached patch? After applying it, it is 
possible to use a new command called GotoDeskPrevPage, which works like 
ordinary GotoDesk, only it jumps to the position where user previously 
left the target desk. I found it quite useful, when I switch between two 
desktops back and forth using keyboard and have two windows on different 
places on each desk.

I don't know the fvwm internals very well, so the patch can be buggy, 
but I am sending it for illustration anyway :)

Regards,
--
Jindrich Makovicka
Index: fvwm/commands.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/commands.h,v
retrieving revision 1.43
diff -u -r1.43 commands.h
--- fvwm/commands.h	30 Sep 2004 17:45:52 -0000	1.43
+++ fvwm/commands.h	6 Oct 2004 16:27:46 -0000
@@ -280,6 +280,7 @@
 P(GnomeShowDesks);
 P(GotoDesk);
 P(GotoDeskAndPage);
+P(GotoDeskPrevPage);
 P(GotoPage);
 P(HideGeometryWindow);
 P(HilightColor);
Index: fvwm/ewmh_events.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/ewmh_events.c,v
retrieving revision 1.45
diff -u -r1.45 ewmh_events.c
--- fvwm/ewmh_events.c	6 Aug 2004 19:42:54 -0000	1.45
+++ fvwm/ewmh_events.c	6 Oct 2004 16:27:47 -0000
@@ -50,7 +50,7 @@
  */
 int ewmh_CurrentDesktop(EWMH_CMD_ARGS)
 {
-	goto_desk(ev->xclient.data.l[0]);
+	goto_desk(ev->xclient.data.l[0], 0);
 	return -1;
 }
 
Index: fvwm/focus.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/focus.c,v
retrieving revision 1.152
diff -u -r1.152 focus.c
--- fvwm/focus.c	1 Sep 2004 14:55:18 -0000	1.152
+++ fvwm/focus.c	6 Oct 2004 16:27:47 -0000
@@ -427,7 +427,7 @@
 	}
 	if (t->Desk != Scr.CurrentDesk)
 	{
-		goto_desk(t->Desk);
+		goto_desk(t->Desk, 0);
 	}
 	if (IS_ICONIFIED(t))
 	{
@@ -639,7 +639,7 @@
 	{
 		if (fw->Desk != Scr.CurrentDesk)
 		{
-			goto_desk(fw->Desk);
+			goto_desk(fw->Desk, 0);
 		}
 		if (IS_ICONIFIED(fw))
 		{
Index: fvwm/functable.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/functable.c,v
retrieving revision 1.31
diff -u -r1.31 functable.c
--- fvwm/functable.c	30 Sep 2004 17:45:52 -0000	1.31
+++ fvwm/functable.c	6 Oct 2004 16:27:47 -0000
@@ -295,6 +295,9 @@
 	CMD_ENT("gotodeskandpage", CMD_GotoDeskAndPage, F_GOTO_DESK, 0, 0),
 	/* - Switch viewport to another desk and page */
 
+	CMD_ENT("gotodeskprevpage", CMD_GotoDeskPrevPage, F_GOTO_DESK, 0, 0),
+	/* - Switch viewport to another desk previous page */
+
 	CMD_ENT("gotopage", CMD_GotoPage, F_GOTO_PAGE, 0, 0),
 	/* - Switch viewport to another page same desk */
 
Index: fvwm/gnome.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/gnome.c,v
retrieving revision 1.64
diff -u -r1.64 gnome.c
--- fvwm/gnome.c	29 Jun 2003 19:53:23 -0000	1.64
+++ fvwm/gnome.c	6 Oct 2004 16:27:47 -0000
@@ -969,7 +969,7 @@
 	a = XInternAtom(dpy, XA_WIN_WORKSPACE, False);
 	if (ev->xclient.message_type == a)
 	{
-		goto_desk(ev->xclient.data.l[0]);
+		goto_desk(ev->xclient.data.l[0], 0);
 		return 1;
 	}
 	a = XInternAtom(dpy, XA_WIN_LAYER, False);
Index: fvwm/placement.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/placement.c,v
retrieving revision 1.138
diff -u -r1.138 placement.c
--- fvwm/placement.c	3 Sep 2004 08:22:22 -0000	1.138
+++ fvwm/placement.c	6 Oct 2004 16:27:47 -0000
@@ -1456,7 +1456,7 @@
 		{
 			reason->desk.do_switch_desk = 1;
 		}
-		goto_desk(fw->Desk);
+		goto_desk(fw->Desk, 0);
 	}
 	/* Don't move viewport if SkipMapping, or if recapturing the window,
 	 * adjust the coordinates later. Otherwise, just switch to the target
Index: fvwm/session.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/session.c,v
retrieving revision 1.126
diff -u -r1.126 session.c
--- fvwm/session.c	8 Jul 2004 14:54:16 -0000	1.126
+++ fvwm/session.c	6 Oct 2004 16:27:47 -0000
@@ -1125,7 +1125,7 @@
 		else if (!strcmp(s1, "[DESKTOP]"))
 		{
 			sscanf(s, "%*s %i", &i1);
-			goto_desk(i1);
+			goto_desk(i1, 0);
 		}
 		else if (!strcmp(s1, "[VIEWPORT]"))
 		{
Index: fvwm/virtual.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/virtual.c,v
retrieving revision 1.172
diff -u -r1.172 virtual.c
--- fvwm/virtual.c	30 Sep 2004 17:45:52 -0000	1.172
+++ fvwm/virtual.c	6 Oct 2004 16:27:47 -0000
@@ -85,12 +85,63 @@
 static unsigned int prev_desk_and_page_page_x = 0;
 static unsigned int prev_desk_and_page_page_y = 0;
 
+typedef struct
+{
+    int desk;
+    unsigned int page_x, page_y;
+} desk_pos;
+
+static desk_pos* desk_positions;
+static int desk_position_count = 0;
+
 /* ---------------------------- exported variables (globals) --------------- */
 
 /* ---------------------------- local functions ---------------------------- */
 
 /*
  *
+ * Gets the viewport coordinates within a desktop
+ * returns 1 if found, 0 if not found
+ *
+ */
+static int get_desk_position(int desk, unsigned int *x, unsigned int *y)
+{
+    int i;
+    for (i = 0; i < desk_position_count; i++) {
+	if (desk_positions[i].desk == desk) {
+	    *x = desk_positions[i].page_x;
+	    *y = desk_positions[i].page_y;
+	    return 1;
+	}
+    }
+    return 0;
+}
+
+/*
+ *
+ * Stores the viewport coordinates within a desktop
+ *
+ */
+static void set_desk_position(int desk, unsigned int x, unsigned int y)
+{
+    int i;
+    for (i = 0; i < desk_position_count; i++) {
+	if (desk_positions[i].desk == desk) {
+	    desk_positions[i].page_x = x;
+	    desk_positions[i].page_y = y;
+	    return;
+	}
+    }
+    desk_positions = (desk_pos*)realloc(desk_positions, (desk_position_count + 1)*sizeof(desk_pos));
+    desk_positions[desk_position_count].desk = desk;
+    desk_positions[desk_position_count].page_x = x;
+    desk_positions[desk_position_count].page_y = y;
+    desk_position_count++;
+    return;
+}
+
+/*
+ *
  * Parse arguments for "Desk" and "MoveToDesk" (formerly "WindowsDesk"):
  *
  * (nil)       : desk number = current desk
@@ -1072,6 +1123,7 @@
 		prev_desk_and_page_page_x = Scr.Vx;
 		prev_desk_and_page_page_y = Scr.Vy;
 		prev_desk_and_page_desk = Scr.CurrentDesk;
+		set_desk_position(Scr.CurrentDesk, Scr.Vx, Scr.Vy);
 	}
 	Scr.Vx = newx;
 	Scr.Vy = newy;
@@ -1234,19 +1286,24 @@
 	return;
 }
 
-void goto_desk(int desk)
+void goto_desk(int desk, int prevpage)
 {
 	/* RBW - the unmapping operations are now removed to their own
 	 * functions so they can also be used by the new GoToDeskAndPage
 	 * command. */
 	if (Scr.CurrentDesk != desk)
 	{
+  	        int px, py;
 		prev_desk = Scr.CurrentDesk;
 		prev_desk_and_page_desk = Scr.CurrentDesk;
 		prev_desk_and_page_page_x = Scr.Vx;
 		prev_desk_and_page_page_y = Scr.Vy;
+		set_desk_position(Scr.CurrentDesk, Scr.Vx, Scr.Vy);
 		UnmapDesk(Scr.CurrentDesk, True);
 		Scr.CurrentDesk = desk;
+		if (prevpage && get_desk_position(Scr.CurrentDesk, &px, &py)) {
+		        MoveViewport(px, py, True);
+		}
 		MapDesk(desk, True);
 		focus_grab_buttons_all();
 		BroadcastPacket(M_NEW_DESK, 1, Scr.CurrentDesk);
@@ -1929,7 +1986,7 @@
  */
 void CMD_GotoDesk(F_CMD_ARGS)
 {
-	goto_desk(GetDeskNumber(action, Scr.CurrentDesk));
+	goto_desk(GetDeskNumber(action, Scr.CurrentDesk), 0);
 
 	return;
 }
@@ -1941,6 +1998,13 @@
 	return;
 }
 
+void CMD_GotoDeskPrevPage(F_CMD_ARGS)
+{
+	goto_desk(GetDeskNumber(action, Scr.CurrentDesk), 1);
+
+	return;
+}
+
 /*
  *
  * Move to a new desktop and page at the same time.
@@ -1978,6 +2042,7 @@
 	}
 	prev_desk_and_page_page_x = Scr.Vx;
 	prev_desk_and_page_page_y = Scr.Vy;
+	set_desk_position(Scr.CurrentDesk, Scr.Vx, Scr.Vy);
 	MoveViewport(val[1], val[2], True);
 	if (is_new_desk)
 	{
Index: fvwm/virtual.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/virtual.h,v
retrieving revision 1.15
diff -u -r1.15 virtual.h
--- fvwm/virtual.h	29 Jun 2003 19:53:23 -0000	1.15
+++ fvwm/virtual.h	6 Oct 2004 16:27:47 -0000
@@ -12,7 +12,7 @@
 void initPanFrames(void);
 Bool is_pan_frame(Window w);
 void MoveViewport(int newx, int newy,Bool);
-void goto_desk(int desk);
+void goto_desk(int desk, int prevpage);
 void do_move_window_to_desk(FvwmWindow *fw, int desk);
 Bool get_page_arguments(char *action, int *page_x, int *page_y);
 char *GetDesktopName(int desk);