]> git.sur5r.net Git - i3/i3/commitdiff
Implement 'workspace back_and_forth' (Patch by Michael Walle)
authorMichael Stapelberg <michael@stapelberg.de>
Mon, 17 Oct 2011 22:17:56 +0000 (23:17 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Mon, 17 Oct 2011 22:17:56 +0000 (23:17 +0100)
docs/userguide
include/config.h
include/workspace.h
src/cfgparse.l
src/cfgparse.y
src/cmdparse.l
src/cmdparse.y
src/workspace.c

index 27e3b9ed67b3c8fb34920295fd0c90df9ebd0353..e12d8b6ead9f831058816fa89dc5f5e98241c12e 100644 (file)
@@ -737,6 +737,25 @@ force_xinerama yes
 Also note that your output names are not descriptive (like +HDMI1+) when using
 Xinerama, instead they are counted up, starting at 0: +xinerama-0+, +xinerama-1+, …
 
+=== Automatic back-and-forth when switching to the current workspace
+
+This configuration directive enables automatic +workspace back_and_forth+ (see
+<<back_and_forth>>) when switching to the workspace that is currently focused.
+
+For instance: Assume you are on workspace "1: www" and switch to "2: IM" using
+mod+2 because somebody sent you a message. You don’t need to remember where you
+came from now, you can just press mod+2 again to switch back to "1: www".
+
+*Syntax*:
+--------------------------------------
+workspace_auto_back_and_forth <yes|no>
+--------------------------------------
+
+*Example*:
+---------------------------------
+workspace_auto_back_and_forth yes
+---------------------------------
+
 == List of commands
 
 Commands are what you bind to specific keypresses. You can also issue commands
@@ -892,6 +911,10 @@ workspace 1, 3, 4 and 9 and you want to cycle through them with a single key
 combination. Similarily, you can use +move workspace next+ and +move workspace
 prev+ to move a container to the next/previous workspace.
 
+[[back_and_forth]]
+To switch back to the previously focused workspace, use +workspace
+back_and_forth+.
+
 To move a container to another xrandr output such as +LVDS1+ or +VGA1+, you can
 use the +move output+ command followed by the name of the target output. You
 may also use +left+, +right+, +up+, +down+ instead of the xrandr output name to
@@ -906,6 +929,9 @@ bindsym mod+2 workspace 2
 bindsym mod+Shift+1 move workspace 1
 bindsym mod+Shift+2 move workspace 2
 ...
+
+# switch between the current and the previously focused one
+bindsym mod+b workspace back_and_forth
 -------------------------
 
 ==== Named workspaces
index 07391a6af6458e4e02d1dfad3c11cf85992f6807..337db8fbac850ac7def371534e66042e0c2b5474 100644 (file)
@@ -133,6 +133,12 @@ struct Config {
          * is fetched once and never updated. */
         bool force_xinerama;
 
+        /** Automatic workspace back and forth switching. If this is set, a
+         * switch to the currently active workspace will switch to the
+         * previously focused one instead, making it possible to fast toggle
+         * between two workspaces. */
+        bool workspace_auto_back_and_forth;
+
         /** The default border style for new windows. */
         border_style_t default_border;
 
index 3f0e83c28f62fc263c623ebc4809a4a9a4d4509e..1dce680ad9252f3d95d296f93e33f3ed93fa1674 100644 (file)
@@ -70,6 +70,13 @@ Con* workspace_next();
  */
 Con* workspace_prev();
 
+/**
+ * Focuses the previously focused workspace.
+ *
+ */
+void workspace_back_and_forth();
+
+
 #if 0
 /**
  * Assigns the given workspace to the given screen by correctly updating its
index 49714401b512ecaf0a49ff2f1ae0e36fb0d60930..622a133b36cf00fb221229c02cf9f4df8216d7f5 100644 (file)
@@ -127,6 +127,7 @@ none                            { return TOK_NONE; }
 focus_follows_mouse             { return TOKFOCUSFOLLOWSMOUSE; }
 force_focus_wrapping            { return TOK_FORCE_FOCUS_WRAPPING; }
 force_xinerama                  { return TOK_FORCE_XINERAMA; }
+workspace_auto_back_and_forth   { return TOK_WORKSPACE_AUTO_BAF; }
 workspace_bar                   { return TOKWORKSPACEBAR; }
 popup_during_fullscreen         { return TOK_POPUP_DURING_FULLSCREEN; }
 ignore                          { return TOK_IGNORE; }
index 9a417f2aba0b54aeb65cd059f9947d756e617c6d..6869eee7ee187d9645392c4f85cf9b972baeb785 100644 (file)
@@ -623,6 +623,7 @@ void parse_file(const char *f) {
 %token                  TOKFOCUSFOLLOWSMOUSE        "focus_follows_mouse"
 %token                  TOK_FORCE_FOCUS_WRAPPING    "force_focus_wrapping"
 %token                  TOK_FORCE_XINERAMA          "force_xinerama"
+%token                  TOK_WORKSPACE_AUTO_BAF      "workspace_auto_back_and_forth"
 %token                  TOKWORKSPACEBAR             "workspace_bar"
 %token                  TOK_DEFAULT                 "default"
 %token                  TOK_STACKING                "stacking"
@@ -679,6 +680,7 @@ line:
     | focus_follows_mouse
     | force_focus_wrapping
     | force_xinerama
+    | workspace_back_and_forth
     | workspace_bar
     | workspace
     | assign
@@ -1035,6 +1037,14 @@ force_xinerama:
     }
     ;
 
+workspace_back_and_forth:
+    TOK_WORKSPACE_AUTO_BAF bool
+    {
+        DLOG("automatic workspace back-and-forth = %d\n", $2);
+        config.workspace_auto_back_and_forth = $2;
+    }
+    ;
+
 workspace_bar:
     TOKWORKSPACEBAR bool
     {
index f6b132ca113cd66cb4dd2a5f63d5ddff39415443..6dda34d0ae446078a9c51995f04583cbfdd701b9 100644 (file)
@@ -72,10 +72,11 @@ EOL (\r?\n)
     cmdyycolumn = 1;
 }
 
-    /* the next/prev tokens are here to recognize them *before* handling
-     * strings ('workspace' command) */
+    /* the next/prev/back_and_forth tokens are here to recognize them *before*
+     * handling strings ('workspace' command) */
 next                            { return TOK_NEXT; }
 prev                            { return TOK_PREV; }
+back_and_forth                  { return TOK_BACK_AND_FORTH; }
 
 <WANT_STRING>\"[^\"]+\"         {
                                   BEGIN(INITIAL);
index ecc4bc020070af1b9bbcf2bdfdeb06fd0af6a7d2..a43d2be0defc5ff16ef1cd2a339d9c298a718456 100644 (file)
@@ -174,6 +174,7 @@ bool definitelyGreaterThan(float a, float b, float epsilon) {
 %token              TOK_OR              "or"
 %token              TOK_PPT             "ppt"
 %token              TOK_NOP             "nop"
+%token              TOK_BACK_AND_FORTH  "back_and_forth"
 
 %token              TOK_CLASS           "class"
 %token              TOK_INSTANCE        "instance"
@@ -587,9 +588,28 @@ workspace:
         workspace_show(workspace_prev());
         tree_render();
     }
+    | TOK_WORKSPACE TOK_BACK_AND_FORTH
+    {
+        workspace_back_and_forth();
+        tree_render();
+    }
     | TOK_WORKSPACE STR
     {
         printf("should switch to workspace %s\n", $2);
+
+        Con *ws = con_get_workspace(focused);
+
+        /* Check if the command wants to switch to the current workspace */
+        if (strcmp(ws->name, $2) == 0) {
+            printf("This workspace is already focused.\n");
+            if (config.workspace_auto_back_and_forth) {
+                workspace_back_and_forth();
+                free($2);
+                tree_render();
+            }
+            break;
+        }
+
         workspace_show_by_name($2);
         free($2);
 
index b4ed5530108268fcd31df78241087f9796a62a5c..e06dbde5664e2b545114e92fee48961702c6cca9 100644 (file)
@@ -2,13 +2,17 @@
  * vim:ts=4:sw=4:expandtab
  *
  * i3 - an improved dynamic tiling window manager
- * © 2009-2010 Michael Stapelberg and contributors (see also: LICENSE)
+ * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
  *
  * workspace.c: Functions for modifying workspaces
  *
  */
 #include "all.h"
 
+/* Stores a copy of the name of the last used workspace for the workspace
+ * back-and-forth switching. */
+static char *previous_workspace_name = NULL;
+
 /*
  * Returns a pointer to the workspace with the given number (starting at 0),
  * creating the workspace if necessary (by allocating the necessary amount of
@@ -191,11 +195,20 @@ static void _workspace_show(Con *workspace, bool changed_num_workspaces) {
     /* enable fullscreen for the target workspace. If it happens to be the
      * same one we are currently on anyways, we can stop here. */
     workspace->fullscreen_mode = CF_OUTPUT;
-    if (workspace == con_get_workspace(focused)) {
+    current = con_get_workspace(focused);
+    if (workspace == current) {
         DLOG("Not switching, already there.\n");
         return;
     }
 
+    /* Remember currently focused workspace for switching back to it later with
+     * the 'workspace back_and_forth' command.
+     * NOTE: We have to duplicate the name as the original will be freed when
+     * the corresponding workspace is cleaned up. */
+
+    FREE(previous_workspace_name);
+    previous_workspace_name = sstrdup(current->name);
+
     workspace_reassign_sticky(workspace);
 
     LOG("switching to %p\n", workspace);
@@ -368,6 +381,19 @@ workspace_prev_end:
     return prev;
 }
 
+/*
+ * Focuses the previously focused workspace.
+ *
+ */
+void workspace_back_and_forth() {
+    if (!previous_workspace_name) {
+        DLOG("No previous workspace name set. Not switching.");
+        return;
+    }
+
+    workspace_show_by_name(previous_workspace_name);
+}
+
 static bool get_urgency_flag(Con *con) {
     Con *child;
     TAILQ_FOREACH(child, &(con->nodes_head), nodes)