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)
18 use List::Util qw(first);
20 my $i3 = i3(get_socket_path());
22 my $tmp = fresh_workspace;
24 # get the output of this workspace
25 my $tree = $i3->get_tree->recv;
26 my @outputs = @{$tree->{nodes}};
28 for my $o (@outputs) {
29 # get the first CT_CON of each output
30 my $content = first { $_->{type} eq 'con' } @{$o->{nodes}};
31 if (defined(first { $_->{name} eq $tmp } @{$content->{nodes}})) {
37 ##################################
38 # map a window, then fullscreen it
39 ##################################
41 my $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
43 my $window = open_window(
44 rect => $original_rect,
48 isa_ok($window, 'X11::XCB::Window');
50 is_deeply($window->rect, $original_rect, "rect unmodified before mapping");
56 # open another container to make the window get only half of the screen
59 my $new_rect = $window->rect;
60 ok(!eq_hash($new_rect, $original_rect), "Window got repositioned");
61 $original_rect = $new_rect;
63 $window->fullscreen(1);
67 $new_rect = $window->rect;
68 ok(!eq_hash($new_rect, $original_rect), "Window got repositioned after fullscreen");
70 my $orect = $output->{rect};
71 my $wrect = $new_rect;
73 # see if the window really is fullscreen. 20 px for borders are allowed
75 ok(($wrect->{x} - $orect->{x}) < $threshold, 'x coordinate fullscreen');
76 ok(($wrect->{y} - $orect->{y}) < $threshold, 'y coordinate fullscreen');
77 ok(abs($wrect->{width} - $orect->{width}) < $threshold, 'width coordinate fullscreen');
78 ok(abs($wrect->{height} - $orect->{height}) < $threshold, 'height coordinate fullscreen');
83 #########################################################
84 # test with a window which is fullscreened before mapping
85 #########################################################
87 # open another container because the empty one will swallow the window we
91 $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
92 $window = open_window(
93 rect => $original_rect,
97 is_deeply($window->rect, $original_rect, "rect unmodified before mapping");
99 $window->fullscreen(1);
102 wait_for_map $window;
104 $new_rect = $window->rect;
105 ok(!eq_hash($new_rect, $original_rect), "Window got repositioned after fullscreen");
106 ok($window->mapped, "Window is mapped after opening it in fullscreen mode");
110 # see if the window really is fullscreen. 20 px for borders are allowed
111 ok(($wrect->{x} - $orect->{x}) < $threshold, 'x coordinate fullscreen');
112 ok(($wrect->{y} - $orect->{y}) < $threshold, 'y coordinate fullscreen');
113 ok(abs($wrect->{width} - $orect->{width}) < $threshold, 'width coordinate fullscreen');
114 ok(abs($wrect->{height} - $orect->{height}) < $threshold, 'height coordinate fullscreen');
116 ################################################################################
117 # Verify that when one window wants to go into fullscreen mode, the old
118 # fullscreen window will be replaced.
119 ################################################################################
121 $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
122 my $swindow = open_window(
123 rect => $original_rect,
131 ok(!$swindow->mapped, 'window not mapped while fullscreen window active');
133 $new_rect = $swindow->rect;
134 ok(!eq_hash($new_rect, $original_rect), "Window got repositioned");
136 $swindow->fullscreen(1);
139 is_num_fullscreen($tmp, 1, 'amount of fullscreen windows');
141 $window->fullscreen(0);
143 is_num_fullscreen($tmp, 1, 'amount of fullscreen windows');
145 ok($swindow->mapped, 'window mapped after other fullscreen ended');
147 ###########################################################################
148 # as $swindow is out of state at the moment (it requested to be fullscreen,
149 # but the WM denied), we check what happens if we go out of fullscreen now
150 # (nothing should happen)
151 ###########################################################################
153 $swindow->fullscreen(0);
156 is_num_fullscreen($tmp, 0, 'amount of fullscreen windows after disabling');
160 is_num_fullscreen($tmp, 1, 'amount of fullscreen windows after fullscreen command');
164 is_num_fullscreen($tmp, 0, 'amount of fullscreen windows after fullscreen command');
166 # clean up the workspace so that it will be cleaned when switching away
167 cmd 'kill' for (@{get_ws_content($tmp)});
169 ################################################################################
170 # Verify that changing focus while in fullscreen does not work.
171 ################################################################################
173 $tmp = fresh_workspace;
175 my $other = open_window;
176 is($x->input_focus, $other->id, 'other window focused');
178 $window = open_window;
179 is($x->input_focus, $window->id, 'window focused');
182 is($x->input_focus, $window->id, 'fullscreen window focused');
185 is($x->input_focus, $window->id, 'fullscreen window still focused');
187 ################################################################################
188 # Verify that changing workspace while in global fullscreen does not work.
189 ################################################################################
191 $tmp = fresh_workspace;
192 $window = open_window;
194 cmd 'fullscreen global';
195 is($x->input_focus, $window->id, 'window focused');
196 is(focused_ws(), $tmp, 'workspace selected');
198 $other = get_unused_workspace;
199 cmd "workspace $other";
200 is($x->input_focus, $window->id, 'window still focused');
201 is(focused_ws(), $tmp, 'workspace still selected');
203 # leave global fullscreen so that is does not interfere with the other tests
204 $window->fullscreen(0);
207 ################################################################################
208 # Verify that fullscreening a window on a second workspace and moving it onto
209 # the first workspace unfullscreens the first window.
210 ################################################################################
212 my $tmp2 = fresh_workspace;
213 $swindow = open_window;
217 is_num_fullscreen($tmp2, 1, 'one fullscreen window on second ws');
219 cmd "move workspace $tmp";
221 is_num_fullscreen($tmp2, 0, 'no fullscreen windows on second ws');
222 is_num_fullscreen($tmp, 1, 'one fullscreen window on first ws');
224 $swindow->fullscreen(0);
227 # Verify that $swindow was the one that initially remained fullscreen.
228 is_num_fullscreen($tmp, 0, 'no fullscreen windows on first ws');
230 ################################################################################
231 # Verify that opening a window with _NET_WM_STATE_FULLSCREEN unfullscreens any
232 # existing container on the workspace and fullscreens the newly opened window.
233 ################################################################################
235 $tmp = fresh_workspace;
237 $window = open_window();
241 is_num_fullscreen($tmp, 1, 'one fullscreen window on ws');
242 is($x->input_focus, $window->id, 'fullscreen window focused');
244 $swindow = open_window({
248 is_num_fullscreen($tmp, 1, 'one fullscreen window on ws');
249 is($x->input_focus, $swindow->id, 'fullscreen window focused');
251 ################################################################################
252 # Verify that command ‘fullscreen enable’ works and is idempotent.
253 ################################################################################
255 $tmp = fresh_workspace;
257 $window = open_window;
258 is($x->input_focus, $window->id, 'window focused');
259 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
261 cmd 'fullscreen enable';
262 is($x->input_focus, $window->id, 'window still focused');
263 is_num_fullscreen($tmp, 1, 'one fullscreen window on workspace');
265 cmd 'fullscreen enable';
266 is($x->input_focus, $window->id, 'window still focused');
267 is_num_fullscreen($tmp, 1, 'still one fullscreen window on workspace');
269 $window->fullscreen(0);
271 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
273 ################################################################################
274 # Verify that command ‘fullscreen enable global’ works and is idempotent.
275 ################################################################################
277 $tmp = fresh_workspace;
279 $window = open_window;
280 is($x->input_focus, $window->id, 'window focused');
281 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
283 cmd 'fullscreen enable global';
284 is($x->input_focus, $window->id, 'window still focused');
285 is_num_fullscreen($tmp, 1, 'one fullscreen window on workspace');
287 cmd 'fullscreen enable global';
288 is($x->input_focus, $window->id, 'window still focused');
289 is_num_fullscreen($tmp, 1, 'still one fullscreen window on workspace');
291 $window->fullscreen(0);
293 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
295 ################################################################################
296 # Verify that command ‘fullscreen disable’ works and is idempotent.
297 ################################################################################
299 $tmp = fresh_workspace;
301 $window = open_window;
302 is($x->input_focus, $window->id, 'window focused');
303 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
305 $window->fullscreen(1);
307 is_num_fullscreen($tmp, 1, 'one fullscreen window on workspace');
309 cmd 'fullscreen disable';
310 is($x->input_focus, $window->id, 'window still focused');
311 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
313 cmd 'fullscreen disable';
314 is($x->input_focus, $window->id, 'window still focused');
315 is_num_fullscreen($tmp, 0, 'still no fullscreen window on workspace');
317 ################################################################################
318 # Verify that command ‘fullscreen toggle’ works.
319 ################################################################################
321 $tmp = fresh_workspace;
323 $window = open_window;
324 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
326 cmd 'fullscreen toggle';
327 is($x->input_focus, $window->id, 'window still focused');
328 is_num_fullscreen($tmp, 1, 'one fullscreen window on workspace');
330 cmd 'fullscreen toggle';
331 is($x->input_focus, $window->id, 'window still focused');
332 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
334 ################################################################################
335 # Verify that a window’s fullscreen is disabled when another one is enabled
336 # on the same workspace. The new fullscreen window should be focused.
337 ################################################################################
339 $tmp = fresh_workspace;
341 $window = open_window;
342 $other = open_window;
344 is($x->input_focus, $other->id, 'other window focused');
345 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
347 cmd 'fullscreen enable';
348 is($x->input_focus, $other->id, 'other window focused');
349 is_num_fullscreen($tmp, 1, 'one fullscreen window on workspace');
351 cmd '[id="' . $window->id . '"] fullscreen enable';
352 is($x->input_focus, $window->id, 'window focused');
353 is_num_fullscreen($tmp, 1, 'one fullscreen window on workspace');
355 ################################################################################
356 # Verify that when a global fullscreen is enabled the window is focused and
357 # its workspace is selected, so that disabling the fullscreen keeps the window
358 # focused and visible.
359 ################################################################################
361 $tmp = fresh_workspace;
363 $window = open_window;
365 is($x->input_focus, $window->id, 'window focused');
367 cmd 'workspace ' . get_unused_workspace;
368 isnt($x->input_focus, $window->id, 'window not focused');
369 isnt(focused_ws(), $tmp, 'workspace not selected');
371 cmd '[id="' . $window->id . '"] fullscreen enable global';
372 is($x->input_focus, $window->id, 'window focused');
374 cmd 'fullscreen disable';
375 is($x->input_focus, $window->id, 'window still focused');
376 is(focused_ws(), $tmp, 'workspace selected');