]> git.sur5r.net Git - i3/i3/blob - testcases/t/156-fullscreen-focus.t
Merge branch 'release-4.16.1'
[i3/i3] / testcases / t / 156-fullscreen-focus.t
1 #!perl
2 # vim:ts=4:sw=4:expandtab
3 #
4 # Please read the following documents before working on tests:
5 # • https://build.i3wm.org/docs/testsuite.html
6 #   (or docs/testsuite)
7 #
8 # • https://build.i3wm.org/docs/lib-i3test.html
9 #   (alternatively: perldoc ./testcases/lib/i3test.pm)
10 #
11 # • https://build.i3wm.org/docs/ipc.html
12 #   (or docs/ipc)
13 #
14 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
15 #   (unless you are already familiar with Perl)
16 #
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.
20 #
21 use i3test i3_config => <<EOT;
22 # i3 config file (v4)
23 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
24
25 fake-outputs 1024x768+0+0,1024x768+1024+0
26 EOT
27 # Screen setup looks like this:
28 # +----+----+
29 # | S1 | S2 |
30 # +----+----+
31
32 sub verify_focus {
33     # Report original line
34     local $Test::Builder::Level = $Test::Builder::Level + 1;
35
36     my ($expected, $msg) = @_;
37     $expected = $expected->id;
38
39     # Ensure the expected focus if the test fails.
40     cmd "[id=$expected] focus" unless is($x->input_focus, $expected, $msg);
41 }
42
43 ################################################################################
44 # Verify that window opened behind fullscreen window will get focus after the
45 # fullscreen window gets moved to a different workspace.
46 ################################################################################
47
48 fresh_workspace;
49 my $left = open_window;
50 verify_focus($left, 'left window focused');
51 diag("left = " . $left->id);
52
53 my $right = open_window;
54 cmd 'fullscreen';
55 diag("right = " . $right->id);
56
57 # Open a third window. Since we're fullscreen, the window won't be mapped, so
58 # don't wait for it to be mapped. Instead, just send the map request and sync
59 # with i3 to make sure i3 recognizes it.
60 my $third = open_window({dont_map => 1});
61 $third->map;
62 sync_with_i3;
63 diag("third = " . $third->id);
64
65 # Move the window to a different workspace, and verify that the third window now
66 # gets focused in the current workspace.
67 my $tmp2 = get_unused_workspace;
68 cmd "move workspace $tmp2";
69 verify_focus($third, 'third window focused');
70
71 kill_all_windows;
72
73 ################################################################################
74 # Ensure that moving a window to a workspace which has a fullscreen window does
75 # not focus it (otherwise the user cannot get out of fullscreen mode anymore).
76 ################################################################################
77
78 my $tmp = fresh_workspace;
79
80 open_window;
81 cmd 'fullscreen';
82
83 my $nodes = get_ws_content($tmp);
84 is(scalar @$nodes, 1, 'precisely one window');
85 is($nodes->[0]->{focused}, 1, 'fullscreen window focused');
86 my $old_id = $nodes->[0]->{id};
87
88 $tmp2 = fresh_workspace;
89 my $move_window = open_window;
90 cmd "move workspace $tmp";
91
92 cmd "workspace $tmp";
93
94 $nodes = get_ws_content($tmp);
95 is(scalar @$nodes, 2, 'precisely two windows');
96 is($nodes->[0]->{id}, $old_id, 'id unchanged');
97 is($nodes->[0]->{focused}, 1, 'fullscreen window focused');
98
99 kill_all_windows;
100
101 ################################################################################
102 # Ensure it's possible to change focus if it doesn't escape the fullscreen
103 # container with fullscreen global. We can't even focus a container in a
104 # different workspace.
105 ################################################################################
106
107 $tmp = fresh_workspace(output => 1);
108 my $diff_ws = open_window;
109
110 $tmp2 = fresh_workspace(output => 0);
111 $left = open_window;
112 my $right1 = open_window;
113 cmd 'split v';
114 my $right2 = open_window;
115
116 cmd 'focus parent';
117 cmd 'fullscreen global';
118
119 cmd '[id="' . $right1->id . '"] focus';
120 verify_focus($right1, 'upper right window focused');
121
122 cmd '[id="' . $right2->id . '"] focus';
123 verify_focus($right2, 'bottom right window focused');
124
125 cmd 'focus parent';
126 isnt($x->input_focus, $right2->id, 'bottom right window no longer focused');
127
128 cmd 'focus child';
129 verify_focus($right2, 'bottom right window focused again');
130
131 cmd 'focus up';
132 verify_focus($right1, 'allowed focus up');
133
134 cmd 'focus down';
135 verify_focus($right2, 'allowed focus down');
136
137 cmd 'focus left';
138 verify_focus($right2, 'prevented focus left');
139
140 cmd 'focus right';
141 verify_focus($right2, 'prevented focus right');
142
143 cmd 'focus down';
144 verify_focus($right1, 'allowed focus wrap (down)');
145
146 cmd 'focus up';
147 verify_focus($right2, 'allowed focus wrap (up)');
148
149 ################################################################################
150 # (depends on previous layout)
151 # Same tests when we're in non-global fullscreen mode. It should now be possible
152 # to focus a container in a different workspace.
153 ################################################################################
154
155 cmd 'focus parent';
156 cmd 'fullscreen disable';
157 cmd 'fullscreen';
158
159 cmd '[id="' . $right1->id . '"] focus';
160 verify_focus($right1, 'upper right window focused');
161
162 cmd '[id="' . $right2->id . '"] focus';
163 verify_focus($right2, 'bottom right window focused');
164
165 cmd 'focus parent';
166 isnt($x->input_focus, $right2->id, 'bottom right window no longer focused');
167
168 cmd 'focus child';
169 verify_focus($right2, 'bottom right window focused again');
170
171 cmd 'focus up';
172 verify_focus($right1, 'allowed focus up');
173
174 cmd 'focus down';
175 verify_focus($right2, 'allowed focus down');
176
177 cmd 'focus down';
178 verify_focus($right1, 'allowed focus wrap (down)');
179
180 cmd 'focus up';
181 verify_focus($right2, 'allowed focus wrap (up)');
182
183 cmd 'focus left';
184 verify_focus($right2, 'focus left wrapped (no-op)');
185
186 cmd 'focus right';
187 verify_focus($diff_ws, 'allowed focus change to different ws');
188
189 cmd 'focus left';
190 verify_focus($right2, 'focused back into fullscreen container');
191
192 cmd '[id="' . $diff_ws->id . '"] focus';
193 verify_focus($diff_ws, 'allowed focus change to different ws by id');
194
195 ################################################################################
196 # (depends on previous layout)
197 # More testing of the interaction between wrapping and the fullscreen focus
198 # restrictions.
199 ################################################################################
200
201 cmd '[id="' . $right1->id . '"] focus';
202 verify_focus($right1, 'upper right window focused');
203
204 cmd 'focus parent';
205 cmd 'fullscreen disable';
206 cmd 'focus child';
207
208 cmd 'split v';
209 my $right12 = open_window;
210
211 cmd 'focus down';
212 verify_focus($right2, 'bottom right window focused');
213
214 cmd 'split v';
215 my $right22 = open_window;
216
217 cmd 'focus parent';
218 cmd 'fullscreen';
219 cmd 'focus child';
220
221 cmd 'focus down';
222 verify_focus($right2, 'focus did not leave parent container (1)');
223
224 cmd 'focus down';
225 verify_focus($right22, 'focus did not leave parent container (2)');
226
227 cmd 'focus up';
228 verify_focus($right2, 'focus did not leave parent container (3)');
229
230 cmd 'focus up';
231 verify_focus($right22, 'focus did not leave parent container (4)');
232
233 ################################################################################
234 # (depends on previous layout)
235 # Ensure that moving in a direction doesn't violate the focus restrictions.
236 ################################################################################
237
238 sub verify_move {
239     my $num = shift;
240     my $msg = shift;
241     my $nodes = get_ws_content($tmp2);
242     my $split = $nodes->[1];
243     my $fs = $split->{nodes}->[1];
244     is(scalar @{$fs->{nodes}}, $num, $msg);
245 }
246
247 cmd 'move left';
248 verify_move(2, 'prevented move left');
249 cmd 'move right';
250 verify_move(2, 'prevented move right');
251 cmd 'move down';
252 verify_move(2, 'prevented move down');
253 cmd 'move up';
254 cmd 'move up';
255 verify_move(2, 'prevented move up');
256
257 ################################################################################
258 # (depends on previous layout)
259 # Moving to a different workspace is allowed with per-output fullscreen
260 # containers.
261 ################################################################################
262
263 cmd "move to workspace $tmp";
264 verify_move(1, 'did not prevent move to workspace by name');
265
266 cmd "workspace $tmp";
267 cmd "move to workspace $tmp2";
268 cmd "workspace $tmp2";
269
270 cmd "move to workspace prev";
271 verify_move(1, 'did not prevent move to workspace by position');
272
273 ################################################################################
274 # (depends on previous layout)
275 # Ensure that is not allowed with global fullscreen containers.
276 ################################################################################
277
278 cmd "workspace $tmp";
279 cmd "move to workspace $tmp2";
280 cmd "workspace $tmp2";
281
282 cmd 'focus parent';
283 cmd 'fullscreen disable';
284 cmd 'fullscreen global';
285 cmd 'focus child';
286
287 cmd "move to workspace $tmp";
288 verify_move(2, 'prevented move to workspace by name');
289
290 cmd "move to workspace prev";
291 verify_move(2, 'prevented move to workspace by position');
292
293 kill_all_windows;
294
295 ################################################################################
296 # Ensure it's possible to focus a window using the focus command despite
297 # fullscreen window blocking it. Fullscreen window should lose its fullscreen
298 # mode.
299 ################################################################################
300
301 # first & second tiling, focus using id
302 $tmp = fresh_workspace;
303 my $first = open_window;
304 my $second = open_window;
305 cmd 'fullscreen';
306 verify_focus($second, 'fullscreen window focused');
307 is_num_fullscreen($tmp, 1, '1 fullscreen window');
308
309 cmd '[id="' . $first->id . '"] focus';
310 sync_with_i3;
311
312 verify_focus($first, 'correctly focused using id');
313 is_num_fullscreen($tmp, 0, 'no fullscreen windows');
314
315 kill_all_windows;
316
317 # first floating, second tiling, focus using 'focus floating'
318 $tmp = fresh_workspace;
319 $first = open_floating_window;
320 $second = open_window;
321 cmd 'fullscreen';
322 verify_focus($second, 'fullscreen window focused');
323 is_num_fullscreen($tmp, 1, '1 fullscreen window');
324
325 cmd 'focus floating';
326 sync_with_i3;
327
328 verify_focus($first, 'correctly focused using focus floating');
329 is_num_fullscreen($tmp, 0, 'no fullscreen windows');
330
331 kill_all_windows;
332
333 # first tiling, second floating, focus using 'focus tiling'
334 $tmp = fresh_workspace;
335 $first = open_window;
336 $second = open_floating_window;
337 cmd 'fullscreen';
338 verify_focus($second, 'fullscreen window focused');
339 is_num_fullscreen($tmp, 1, '1 fullscreen window');
340
341 cmd 'focus tiling';
342 sync_with_i3;
343
344 verify_focus($first, 'correctly focused using focus tiling');
345 is_num_fullscreen($tmp, 0, 'no fullscreen windows');
346
347 kill_all_windows;
348
349 ################################################################################
350 # When the fullscreen window is in an other workspace it should maintain its
351 # fullscreen mode since it's not blocking the window to be focused.
352 ################################################################################
353
354 $tmp = fresh_workspace;
355 $first = open_window;
356
357 $tmp2 = fresh_workspace;
358 $second = open_window;
359 cmd 'fullscreen';
360 verify_focus($second, 'fullscreen window focused');
361 is_num_fullscreen($tmp2, 1, '1 fullscreen window');
362
363 cmd '[id="' . $first->id . '"] focus';
364 sync_with_i3;
365
366 verify_focus($first, 'correctly focused using focus id');
367 is_num_fullscreen($tmp, 0, 'no fullscreen windows on first workspace');
368 is_num_fullscreen($tmp2, 1, 'still one fullscreen window on second workspace');
369
370 kill_all_windows;
371
372 ################################################################################
373 # But a global window in another workspace is blocking the window to be focused.
374 # Ensure that it loses its fullscreen mode.
375 ################################################################################
376
377 $tmp = fresh_workspace;
378 $first = open_window;
379
380 $tmp2 = fresh_workspace;
381 $second = open_window;
382 cmd 'fullscreen global';
383 verify_focus($second, 'global window focused');
384 is_num_fullscreen($tmp2, 1, '1 fullscreen window');
385
386 cmd '[id="' . $first->id . '"] focus';
387 sync_with_i3;
388
389 verify_focus($first, 'correctly focused using focus id');
390 is_num_fullscreen($tmp2, 0, 'no fullscreen windows');
391
392
393 # TODO: Tests for "move to output" and "move workspace to output".
394 done_testing;