2 # vim:ts=4:sw=4:expandtab
4 # Please read the following documents before working on tests:
5 # • http://build.i3wm.org/docs/testsuite.html
8 # • http://build.i3wm.org/docs/lib-i3test.html
9 # (alternatively: perldoc ./testcases/lib/i3test.pm)
11 # • http://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_autostart => 0;
23 # Screen setup looks like this:
29 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
31 fake-outputs 1024x768+0+0,1024x768+1024+0
34 my $pid = launch_with_config($config);
36 my $i3 = i3(get_socket_path());
38 my $tmp = fresh_workspace;
40 ################################################################################
41 # Open the left window.
42 ################################################################################
44 my $left = open_window({ background_color => '#ff0000' });
46 is($x->input_focus, $left->id, 'left window focused');
48 diag("left = " . $left->id);
50 ################################################################################
51 # Open the right window.
52 ################################################################################
54 my $right = open_window({ background_color => '#00ff00' });
56 diag("right = " . $right->id);
58 ################################################################################
59 # Set the right window to fullscreen.
60 ################################################################################
62 cmd 'nop setting fullscreen';
65 ################################################################################
66 # Open a third window. Since we're fullscreen, the window won't be # mapped, so
67 # don't wait for it to be mapped. Instead, just send the map request and sync
68 # with i3 to make sure i3 recognizes it.
69 ################################################################################
71 my $third = open_window({
72 background_color => '#0000ff',
73 name => 'Third window',
81 diag("third = " . $third->id);
83 ################################################################################
84 # Move the window to a different workspace, and verify that the third window now
85 # gets focused in the current workspace.
86 ################################################################################
88 my $tmp2 = get_unused_workspace;
90 cmd "move workspace $tmp2";
92 is($x->input_focus, $third->id, 'third window focused');
94 ################################################################################
95 # Ensure that moving a window to a workspace which has a fullscreen window does
96 # not focus it (otherwise the user cannot get out of fullscreen mode anymore).
97 ################################################################################
99 $tmp = fresh_workspace;
101 my $fullscreen_window = open_window;
104 my $nodes = get_ws_content($tmp);
105 is(scalar @$nodes, 1, 'precisely one window');
106 is($nodes->[0]->{focused}, 1, 'fullscreen window focused');
107 my $old_id = $nodes->[0]->{id};
109 $tmp2 = fresh_workspace;
110 my $move_window = open_window;
111 cmd "move workspace $tmp";
113 cmd "workspace $tmp";
115 $nodes = get_ws_content($tmp);
116 is(scalar @$nodes, 2, 'precisely two windows');
117 is($nodes->[0]->{id}, $old_id, 'id unchanged');
118 is($nodes->[0]->{focused}, 1, 'fullscreen window focused');
120 ################################################################################
121 # Ensure it's possible to change focus if it doesn't escape the fullscreen
122 # container with fullscreen global. We can't even focus a container in a
123 # different workspace.
124 ################################################################################
129 $x->root->warp_pointer(1025, 0);
132 $tmp = fresh_workspace;
133 cmd "workspace $tmp";
134 my $diff_ws = open_window;
137 $x->root->warp_pointer(0, 0);
140 $tmp2 = fresh_workspace;
141 cmd "workspace $tmp2";
145 my $right1 = open_window;
147 my $right2 = open_window;
150 cmd 'fullscreen global';
152 cmd '[id="' . $right1->id . '"] focus';
153 is($x->input_focus, $right1->id, 'upper right window focused');
155 cmd '[id="' . $right2->id . '"] focus';
156 is($x->input_focus, $right2->id, 'bottom right window focused');
159 isnt($x->input_focus, $right2->id, 'bottom right window no longer focused');
162 is($x->input_focus, $right2->id, 'bottom right window focused again');
164 cmd '[id="' . $left->id . '"] focus';
165 is($x->input_focus, $right2->id, 'prevented focus change to left window');
168 is($x->input_focus, $right1->id, 'allowed focus up');
171 is($x->input_focus, $right2->id, 'allowed focus down');
174 is($x->input_focus, $right2->id, 'prevented focus left');
177 is($x->input_focus, $right2->id, 'prevented focus right');
180 is($x->input_focus, $right1->id, 'allowed focus wrap (down)');
183 is($x->input_focus, $right2->id, 'allowed focus wrap (up)');
185 cmd '[id="' . $diff_ws->id . '"] focus';
186 is($x->input_focus, $right2->id, 'prevented focus change to different ws');
188 ################################################################################
189 # Same tests when we're in non-global fullscreen mode. It should now be possible
190 # to focus a container in a different workspace.
191 ################################################################################
194 cmd 'fullscreen global';
197 cmd '[id="' . $right1->id . '"] focus';
198 is($x->input_focus, $right1->id, 'upper right window focused');
200 cmd '[id="' . $right2->id . '"] focus';
201 is($x->input_focus, $right2->id, 'bottom right window focused');
204 isnt($x->input_focus, $right2->id, 'bottom right window no longer focused');
207 is($x->input_focus, $right2->id, 'bottom right window focused again');
209 cmd '[id="' . $left->id . '"] focus';
210 is($x->input_focus, $right2->id, 'prevented focus change to left window');
213 is($x->input_focus, $right1->id, 'allowed focus up');
216 is($x->input_focus, $right2->id, 'allowed focus down');
219 is($x->input_focus, $right1->id, 'allowed focus wrap (down)');
222 is($x->input_focus, $right2->id, 'allowed focus wrap (up)');
225 is($x->input_focus, $right2->id, 'focus left wrapped (no-op)');
228 is($x->input_focus, $diff_ws->id, 'allowed focus change to different ws');
231 is($x->input_focus, $right2->id, 'focused back into fullscreen container');
233 cmd '[id="' . $diff_ws->id . '"] focus';
234 is($x->input_focus, $diff_ws->id, 'allowed focus change to different ws by id');
236 ################################################################################
237 # More testing of the interaction between wrapping and the fullscreen focus
239 ################################################################################
241 cmd '[id="' . $right1->id . '"] focus';
242 is($x->input_focus, $right1->id, 'upper right window focused');
249 my $right12 = open_window;
252 is($x->input_focus, $right2->id, 'bottom right window focused');
255 my $right22 = open_window;
262 is($x->input_focus, $right2->id, 'focus did not leave parent container (1)');
265 is($x->input_focus, $right22->id, 'focus did not leave parent container (2)');
268 is($x->input_focus, $right2->id, 'focus did not leave parent container (3)');
271 is($x->input_focus, $right22->id, 'focus did not leave parent container (4)');
273 ################################################################################
274 # Ensure that moving in a direction doesn't violate the focus restrictions.
275 ################################################################################
280 my $nodes = get_ws_content($tmp2);
281 my $split = $nodes->[1];
282 my $fs = $split->{nodes}->[1];
283 is(scalar @{$fs->{nodes}}, $num, $msg);
287 verify_move(2, 'prevented move left');
289 verify_move(2, 'prevented move right');
291 verify_move(2, 'prevented move down');
294 verify_move(2, 'prevented move up');
296 ################################################################################
297 # Moving to a different workspace is allowed with per-output fullscreen
299 ################################################################################
301 cmd "move to workspace $tmp";
302 verify_move(1, 'did not prevent move to workspace by name');
304 cmd "workspace $tmp";
305 cmd "move to workspace $tmp2";
306 cmd "workspace $tmp2";
308 cmd "move to workspace prev";
309 verify_move(1, 'did not prevent move to workspace by position');
311 ################################################################################
312 # Ensure that is not allowed with global fullscreen containers.
313 ################################################################################
315 cmd "workspace $tmp";
316 cmd "move to workspace $tmp2";
317 cmd "workspace $tmp2";
321 cmd 'fullscreen global';
324 cmd "move to workspace $tmp";
325 verify_move(2, 'prevented move to workspace by name');
327 cmd "move to workspace prev";
328 verify_move(2, 'prevented move to workspace by position');
330 # TODO: Tests for "move to output" and "move workspace to output".
332 exit_gracefully($pid);