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 # Tests for _NET_WM_DESKTOP.
19 use i3test i3_autostart => 0;
20 use X11::XCB qw(:all);
22 ###############################################################################
24 sub get_net_wm_desktop {
28 my $cookie = $x->get_property(
31 $x->atom(name => '_NET_WM_DESKTOP')->id,
32 $x->atom(name => 'CARDINAL')->id,
37 my $reply = $x->get_property_reply($cookie->{sequence});
38 return undef if $reply->{length} != 1;
40 return unpack("L", $reply->{value});
43 sub send_net_wm_desktop {
45 my $msg = pack "CCSLLLLLL",
46 X11::XCB::CLIENT_MESSAGE, 32, 0,
48 $x->atom(name => '_NET_WM_DESKTOP')->id,
51 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
55 sub open_window_with_net_wm_desktop {
57 my $window = open_window(
63 $x->atom(name => '_NET_WM_DESKTOP')->id,
64 $x->atom(name => 'CARDINAL')->id,
74 # We need to kill all windows in between tests since they survive the i3 restart
75 # and will interfere with the following tests.
78 cmd '[title="Window.*"] kill';
81 ###############################################################################
83 my ($config, $config_mm, $pid, $con);
87 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
90 status_command i3status
96 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
98 workspace "0" output "fake-0"
99 workspace "1" output "fake-0"
100 workspace "2" output "fake-0"
101 workspace "10" output "fake-1"
102 workspace "11" output "fake-1"
103 workspace "12" output "fake-1"
105 fake-outputs 1024x768+0+0,1024x768+1024+0
108 ###############################################################################
109 # Upon managing a window which does not set _NET_WM_DESKTOP, the property is
111 ###############################################################################
113 $pid = launch_with_config($config);
118 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set upon managing a window');
121 exit_gracefully($pid);
123 ###############################################################################
124 # Upon managing a window which sets _NET_WM_DESKTOP, the window is moved to
125 # the specified desktop.
126 ###############################################################################
128 $pid = launch_with_config($config);
137 $con = open_window_with_net_wm_desktop(1);
139 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP still has the correct value');
140 is_num_children('1', 2, 'The window was moved to workspace 1');
143 exit_gracefully($pid);
145 ###############################################################################
146 # Upon managing a window which sets _NET_WM_DESKTOP to the appropriate value,
147 # the window is made sticky and floating.
148 ###############################################################################
150 $pid = launch_with_config($config);
153 $con = open_window_with_net_wm_desktop(0xFFFFFFFF);
155 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP still has the correct value');
156 is(@{get_ws('0')->{floating_nodes}}, 1, 'The window is floating');
157 ok(get_ws('0')->{floating_nodes}->[0]->{nodes}->[0]->{sticky}, 'The window is sticky');
160 exit_gracefully($pid);
162 ###############################################################################
163 # _NET_WM_DESKTOP is updated when the window is moved to another workspace
164 # on the same output.
165 ###############################################################################
167 $pid = launch_with_config($config);
176 cmd 'move window to workspace 1';
178 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated when moving the window');
181 exit_gracefully($pid);
183 ###############################################################################
184 # _NET_WM_DESKTOP is updated when the floating window is moved to another
185 # workspace on the same output.
186 ###############################################################################
188 $pid = launch_with_config($config);
196 cmd 'floating enable';
198 cmd 'move window to workspace 1';
200 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated when moving the window');
203 exit_gracefully($pid);
205 ###############################################################################
206 # _NET_WM_DESKTOP is updated when the window is moved to another workspace
208 ###############################################################################
210 $pid = launch_with_config($config_mm);
219 cmd 'move window to workspace 10';
221 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated when moving the window');
224 exit_gracefully($pid);
226 ###############################################################################
227 # _NET_WM_DESKTOP is removed when the window is withdrawn.
228 ###############################################################################
230 $pid = launch_with_config($config);
233 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set (sanity check)');
236 wait_for_unmap($con);
238 is(get_net_wm_desktop($con), undef, '_NET_WM_DESKTOP is removed');
241 exit_gracefully($pid);
243 ###############################################################################
244 # A _NET_WM_DESKTOP client message sent to the root window moves a window
245 # to the correct workspace.
246 ###############################################################################
248 $pid = launch_with_config($config);
257 is_num_children('0', 2, 'The window is on workspace 0');
259 send_net_wm_desktop($con, 1);
261 is_num_children('0', 1, 'The window is no longer on workspace 0');
262 is_num_children('1', 2, 'The window is now on workspace 1');
263 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated');
266 exit_gracefully($pid);
268 ###############################################################################
269 # A _NET_WM_DESKTOP client message sent to the root window can make a window
271 ###############################################################################
273 $pid = launch_with_config($config);
278 send_net_wm_desktop($con, 0xFFFFFFFF);
280 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
281 is(@{get_ws('0')->{floating_nodes}}, 1, 'The window is floating');
282 ok(get_ws('0')->{floating_nodes}->[0]->{nodes}->[0]->{sticky}, 'The window is sticky');
285 exit_gracefully($pid);
287 ###############################################################################
288 # _NET_WM_DESKTOP is updated when a new workspace with a lower number is
290 ###############################################################################
292 $pid = launch_with_config($config);
296 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
299 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated');
302 exit_gracefully($pid);
304 ###############################################################################
305 # _NET_WM_DESKTOP is updated when a window is made sticky by command.
306 ###############################################################################
308 $pid = launch_with_config($config);
312 cmd 'floating enable';
313 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
316 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
319 exit_gracefully($pid);
321 ###############################################################################
322 # _NET_WM_DESKTOP is updated when a window is made sticky by client message.
323 ###############################################################################
325 $pid = launch_with_config($config);
329 cmd 'floating enable';
330 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
332 my $msg = pack "CCSLLLLLL",
333 X11::XCB::CLIENT_MESSAGE, 32, 0,
335 $x->atom(name => '_NET_WM_STATE')->id,
337 $x->atom(name => '_NET_WM_STATE_STICKY')->id,
340 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
343 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
346 exit_gracefully($pid);
348 ###############################################################################
349 # _NET_WM_DESKTOP is updated when a window is moved to the scratchpad.
350 ###############################################################################
352 $pid = launch_with_config($config);
356 cmd 'floating enable';
357 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
359 cmd 'move scratchpad';
360 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
362 cmd 'scratchpad show';
363 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
366 exit_gracefully($pid);
368 ###############################################################################