i3 - improved tiling WM


Better back_and_forth handling with multimonitor setups

Patch status: rejected

Patch by Sebastian Rachuj

To apply this patch, use:
curl http://cr.i3wm.org/patch/74/raw.patch | git am

b/src/workspace.c

13
@@ -19,6 +19,11 @@
14
  * back-and-forth switching. */
15
 static char *previous_workspace_name = NULL;
16
 
17
+/* Stores a copy of the name of the last displaced workspace. This means
18
+ * that the workspace did not have a focus when it lost visibility.
19
+ * Can be used for Bug #927. */
20
+static char *displaced_workspace_name = NULL;
21
+
22
 /*
23
  * Sets ws->layout to splith/splitv if default_orientation was specified in the
24
  * configfile. Otherwise, it uses splith/splitv depending on whether the output
25
@@ -376,12 +381,29 @@ static void _workspace_show(Con *workspace) {
26
 
27
     /* disable fullscreen for the other workspaces and get the workspace we are
28
      * currently on. */
29
+    /* Additionally remember the workspace name of the workspace that was on 
30
+     * another output and was displaced. */
31
+    bool changed_displaced = false;
32
     TAILQ_FOREACH(current, &(workspace->parent->nodes_head), nodes) {
33
+        if (workspace_is_visible(current) && !con_is_internal(current) &&
34
+            con_get_output(focused) != con_get_output(workspace)) {
35
+            FREE(displaced_workspace_name);
36
+            displaced_workspace_name = sstrdup(current->name);
37
+            changed_displaced = true;
38
+            DLOG("Setting displaced_workspace_name = %s\n", displaced_workspace_name);
39
+        }
40
         if (current->fullscreen_mode == CF_OUTPUT)
41
             old = current;
42
         current->fullscreen_mode = CF_NONE;
43
     }
44
 
45
+    /* If there was no workspace displaced, we did not write anything to
46
+     * the string and can therefore remove the old information. */
47
+    if (!changed_displaced) {
48
+        FREE(displaced_workspace_name);
49
+        DLOG("Freeing displaced_workspace_name\n");
50
+    }
51
+
52
     /* enable fullscreen for the target workspace. If it happens to be the
53
      * same one we are currently on anyways, we can stop here. */
54
     workspace->fullscreen_mode = CF_OUTPUT;
55
@@ -754,7 +776,17 @@ void workspace_back_and_forth(void) {
56
         return;
57
     }
58
 
59
-    workspace_show_by_name(previous_workspace_name);
60
+    /* Save the real workspace in case we show the displaced workspace
61
+     * first. */
62
+    char* real_prev = sstrdup(previous_workspace_name);
63
+
64
+    /* With the last workspace change there was workspace displaced.
65
+     * Show it before showing the real previous workspace. */
66
+    if (displaced_workspace_name)
67
+        workspace_show_by_name(displaced_workspace_name);
68
+
69
+    workspace_show_by_name(real_prev);
70
+    FREE(real_prev);
71
 }
72
 
73
 /*