]> git.sur5r.net Git - i3/i3/blob - testcases/t/100-fullscreen.t
Merge branch 'next' into master
[i3/i3] / testcases / t / 100-fullscreen.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 use i3test;
18 use List::Util qw(first);
19
20 my $i3 = i3(get_socket_path());
21
22 my $tmp = fresh_workspace;
23
24 # get the output of this workspace
25 my $tree = $i3->get_tree->recv;
26 my @outputs = @{$tree->{nodes}};
27 my $output;
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}})) {
32         $output = $o;
33         last;
34     }
35 }
36
37 ##################################
38 # map a window, then fullscreen it
39 ##################################
40
41 my $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
42
43 my $window = open_window(
44     rect => $original_rect,
45     dont_map => 1,
46 );
47
48 isa_ok($window, 'X11::XCB::Window');
49
50 is_deeply($window->rect, $original_rect, "rect unmodified before mapping");
51
52 $window->map;
53
54 wait_for_map $window;
55
56 # open another container to make the window get only half of the screen
57 cmd 'open';
58
59 my $new_rect = $window->rect;
60 ok(!eq_hash($new_rect, $original_rect), "Window got repositioned");
61 $original_rect = $new_rect;
62
63 $window->fullscreen(1);
64
65 sync_with_i3;
66
67 $new_rect = $window->rect;
68 ok(!eq_hash($new_rect, $original_rect), "Window got repositioned after fullscreen");
69
70 my $orect = $output->{rect};
71 my $wrect = $new_rect;
72
73 # see if the window really is fullscreen. 20 px for borders are allowed
74 my $threshold = 20;
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');
79
80
81 $window->unmap;
82
83 #########################################################
84 # test with a window which is fullscreened before mapping
85 #########################################################
86
87 # open another container because the empty one will swallow the window we
88 # map in a second
89 cmd 'open';
90
91 $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
92 $window = open_window(
93     rect => $original_rect,
94     dont_map => 1,
95 );
96
97 is_deeply($window->rect, $original_rect, "rect unmodified before mapping");
98
99 $window->fullscreen(1);
100 $window->map;
101
102 wait_for_map $window;
103
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");
107
108 $wrect = $new_rect;
109
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');
115
116 ################################################################################
117 # Verify that when one window wants to go into fullscreen mode, the old
118 # fullscreen window will be replaced.
119 ################################################################################
120
121 $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
122 my $swindow = open_window(
123     rect => $original_rect,
124     dont_map => 1,
125 );
126
127 $swindow->map;
128
129 sync_with_i3;
130
131 ok(!$swindow->mapped, 'window not mapped while fullscreen window active');
132
133 $new_rect = $swindow->rect;
134 ok(!eq_hash($new_rect, $original_rect), "Window got repositioned");
135
136 $swindow->fullscreen(1);
137 sync_with_i3;
138
139 is_num_fullscreen($tmp, 1, 'amount of fullscreen windows');
140
141 $window->fullscreen(0);
142 sync_with_i3;
143 is_num_fullscreen($tmp, 1, 'amount of fullscreen windows');
144
145 ok($swindow->mapped, 'window mapped after other fullscreen ended');
146
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 ###########################################################################
152
153 $swindow->fullscreen(0);
154 sync_with_i3;
155
156 is_num_fullscreen($tmp, 0, 'amount of fullscreen windows after disabling');
157
158 cmd 'fullscreen';
159
160 is_num_fullscreen($tmp, 1, 'amount of fullscreen windows after fullscreen command');
161
162 cmd 'fullscreen';
163
164 is_num_fullscreen($tmp, 0, 'amount of fullscreen windows after fullscreen command');
165
166 # clean up the workspace so that it will be cleaned when switching away
167 cmd 'kill' for (@{get_ws_content($tmp)});
168
169 ################################################################################
170 # Verify that changing focus while in fullscreen does not work.
171 ################################################################################
172
173 $tmp = fresh_workspace;
174
175 my $other = open_window;
176 is($x->input_focus, $other->id, 'other window focused');
177
178 $window = open_window;
179 is($x->input_focus, $window->id, 'window focused');
180
181 cmd 'fullscreen';
182 is($x->input_focus, $window->id, 'fullscreen window focused');
183
184 cmd 'focus left';
185 is($x->input_focus, $window->id, 'fullscreen window still focused');
186
187 ################################################################################
188 # Verify that changing workspace while in global fullscreen does not work.
189 ################################################################################
190
191 $tmp = fresh_workspace;
192 $window = open_window;
193
194 cmd 'fullscreen global';
195 is($x->input_focus, $window->id, 'window focused');
196 is(focused_ws(), $tmp, 'workspace selected');
197
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');
202
203 # leave global fullscreen so that is does not interfere with the other tests
204 $window->fullscreen(0);
205 sync_with_i3;
206
207 ################################################################################
208 # Verify that fullscreening a window on a second workspace and moving it onto
209 # the first workspace unfullscreens the first window.
210 ################################################################################
211
212 my $tmp2 = fresh_workspace;
213 $swindow = open_window;
214
215 cmd 'fullscreen';
216
217 is_num_fullscreen($tmp2, 1, 'one fullscreen window on second ws');
218
219 cmd "move workspace $tmp";
220
221 is_num_fullscreen($tmp2, 0, 'no fullscreen windows on second ws');
222 is_num_fullscreen($tmp, 1, 'one fullscreen window on first ws');
223
224 $swindow->fullscreen(0);
225 sync_with_i3;
226
227 # Verify that $swindow was the one that initially remained fullscreen.
228 is_num_fullscreen($tmp, 0, 'no fullscreen windows on first ws');
229
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 ################################################################################
234
235 $tmp = fresh_workspace;
236
237 $window = open_window();
238
239 cmd "fullscreen";
240
241 is_num_fullscreen($tmp, 1, 'one fullscreen window on ws');
242 is($x->input_focus, $window->id, 'fullscreen window focused');
243
244 $swindow = open_window({
245     fullscreen => 1
246 });
247
248 is_num_fullscreen($tmp, 1, 'one fullscreen window on ws');
249 is($x->input_focus, $swindow->id, 'fullscreen window focused');
250
251 ################################################################################
252 # Verify that command ‘fullscreen enable’ works and is idempotent.
253 ################################################################################
254
255 $tmp = fresh_workspace;
256
257 $window = open_window;
258 is($x->input_focus, $window->id, 'window focused');
259 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
260
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');
264
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');
268
269 $window->fullscreen(0);
270 sync_with_i3;
271 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
272
273 ################################################################################
274 # Verify that command ‘fullscreen enable global’ works and is idempotent.
275 ################################################################################
276
277 $tmp = fresh_workspace;
278
279 $window = open_window;
280 is($x->input_focus, $window->id, 'window focused');
281 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
282
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');
286
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');
290
291 $window->fullscreen(0);
292 sync_with_i3;
293 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
294
295 ################################################################################
296 # Verify that command ‘fullscreen disable’ works and is idempotent.
297 ################################################################################
298
299 $tmp = fresh_workspace;
300
301 $window = open_window;
302 is($x->input_focus, $window->id, 'window focused');
303 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
304
305 $window->fullscreen(1);
306 sync_with_i3;
307 is_num_fullscreen($tmp, 1, 'one fullscreen window on workspace');
308
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');
312
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');
316
317 ################################################################################
318 # Verify that command ‘fullscreen toggle’ works.
319 ################################################################################
320
321 $tmp = fresh_workspace;
322
323 $window = open_window;
324 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
325
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');
329
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');
333
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 ################################################################################
338
339 $tmp = fresh_workspace;
340
341 $window = open_window;
342 $other = open_window;
343
344 is($x->input_focus, $other->id, 'other window focused');
345 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
346
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');
350
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');
354
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 ################################################################################
360
361 $tmp = fresh_workspace;
362
363 $window = open_window;
364
365 is($x->input_focus, $window->id, 'window focused');
366
367 cmd 'workspace ' . get_unused_workspace;
368 isnt($x->input_focus, $window->id, 'window not focused');
369 isnt(focused_ws(), $tmp, 'workspace not selected');
370
371 cmd '[id="' . $window->id . '"] fullscreen enable global';
372 is($x->input_focus, $window->id, 'window focused');
373
374 cmd 'fullscreen disable';
375 is($x->input_focus, $window->id, 'window still focused');
376 is(focused_ws(), $tmp, 'workspace selected');
377
378 done_testing;