]> git.sur5r.net Git - i3/i3/commitdiff
Bugfix: with one ws per output, don’t crash on cross-output moves (Thanks moju)
authorMichael Stapelberg <michael@stapelberg.de>
Fri, 28 Sep 2012 21:04:37 +0000 (23:04 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Fri, 28 Sep 2012 21:04:37 +0000 (23:04 +0200)
fixes #827

src/commands.c
src/workspace.c
testcases/t/507-workspace-move-crash.t [new file with mode: 0644]

index 070f635373971d56d2ad079e9e3786c6f05dd32b..0263802fe4551c77c858f0397679e4aa112de4ca 100644 (file)
@@ -1158,6 +1158,7 @@ void cmd_move_workspace_to_output(I3_CMD, char *name) {
             /* notify the IPC listeners */
             ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"init\"}");
         }
+        DLOG("Detaching\n");
 
         /* detach from the old output and attach to the new output */
         Con *old_content = ws->parent;
@@ -1182,10 +1183,21 @@ void cmd_move_workspace_to_output(I3_CMD, char *name) {
             workspace_show(ws);
         }
 
-        /* Call the on_remove_child callback of the workspace which previously
-         * was visible on the destination output. Since it is no longer
-         * visible, it might need to get cleaned up. */
-        CALL(previously_visible_ws, on_remove_child);
+        /* NB: We cannot simply work with previously_visible_ws since it might
+         * have been cleaned up by workspace_show() already, depending on the
+         * focus order/number of other workspaces on the output.
+         * Instead, we loop through the available workspaces and only work with
+         * previously_visible_ws if we still find it. */
+        TAILQ_FOREACH(ws, &(content->nodes_head), nodes) {
+            if (ws != previously_visible_ws)
+                continue;
+
+            /* Call the on_remove_child callback of the workspace which previously
+             * was visible on the destination output. Since it is no longer
+             * visible, it might need to get cleaned up. */
+            CALL(previously_visible_ws, on_remove_child);
+            break;
+        }
     }
 
     cmd_output->needs_tree_render = true;
index 3a5844cb8c1794d1adbe50e6e713046d582739d0..14840e4a985941e706ae4b559debceae86eee3ce 100644 (file)
@@ -365,7 +365,7 @@ static void _workspace_show(Con *workspace) {
 
     workspace_reassign_sticky(workspace);
 
-    LOG("switching to %p\n", workspace);
+    DLOG("switching to %p / %s\n", workspace, workspace->name);
     Con *next = con_descend_focused(workspace);
 
     /* Memorize current output */
@@ -400,6 +400,7 @@ static void _workspace_show(Con *workspace) {
     } else
         con_focus(next);
 
+    DLOG("old = %p / %s\n", old, (old ? old->name : "(null)"));
     /* Close old workspace if necessary. This must be done *after* doing
      * urgency handling, because tree_close() will do a con_focus() on the next
      * client, which will clear the urgency flag too early. Also, there is no
diff --git a/testcases/t/507-workspace-move-crash.t b/testcases/t/507-workspace-move-crash.t
new file mode 100644 (file)
index 0000000..9e80553
--- /dev/null
@@ -0,0 +1,48 @@
+#!perl
+# vim:ts=4:sw=4:expandtab
+#
+# Please read the following documents before working on tests:
+# • http://build.i3wm.org/docs/testsuite.html
+#   (or docs/testsuite)
+#
+# • http://build.i3wm.org/docs/lib-i3test.html
+#   (alternatively: perldoc ./testcases/lib/i3test.pm)
+#
+# • http://build.i3wm.org/docs/ipc.html
+#   (or docs/ipc)
+#
+# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
+#   (unless you are already familiar with Perl)
+#
+# Tests whether i3 crashes on cross-output moves with one workspace per output.
+# Ticket: #827
+# Bug still in: 4.3-78-g66b389c
+#
+use List::Util qw(first);
+use i3test i3_autostart => 0;
+
+# Ensure the pointer is at (0, 0) so that we really start on the first
+# (the left) workspace.
+$x->root->warp_pointer(0, 0);
+
+my $config = <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+
+fake-outputs 1024x768+0+0,1024x768+1024+0
+EOT
+my $pid = launch_with_config($config);
+
+################################################################################
+# Setup workspaces so that they stay open (with an empty container).
+################################################################################
+
+is(focused_ws, '1', 'starting on workspace 1');
+
+cmd 'move workspace to output fake-1';
+
+does_i3_live;
+
+exit_gracefully($pid);
+
+done_testing;