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,
72 # We don’t wait for MapNotify and instead sync with i3 so that we don’t need
73 # to encounter the full timeout of 4s when opening a window on a non-visible
81 # We need to kill all windows in between tests since they survive the i3 restart
82 # and will interfere with the following tests.
85 cmd '[title="Window.*"] kill';
88 ###############################################################################
92 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
95 status_command i3status
99 my $pid = launch_with_config($config);
101 ###############################################################################
102 # Upon managing a window which does not set _NET_WM_DESKTOP, the property is
104 ###############################################################################
107 my $con = open_window;
109 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set upon managing a window');
113 ###############################################################################
114 # Upon managing a window which sets _NET_WM_DESKTOP, the window is moved to
115 # the specified desktop.
116 ###############################################################################
125 $con = open_window_with_net_wm_desktop(1);
127 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP still has the correct value');
128 is_num_children('1', 2, 'The window was moved to workspace 1');
132 ###############################################################################
133 # Upon managing a window which sets _NET_WM_DESKTOP to the appropriate value,
134 # the window is made sticky and floating.
135 ###############################################################################
138 $con = open_window_with_net_wm_desktop(0xFFFFFFFF);
140 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP still has the correct value');
141 is(@{get_ws('0')->{floating_nodes}}, 1, 'The window is floating');
142 ok(get_ws('0')->{floating_nodes}->[0]->{nodes}->[0]->{sticky}, 'The window is sticky');
146 ###############################################################################
147 # _NET_WM_DESKTOP is updated when the window is moved to another workspace
148 # on the same output.
149 ###############################################################################
158 cmd 'move window to workspace 1';
160 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated when moving the window');
164 ###############################################################################
165 # _NET_WM_DESKTOP is updated when the floating window is moved to another
166 # workspace on the same output.
167 ###############################################################################
175 cmd 'floating enable';
177 cmd 'move window to workspace 1';
179 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated when moving the window');
183 ###############################################################################
184 # _NET_WM_DESKTOP is removed when the window is withdrawn.
185 ###############################################################################
188 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set (sanity check)');
191 wait_for_unmap($con);
193 is(get_net_wm_desktop($con), undef, '_NET_WM_DESKTOP is removed');
197 ###############################################################################
198 # A _NET_WM_DESKTOP client message sent to the root window moves a window
199 # to the correct workspace.
200 ###############################################################################
209 is_num_children('0', 2, 'The window is on workspace 0');
211 send_net_wm_desktop($con, 1);
213 is_num_children('0', 1, 'The window is no longer on workspace 0');
214 is_num_children('1', 2, 'The window is now on workspace 1');
215 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated');
219 ###############################################################################
220 # A _NET_WM_DESKTOP client message sent to the root window can make a window
222 ###############################################################################
227 send_net_wm_desktop($con, 0xFFFFFFFF);
229 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
230 is(@{get_ws('0')->{floating_nodes}}, 1, 'The window is floating');
231 ok(get_ws('0')->{floating_nodes}->[0]->{nodes}->[0]->{sticky}, 'The window is sticky');
235 ###############################################################################
236 # _NET_WM_DESKTOP is updated when a new workspace with a lower number is
238 ###############################################################################
242 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
245 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated');
249 ###############################################################################
250 # _NET_WM_DESKTOP is updated when a window is made sticky by command.
251 ###############################################################################
255 cmd 'floating enable';
256 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
259 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
263 ###############################################################################
264 # _NET_WM_DESKTOP is updated when a window is made sticky by client message.
265 ###############################################################################
269 cmd 'floating enable';
270 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
272 my $msg = pack "CCSLLLLLL",
273 X11::XCB::CLIENT_MESSAGE, 32, 0,
275 $x->atom(name => '_NET_WM_STATE')->id,
277 $x->atom(name => '_NET_WM_STATE_STICKY')->id,
280 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
283 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
287 ###############################################################################
288 # _NET_WM_DESKTOP is updated when a window is moved to the scratchpad.
289 ###############################################################################
293 cmd 'floating enable';
294 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
296 cmd 'move scratchpad';
297 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
299 cmd 'scratchpad show';
300 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
304 ###############################################################################
306 exit_gracefully($pid);