i3 - improved tiling WM


Fix output retrieval for floating cons

Patch status: merged

Patch by jj

Long description:

When focusing/moving to outputs, the method of getting the correct
output for a given container fails if the container in question is
floating and only partially mapped on an output screen. This patch
introduces a fail-safe retrieval of the output for any container.

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

b/src/commands.c

18
@@ -78,6 +78,17 @@ static Output *get_output_from_string(Output *current_output, const char *output
19
 }
20
 
21
 /*
22
+ * Returns the output containing the given container.
23
+ */
24
+static Output *get_output_of_con(Con *con) {
25
+    Con *output_con = con_get_output(con);
26
+    Output *output = get_output_by_name(output_con->name);
27
+    assert(output != NULL);
28
+
29
+    return output;
30
+}
31
+
32
+/*
33
  * Checks whether we switched to a new workspace and returns false in that case,
34
  * signaling that further workspace switching should be done by the calling function
35
  * If not, calls workspace_back_and_forth() if workspace_auto_back_and_forth is set
36
@@ -1049,7 +1060,7 @@ void cmd_move_con_to_output(I3_CMD, char *name) {
37
 
38
     // TODO: fix the handling of criteria
39
     TAILQ_FOREACH(current, &owindows, owindows)
40
-        current_output = get_output_containing(current->con->rect.x, current->con->rect.y);
41
+        current_output = get_output_of_con(current->con);
42
 
43
     assert(current_output != NULL);
44
 
45
@@ -1131,8 +1142,7 @@ void cmd_move_workspace_to_output(I3_CMD, char *name) {
46
 
47
     owindow *current;
48
     TAILQ_FOREACH(current, &owindows, owindows) {
49
-        Output *current_output = get_output_containing(current->con->rect.x,
50
-                                                       current->con->rect.y);
51
+        Output *current_output = get_output_of_con(current->con);
52
         if (!current_output) {
53
             ELOG("Cannot get current output. This is a bug in i3.\n");
54
             ysuccess(false);
55
@@ -1672,7 +1682,7 @@ void cmd_focus_output(I3_CMD, char *name) {
56
     Output *output;
57
 
58
     TAILQ_FOREACH(current, &owindows, owindows)
59
-        current_output = get_output_containing(current->con->rect.x, current->con->rect.y);
60
+        current_output = get_output_of_con(current->con);
61
     assert(current_output != NULL);
62
 
63
     output = get_output_from_string(current_output, name);

b/testcases/t/502-focus-output.t

68
@@ -71,6 +71,23 @@ is(focused_output, 'fake-1', 'focus on second output');
69
 cmd 'focus output fake-0';
70
 is(focused_output, 'fake-0', 'focus on first output');
71
 
72
+################################################################################
73
+# use 'focus output' and verify that i3 does not crash when the currently
74
+# focused window is floating and is only partially mapped on an output screen
75
+################################################################################
76
+
77
+is(focused_output, 'fake-0', 'focus on first output');
78
+
79
+my $floating_win = open_window;
80
+cmd 'floating toggle';
81
+cmd 'move to absolute position -10 -10';
82
+
83
+cmd 'focus output right';
84
+is(focused_output, 'fake-1', 'focus on second output');
85
+
86
+cmd 'focus output fake-0';
87
+is(focused_output, 'fake-0', 'focus on first output');
88
+
89
 exit_gracefully($pid);
90
 
91
 done_testing;