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);

Reply via email to