This patch introduces a new feature called "SaveWorkspaceFocus", which
when enabled, makes ctwm remember which window has the focus within
each virtual workspace. As you switch workspaces, the cursor is
automatically warped to the window previous in focus in the workspace.
This significantly reduces the amount of mouse use.

Here is the documentation addition (from the patch):

  When changing to a workspace, restore the focus to the last window
  that had the focus when you left the workspace by warping the mouse
  into it. This essentially saves the focus window with the workspace
  and restores it automatically when you switch. In many cases, it
  avoids having to reach for the mouse after moving to a new workspace.


(Please review and/or merge.)
--- ctwm-3.8a/ctwm.man	2007-02-16 04:24:27.000000000 -0500
+++ ctwm-3.8a.blais/ctwm.man	2007-10-21 21:12:27.000000000 -0400
@@ -1281,6 +1281,13 @@
 .IP "\fBSloppyFocus\fP" 8
 Use sloppy focus.
 
+.IP "\fBSaveWorkspaceFocus\fP" 8
+When changing to a workspace, restore the focus to the last window
+that had the focus when you left the workspace by warping the mouse
+into it. This essentially saves the focus window with the workspace
+and restores it automatically when you switch. In many cases, it
+avoids having to reach for the mouse after moving to a new workspace.
+
 .IP "\fBSortIconManager\fP" 8
 This variable indicates that entries in the icon manager should be
 sorted alphabetically rather than by simply appending new windows to
--- ctwm-3.8a/screen.h	2007-02-16 04:24:27.000000000 -0500
+++ ctwm-3.8a.blais/screen.h	2007-10-21 20:35:13.000000000 -0400
@@ -428,6 +428,7 @@
     short WarpToDefaultMenuEntry; /* warp cursor to default menu entry, if any  */
     short ClickToFocus;		/* click to focus */
     short SloppyFocus;		/* "sloppy" focus */
+    short SaveWorkspaceFocus;	/* Save and restore focus on workspace change. */
     short NoIconManagers;	/* Don't create any icon managers */
     short ClientBorderWidth;	/* respect client window border width */
     short SqueezeTitle;		/* make title as small as possible */
--- ctwm-3.8a/workmgr.h	2007-02-16 04:24:28.000000000 -0500
+++ ctwm-3.8a.blais/workmgr.h	2007-10-21 20:35:49.000000000 -0400
@@ -93,6 +93,7 @@
   IconMgr             *iconmgr;
   ColorPair           cp;
   ColorPair           backcp;
+  TwmWindow	      *save_focus;  /* Used by SaveWorkspaceFocus feature */
   struct WindowRegion *FirstWindowRegion;
   struct WorkSpace *next;
 };
--- ctwm-3.8a/workmgr.c	2007-10-21 19:48:42.000000000 -0400
+++ ctwm-3.8a.blais/workmgr.c	2007-10-21 21:06:14.000000000 -0400
@@ -472,6 +472,12 @@
 	    XSetWindowBackgroundPixmap (dpy, vs->window, newws->image->pixmap);
 	XClearWindow (dpy, vs->window);
     }
+
+    /* If SaveWorkspaceFocus is on, save the focus of the last window. */
+    if ( Scr->SaveWorkspaceFocus ) {
+        oldws->save_focus = Scr->Focus;
+    }
+
     focuswindow = (TwmWindow*)0;
     for (twmWin = &(Scr->TwmRoot); twmWin != NULL; twmWin = twmWin->next) {
 	if (twmWin->vs == vs) {
@@ -485,11 +491,12 @@
 		break;
 	      }
 	    }
-	  } else
+	  } /*else
 	    if (twmWin->hasfocusvisible) {
 	      focuswindow = twmWin;
 	      SetFocusVisualAttributes (focuswindow, False);
 	    }
+            */
 	}
     }
     /* Move to the end of the twmWin list */
@@ -528,9 +535,11 @@
 	}
     }	
     CurrentIconManagerEntry (wl);
+    /*
     if (focuswindow) {
 	SetFocusVisualAttributes (focuswindow, True);
     }
+    */
     vs->wsw->currentwspc = newws;
     if (Scr->ReverseCurrentWorkspace && vs->wsw->state == MAPSTATE) {
         MapSubwindow *msw = vs->wsw->mswl [oldws->number];
@@ -611,10 +620,20 @@
 			   (Window) 0, (TwmWindow*) 0, &event, C_ROOT, FALSE);
     }
 
-    /* keep track of the order of the workspaces across restarts */
-    CtwmSetVScreenMap(dpy, Scr->Root, Scr->vScreenList);
+    /* If SaveWorkspaceFocus is on, try to restore the focus to the last
+       window which was focused when we left this workspace. */
+    if ( Scr->SaveWorkspaceFocus && newws->save_focus) {
+        for (twmWin = &(Scr->TwmRoot); twmWin != NULL; twmWin = twmWin->next) {
+            if (twmWin == newws->save_focus) {
+                WarpToWindow(twmWin);
+            }
+        }
+    }
+
+/*     /\* keep track of the order of the workspaces across restarts *\/ */
+/*     CtwmSetVScreenMap(dpy, Scr->Root, Scr->vScreenList); */
 
-    XSync (dpy, 0);
+/*     XSync (dpy, 0); */
     if (Scr->ClickToFocus || Scr->SloppyFocus) set_last_window (newws);
     MaybeAnimate = True;
 }
@@ -652,6 +671,7 @@
     ws->label = (char*) strdup (name);
 #endif
     ws->clientlist = NULL;
+    ws->save_focus = NULL;
 
     if (background == NULL)
 	ws->cp.back = Scr->IconManagerC.back;
--- ctwm-3.8a/ctwm.c	2007-02-16 04:24:27.000000000 -0500
+++ ctwm-3.8a.blais/ctwm.c	2007-10-21 21:18:54.000000000 -0400
@@ -1028,6 +1028,7 @@
     Scr->WarpToDefaultMenuEntry = FALSE;
     Scr->ClickToFocus = FALSE;
     Scr->SloppyFocus = FALSE;
+    Scr->SaveWorkspaceFocus = FALSE;
     Scr->NoIconTitlebar = FALSE;
     Scr->NoTitlebar = FALSE;
     Scr->DecorateTransients = FALSE;
--- ctwm-3.8a/parse.c	2007-02-16 04:24:27.000000000 -0500
+++ ctwm-3.8a.blais/parse.c	2007-10-21 21:33:42.000000000 -0400
@@ -636,6 +636,7 @@
 #define kw0_SloppyFocus                 63
 #define kw0_NoImagesInWorkSpaceManager  64
 #define kw0_NoWarpToMenuTitle           65
+#define kw0_SaveWorkspaceFocus          66 /* blais */
 
 #define kws_UsePPosition		1
 #define kws_IconFont			2
@@ -1024,6 +1025,7 @@
     { "root",			ROOT, 0 },
     { "s",			SHIFT, 0 },
     { "savecolor",              SAVECOLOR, 0},
+    { "saveworkspacefocus",     KEYWORD, kw0_SaveWorkspaceFocus },
     { "schrinkicontitles",	KEYWORD, kw0_ShrinkIconTitles },
     { "select",			SELECT, 0 },
     { "shift",			SHIFT, 0 },
@@ -1367,6 +1369,10 @@
 	Scr->SloppyFocus = TRUE;
 	return 1;
 
+      case kw0_SaveWorkspaceFocus:
+	Scr->SaveWorkspaceFocus = TRUE;
+	return 1;
+
       case kw0_NoImagesInWorkSpaceManager:
 	Scr->NoImagesInWorkSpaceManager = TRUE;
 	return 1;

Reply via email to