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)
17 # Tests for _NET_WM_DESKTOP.
19 use i3test i3_config => <<EOT;
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
24 status_command i3status
27 use X11::XCB qw(:all);
29 ###############################################################################
31 sub get_net_wm_desktop {
35 my $cookie = $x->get_property(
38 $x->atom(name => '_NET_WM_DESKTOP')->id,
39 $x->atom(name => 'CARDINAL')->id,
44 my $reply = $x->get_property_reply($cookie->{sequence});
45 return undef if $reply->{length} != 1;
47 return unpack("L", $reply->{value});
50 sub send_net_wm_desktop {
52 my $msg = pack "CCSLLLLLL",
53 X11::XCB::CLIENT_MESSAGE, 32, 0,
55 $x->atom(name => '_NET_WM_DESKTOP')->id,
58 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
62 sub open_window_with_net_wm_desktop {
64 my $window = open_window(
70 $x->atom(name => '_NET_WM_DESKTOP')->id,
71 $x->atom(name => 'CARDINAL')->id,
79 # We don’t wait for MapNotify and instead sync with i3 so that we don’t need
80 # to encounter the full timeout of 4s when opening a window on a non-visible
88 ###############################################################################
89 # Upon managing a window which does not set _NET_WM_DESKTOP, the property is
91 ###############################################################################
94 my $con = open_window;
96 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set upon managing a window');
100 ###############################################################################
101 # Upon managing a window which sets _NET_WM_DESKTOP, the window is moved to
102 # the specified desktop.
103 ###############################################################################
112 $con = open_window_with_net_wm_desktop(1);
114 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP still has the correct value');
115 is_num_children('1', 2, 'The window was moved to workspace 1');
119 ###############################################################################
120 # Upon managing a window which sets _NET_WM_DESKTOP to the appropriate value,
121 # the window is made sticky and floating.
122 ###############################################################################
125 $con = open_window_with_net_wm_desktop(0xFFFFFFFF);
127 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP still has the correct value');
128 is(@{get_ws('0')->{floating_nodes}}, 1, 'The window is floating');
129 ok(get_ws('0')->{floating_nodes}->[0]->{nodes}->[0]->{sticky}, 'The window is sticky');
133 ###############################################################################
134 # _NET_WM_DESKTOP is updated when the window is moved to another workspace
135 # on the same output.
136 ###############################################################################
145 cmd 'move window to workspace 1';
147 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated when moving the window');
151 ###############################################################################
152 # _NET_WM_DESKTOP is updated when the floating window is moved to another
153 # workspace on the same output.
154 ###############################################################################
162 cmd 'floating enable';
164 cmd 'move window to workspace 1';
166 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated when moving the window');
170 ###############################################################################
171 # _NET_WM_DESKTOP is removed when the window is withdrawn.
172 ###############################################################################
175 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set (sanity check)');
178 wait_for_unmap($con);
180 is(get_net_wm_desktop($con), undef, '_NET_WM_DESKTOP is removed');
184 ###############################################################################
185 # A _NET_WM_DESKTOP client message sent to the root window moves a window
186 # to the correct workspace.
187 ###############################################################################
196 is_num_children('0', 2, 'The window is on workspace 0');
198 send_net_wm_desktop($con, 1);
200 is_num_children('0', 1, 'The window is no longer on workspace 0');
201 is_num_children('1', 2, 'The window is now on workspace 1');
202 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated');
206 ###############################################################################
207 # A _NET_WM_DESKTOP client message sent to the root window can make a window
209 ###############################################################################
214 send_net_wm_desktop($con, 0xFFFFFFFF);
216 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
217 is(@{get_ws('0')->{floating_nodes}}, 1, 'The window is floating');
218 ok(get_ws('0')->{floating_nodes}->[0]->{nodes}->[0]->{sticky}, 'The window is sticky');
222 ###############################################################################
223 # _NET_WM_DESKTOP is updated when a new workspace with a lower number is
225 ###############################################################################
229 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
232 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated');
236 ###############################################################################
237 # _NET_WM_DESKTOP is updated when a window is made sticky by command.
238 ###############################################################################
242 cmd 'floating enable';
243 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
246 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
250 ###############################################################################
251 # _NET_WM_DESKTOP is updated when a window is made sticky by client message.
252 ###############################################################################
256 cmd 'floating enable';
257 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
259 my $msg = pack "CCSLLLLLL",
260 X11::XCB::CLIENT_MESSAGE, 32, 0,
262 $x->atom(name => '_NET_WM_STATE')->id,
264 $x->atom(name => '_NET_WM_STATE_STICKY')->id,
267 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
270 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
274 ###############################################################################
275 # _NET_WM_DESKTOP is updated when a window is moved to the scratchpad.
276 ###############################################################################
280 cmd 'floating enable';
281 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
283 cmd 'move scratchpad';
284 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
286 cmd 'scratchpad show';
287 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
291 ###############################################################################