2 # vim:ts=4:sw=4:expandtab
4 # Please read the following documents before working on tests:
5 # • https://build.i3wm.org/docs/testsuite.html
8 # • https://build.i3wm.org/docs/lib-i3test.html
9 # (alternatively: perldoc ./testcases/lib/i3test.pm)
11 # • https://build.i3wm.org/docs/ipc.html
14 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
15 # (unless you are already familiar with Perl)
17 # Test if new containers get focused when there is a fullscreen container at
18 # the time of launching the new one. Also make sure that focusing containers
19 # in other workspaces work even when there is a fullscreen container.
21 use i3test i3_config => <<EOT;
23 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
25 fake-outputs 1024x768+0+0,1024x768+1024+0
27 # Screen setup looks like this:
32 my $tmp = fresh_workspace;
34 ################################################################################
35 # Open the left window.
36 ################################################################################
38 my $left = open_window({ background_color => '#ff0000' });
40 is($x->input_focus, $left->id, 'left window focused');
42 diag("left = " . $left->id);
44 ################################################################################
45 # Open the right window.
46 ################################################################################
48 my $right = open_window({ background_color => '#00ff00' });
50 diag("right = " . $right->id);
52 ################################################################################
53 # Set the right window to fullscreen.
54 ################################################################################
56 cmd 'nop setting fullscreen';
59 ################################################################################
60 # Open a third window. Since we're fullscreen, the window won't be # mapped, so
61 # don't wait for it to be mapped. Instead, just send the map request and sync
62 # with i3 to make sure i3 recognizes it.
63 ################################################################################
65 my $third = open_window({
66 background_color => '#0000ff',
67 name => 'Third window',
75 diag("third = " . $third->id);
77 ################################################################################
78 # Move the window to a different workspace, and verify that the third window now
79 # gets focused in the current workspace.
80 ################################################################################
82 my $tmp2 = get_unused_workspace;
84 cmd "move workspace $tmp2";
86 is($x->input_focus, $third->id, 'third window focused');
88 ################################################################################
89 # Ensure that moving a window to a workspace which has a fullscreen window does
90 # not focus it (otherwise the user cannot get out of fullscreen mode anymore).
91 ################################################################################
93 $tmp = fresh_workspace;
95 my $fullscreen_window = open_window;
98 my $nodes = get_ws_content($tmp);
99 is(scalar @$nodes, 1, 'precisely one window');
100 is($nodes->[0]->{focused}, 1, 'fullscreen window focused');
101 my $old_id = $nodes->[0]->{id};
103 $tmp2 = fresh_workspace;
104 my $move_window = open_window;
105 cmd "move workspace $tmp";
107 cmd "workspace $tmp";
109 $nodes = get_ws_content($tmp);
110 is(scalar @$nodes, 2, 'precisely two windows');
111 is($nodes->[0]->{id}, $old_id, 'id unchanged');
112 is($nodes->[0]->{focused}, 1, 'fullscreen window focused');
114 ################################################################################
115 # Ensure it's possible to change focus if it doesn't escape the fullscreen
116 # container with fullscreen global. We can't even focus a container in a
117 # different workspace.
118 ################################################################################
124 $x->root->warp_pointer(1025, 0);
127 $tmp = fresh_workspace;
128 cmd "workspace $tmp";
129 my $diff_ws = open_window;
133 $x->root->warp_pointer(0, 0);
136 $tmp2 = fresh_workspace;
137 cmd "workspace $tmp2";
141 my $right1 = open_window;
143 my $right2 = open_window;
146 cmd 'fullscreen global';
148 cmd '[id="' . $right1->id . '"] focus';
149 is($x->input_focus, $right1->id, 'upper right window focused');
151 cmd '[id="' . $right2->id . '"] focus';
152 is($x->input_focus, $right2->id, 'bottom right window focused');
155 isnt($x->input_focus, $right2->id, 'bottom right window no longer focused');
158 is($x->input_focus, $right2->id, 'bottom right window focused again');
160 cmd '[id="' . $left->id . '"] focus';
161 is($x->input_focus, $right2->id, 'prevented focus change to left window');
164 is($x->input_focus, $right1->id, 'allowed focus up');
167 is($x->input_focus, $right2->id, 'allowed focus down');
170 is($x->input_focus, $right2->id, 'prevented focus left');
173 is($x->input_focus, $right2->id, 'prevented focus right');
176 is($x->input_focus, $right1->id, 'allowed focus wrap (down)');
179 is($x->input_focus, $right2->id, 'allowed focus wrap (up)');
181 cmd '[id="' . $diff_ws->id . '"] focus';
182 is($x->input_focus, $right2->id, 'prevented focus change to different ws');
184 ################################################################################
185 # Same tests when we're in non-global fullscreen mode. It should now be possible
186 # to focus a container in a different workspace.
187 ################################################################################
190 cmd 'fullscreen global';
193 cmd '[id="' . $right1->id . '"] focus';
194 is($x->input_focus, $right1->id, 'upper right window focused');
196 cmd '[id="' . $right2->id . '"] focus';
197 is($x->input_focus, $right2->id, 'bottom right window focused');
200 isnt($x->input_focus, $right2->id, 'bottom right window no longer focused');
203 is($x->input_focus, $right2->id, 'bottom right window focused again');
205 cmd '[id="' . $left->id . '"] focus';
206 is($x->input_focus, $right2->id, 'prevented focus change to left window');
209 is($x->input_focus, $right1->id, 'allowed focus up');
212 is($x->input_focus, $right2->id, 'allowed focus down');
215 is($x->input_focus, $right1->id, 'allowed focus wrap (down)');
218 is($x->input_focus, $right2->id, 'allowed focus wrap (up)');
221 is($x->input_focus, $right2->id, 'focus left wrapped (no-op)');
224 is($x->input_focus, $diff_ws->id, 'allowed focus change to different ws');
227 is($x->input_focus, $right2->id, 'focused back into fullscreen container');
229 cmd '[id="' . $diff_ws->id . '"] focus';
230 is($x->input_focus, $diff_ws->id, 'allowed focus change to different ws by id');
232 ################################################################################
233 # More testing of the interaction between wrapping and the fullscreen focus
235 ################################################################################
237 cmd '[id="' . $right1->id . '"] focus';
238 is($x->input_focus, $right1->id, 'upper right window focused');
245 my $right12 = open_window;
248 is($x->input_focus, $right2->id, 'bottom right window focused');
251 my $right22 = open_window;
258 is($x->input_focus, $right2->id, 'focus did not leave parent container (1)');
261 is($x->input_focus, $right22->id, 'focus did not leave parent container (2)');
264 is($x->input_focus, $right2->id, 'focus did not leave parent container (3)');
267 is($x->input_focus, $right22->id, 'focus did not leave parent container (4)');
269 ################################################################################
270 # Ensure that moving in a direction doesn't violate the focus restrictions.
271 ################################################################################
276 my $nodes = get_ws_content($tmp2);
277 my $split = $nodes->[1];
278 my $fs = $split->{nodes}->[1];
279 is(scalar @{$fs->{nodes}}, $num, $msg);
283 verify_move(2, 'prevented move left');
285 verify_move(2, 'prevented move right');
287 verify_move(2, 'prevented move down');
290 verify_move(2, 'prevented move up');
292 ################################################################################
293 # Moving to a different workspace is allowed with per-output fullscreen
295 ################################################################################
297 cmd "move to workspace $tmp";
298 verify_move(1, 'did not prevent move to workspace by name');
300 cmd "workspace $tmp";
301 cmd "move to workspace $tmp2";
302 cmd "workspace $tmp2";
304 cmd "move to workspace prev";
305 verify_move(1, 'did not prevent move to workspace by position');
307 ################################################################################
308 # Ensure that is not allowed with global fullscreen containers.
309 ################################################################################
311 cmd "workspace $tmp";
312 cmd "move to workspace $tmp2";
313 cmd "workspace $tmp2";
317 cmd 'fullscreen global';
320 cmd "move to workspace $tmp";
321 verify_move(2, 'prevented move to workspace by name');
323 cmd "move to workspace prev";
324 verify_move(2, 'prevented move to workspace by position');
326 # TODO: Tests for "move to output" and "move workspace to output".