]> git.sur5r.net Git - i3/i3/commitdiff
fixes #776
authorchrysn <chrysn@fsfe.org>
Tue, 4 Sep 2012 08:51:18 +0000 (10:51 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Sat, 22 Sep 2012 11:35:31 +0000 (13:35 +0200)
this implements both the "move container to workspace back_and_forth" command
and movements to the same workspace when auto_back_and_forth is set.

it includes documentation and test suite additions by michael.

it also simplifies the workspace_show_by_name function (making use of
workspace_get accepting NULL pointers).

docs/userguide
include/commands.h
include/workspace.h
parser-specs/commands.spec
src/commands.c
src/workspace.c
testcases/t/176-workspace-baf.t

index 2214f016522764598a3f7517cee285cf735c228e..525cfd77dbcae19c4272ace93486e785bc349d0c 100644 (file)
@@ -1395,7 +1395,8 @@ RandR output.
 
 [[back_and_forth]]
 To switch back to the previously focused workspace, use +workspace
-back_and_forth+.
+back_and_forth+; likewise, you can move containers to the previously focused
+workspace using +move container to workspace back_and_forth+.
 
 *Syntax*:
 -----------------------------------
@@ -1421,6 +1422,7 @@ bindsym mod+Shift+2 move container to workspace 2
 
 # switch between the current and the previously focused one
 bindsym mod+b workspace back_and_forth
+bindsym mod+Shift+b move container to workspace back_and_forth
 
 # move the whole workspace to the next output
 bindsym mod+x move workspace to output right
index c971bb48de7f28e4f8602b4d3dd5191aec8f3fc5..43bd0b0ae831343d4786810cac163ae31b1c6eac 100644 (file)
@@ -55,6 +55,12 @@ void cmd_criteria_add(I3_CMD, char *ctype, char *cvalue);
  */
 void cmd_move_con_to_workspace(I3_CMD, char *which);
 
+/**
+ * Implementation of 'move [window|container] [to] workspace back_and_forth'.
+ *
+ */
+void cmd_move_con_to_workspace_back_and_forth(I3_CMD);
+
 /**
  * Implementation of 'move [window|container] [to] workspace <name>'.
  *
index ad780f1f2013146c86e93f5925d51fed78d125b3..a7f2d13bd1ba47932f466b1aba5d41926543134e 100644 (file)
@@ -95,6 +95,12 @@ Con* workspace_prev_on_output(void);
  */
 void workspace_back_and_forth(void);
 
+/**
+ * Returns the previously focused workspace con, or NULL if unavailable.
+ *
+ */
+Con *workspace_back_and_forth_get(void);
+
 
 #if 0
 /**
index b4c9e005bd8ab16583bae3ef2dc8aeab8984f1f9..2c46e66c0b7d797ff5295c76d73303a6527e70e9 100644 (file)
@@ -243,6 +243,8 @@ state MOVE_WORKSPACE:
       -> MOVE_WORKSPACE_TO_OUTPUT
   workspace = 'next', 'prev', 'next_on_output', 'prev_on_output', 'current'
       -> call cmd_move_con_to_workspace($workspace)
+  'back_and_forth'
+      -> call cmd_move_con_to_workspace_back_and_forth()
   'number'
       -> MOVE_WORKSPACE_NUMBER
   workspace = string
index 2d8fce3cc410cf7802eb2a72c280cdbc1b238553..34f0f9db97f5da72a4e042da4addc7bf383f8fe9 100644 (file)
@@ -99,6 +99,29 @@ static bool maybe_back_and_forth(struct CommandResult *cmd_output, char *name) {
     return true;
 }
 
+/*
+ * Return the passed workspace unless it is the current one and auto back and
+ * forth is enabled, in which case the back_and_forth workspace is returned.
+ */
+static Con *maybe_auto_back_and_forth_workspace(Con *workspace) {
+    Con *current, *baf;
+
+    if (!config.workspace_auto_back_and_forth)
+        return workspace;
+
+    current = con_get_workspace(focused);
+
+    if (current == workspace) {
+        baf = workspace_back_and_forth_get();
+        if (baf != NULL) {
+            DLOG("Substituting workspace with back_and_forth, as it is focused.\n");
+            return baf;
+        }
+    }
+
+    return workspace;
+}
+
 // This code is commented out because we might recycle it for popping up error
 // messages on parser errors.
 #if 0
@@ -400,6 +423,38 @@ void cmd_move_con_to_workspace(I3_CMD, char *which) {
     ysuccess(true);
 }
 
+/**
+ * Implementation of 'move [window|container] [to] workspace back_and_forth'.
+ *
+ */
+void cmd_move_con_to_workspace_back_and_forth(I3_CMD) {
+    owindow *current;
+    Con *ws;
+
+    ws = workspace_back_and_forth_get();
+
+    if (ws == NULL) {
+        y(map_open);
+        ystr("success");
+        y(bool, false);
+        ystr("error");
+        ystr("No workspace was previously active.");
+        y(map_close);
+        return;
+    }
+
+    HANDLE_EMPTY_MATCH;
+
+    TAILQ_FOREACH(current, &owindows, owindows) {
+        DLOG("matching: %p / %s\n", current->con, current->con->name);
+        con_move_to_workspace(current->con, ws, true, false);
+    }
+
+    cmd_output->needs_tree_render = true;
+    // XXX: default reply for now, make this a better reply
+    ysuccess(true);
+}
+
 /*
  * Implementation of 'move [window|container] [to] workspace <name>'.
  *
@@ -432,6 +487,8 @@ void cmd_move_con_to_workspace_name(I3_CMD, char *name) {
     /* get the workspace */
     Con *ws = workspace_get(name, NULL);
 
+    ws = maybe_auto_back_and_forth_workspace(ws);
+
     HANDLE_EMPTY_MATCH;
 
     TAILQ_FOREACH(current, &owindows, owindows) {
@@ -489,6 +546,8 @@ void cmd_move_con_to_workspace_number(I3_CMD, char *which) {
         workspace = workspace_get(which, NULL);
     }
 
+    workspace = maybe_auto_back_and_forth_workspace(workspace);
+
     HANDLE_EMPTY_MATCH;
 
     TAILQ_FOREACH(current, &owindows, owindows) {
index 94efd47b6e2455cf0151f7a41b0366d9022aeed8..6f560ad9d4c0b4d71fed6938033cb5e6f49ae11a 100644 (file)
@@ -392,8 +392,7 @@ void workspace_show(Con *workspace) {
  */
 void workspace_show_by_name(const char *num) {
     Con *workspace;
-    bool changed_num_workspaces;
-    workspace = workspace_get(num, &changed_num_workspaces);
+    workspace = workspace_get(num, NULL);
     _workspace_show(workspace);
 }
 
@@ -664,6 +663,22 @@ void workspace_back_and_forth(void) {
     workspace_show_by_name(previous_workspace_name);
 }
 
+/*
+ * Returns the previously focused workspace con, or NULL if unavailable.
+ *
+ */
+Con *workspace_back_and_forth_get(void) {
+    if (!previous_workspace_name) {
+        DLOG("no previous workspace name set.");
+        return NULL;
+    }
+
+    Con *workspace;
+    workspace = workspace_get(previous_workspace_name, NULL);
+
+    return workspace;
+}
+
 static bool get_urgency_flag(Con *con) {
     Con *child;
     TAILQ_FOREACH(child, &(con->nodes_head), nodes)
index 07c3c84a1e8fe8c016ad0e68bb7bf33c2a229921..8ed33030818343e595db4cfcf9df558ad79b60b8 100644 (file)
@@ -47,6 +47,33 @@ ok(get_ws($second_ws)->{focused}, 'second workspace focused');
 cmd qq|workspace "$second_ws"|;
 ok(get_ws($second_ws)->{focused}, 'second workspace still focused');
 
+################################################################################
+# verify that 'move workspace back_and_forth' works as expected
+################################################################################
+
+cmd qq|workspace "$first_ws"|;
+my $first_win = open_window;
+
+cmd qq|workspace "$second_ws"|;
+my $second_win = open_window;
+
+is(@{get_ws_content($first_ws)}, 1, 'one container on ws 1 before moving');
+cmd 'move workspace back_and_forth';
+is(@{get_ws_content($first_ws)}, 2, 'two containers on ws 1 before moving');
+
+my $third_win = open_window;
+
+################################################################################
+# verify that moving to the current ws is a no-op without
+# workspace_auto_back_and_forth.
+################################################################################
+
+cmd qq|workspace "$first_ws"|;
+
+is(@{get_ws_content($second_ws)}, 1, 'one container on ws 2 before moving');
+cmd qq|move workspace "$first_ws"|;
+is(@{get_ws_content($second_ws)}, 1, 'still one container');
+
 exit_gracefully($pid);
 
 #####################################################################
@@ -72,6 +99,19 @@ ok(get_ws($third_ws)->{focused}, 'third workspace focused');
 
 cmd qq|workspace "$third_ws"|;
 ok(get_ws($second_ws)->{focused}, 'second workspace focused');
+$first_win = open_window;
+
+################################################################################
+# verify that moving to the current ws moves to the previous one with
+# workspace_auto_back_and_forth.
+################################################################################
+
+cmd qq|workspace "$first_ws"|;
+$second_win = open_window;
+
+is(@{get_ws_content($second_ws)}, 1, 'one container on ws 2 before moving');
+cmd qq|move workspace "$first_ws"|;
+is(@{get_ws_content($second_ws)}, 2, 'two containers on ws 2');
 
 ################################################################################
 # Now see if "workspace number <number>" also works as expected with