]> git.sur5r.net Git - i3/i3/blob - testcases/t/529-net-wm-desktop.t
Kill windows between tests
[i3/i3] / testcases / t / 529-net-wm-desktop.t
1 #!perl
2 # vim:ts=4:sw=4:expandtab
3 #
4 # Please read the following documents before working on tests:
5 # • http://build.i3wm.org/docs/testsuite.html
6 #   (or docs/testsuite)
7 #
8 # • http://build.i3wm.org/docs/lib-i3test.html
9 #   (alternatively: perldoc ./testcases/lib/i3test.pm)
10 #
11 # • http://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 # Tests for _NET_WM_DESKTOP.
18 # Ticket: #2153
19 use i3test i3_autostart => 0;
20 use X11::XCB qw(:all);
21
22 ###############################################################################
23
24 sub get_net_wm_desktop {
25     sync_with_i3;
26
27     my ($con) = @_; 
28     my $cookie = $x->get_property(
29         0,  
30         $con->{id},
31         $x->atom(name => '_NET_WM_DESKTOP')->id,
32         $x->atom(name => 'CARDINAL')->id,
33         0,  
34         1
35     );  
36
37     my $reply = $x->get_property_reply($cookie->{sequence});
38     return undef if $reply->{length} != 1;
39
40     return unpack("L", $reply->{value});
41 }
42
43 sub send_net_wm_desktop {
44     my ($con, $idx) = @_;
45     my $msg = pack "CCSLLLLLL",
46         X11::XCB::CLIENT_MESSAGE, 32, 0,
47         $con->{id},
48         $x->atom(name => '_NET_WM_DESKTOP')->id,
49         $idx, 0, 0, 0, 0;
50
51     $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
52     sync_with_i3;
53 }
54
55 sub open_window_with_net_wm_desktop {
56     my $idx = shift;
57     my $window = open_window(
58         before_map => sub {
59             my ($window) = @_;
60             $x->change_property(
61                 PROP_MODE_REPLACE,
62                 $window->id,
63                 $x->atom(name => '_NET_WM_DESKTOP')->id,
64                 $x->atom(name => 'CARDINAL')->id,
65                 32, 1,
66                 pack('L', $idx),
67             );
68         },
69         dont_map => 1,
70     );
71
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
74     # workspace.
75     $window->map;
76     sync_with_i3;
77
78     return $window;
79 }
80
81 ###############################################################################
82
83 my $config = <<EOT;
84 # i3 config file (v4)
85 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
86
87 bar {
88     status_command i3status
89 }
90 EOT
91
92 my $pid = launch_with_config($config);
93
94 ###############################################################################
95 # Upon managing a window which does not set _NET_WM_DESKTOP, the property is
96 # set on the window.
97 ###############################################################################
98
99 cmd 'workspace 1';
100 my $con = open_window;
101
102 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set upon managing a window');
103
104 kill_all_windows;
105
106 ###############################################################################
107 # Upon managing a window which sets _NET_WM_DESKTOP, the window is moved to
108 # the specified desktop.
109 ###############################################################################
110
111 cmd 'workspace 0';
112 open_window;
113 cmd 'workspace 1';
114 open_window;
115 cmd 'workspace 2';
116 open_window;
117
118 $con = open_window_with_net_wm_desktop(1);
119
120 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP still has the correct value');
121 is_num_children('1', 2, 'The window was moved to workspace 1');
122
123 kill_all_windows;
124
125 ###############################################################################
126 # Upon managing a window which sets _NET_WM_DESKTOP to the appropriate value,
127 # the window is made sticky and floating.
128 ###############################################################################
129
130 cmd 'workspace 0';
131 $con = open_window_with_net_wm_desktop(0xFFFFFFFF);
132
133 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP still has the correct value');
134 is(@{get_ws('0')->{floating_nodes}}, 1, 'The window is floating');
135 ok(get_ws('0')->{floating_nodes}->[0]->{nodes}->[0]->{sticky}, 'The window is sticky');
136
137 kill_all_windows;
138
139 ###############################################################################
140 # _NET_WM_DESKTOP is updated when the window is moved to another workspace
141 # on the same output.
142 ###############################################################################
143
144 cmd 'workspace 0';
145 open_window;
146 cmd 'workspace 1';
147 open_window;
148 cmd 'workspace 0';
149 $con = open_window;
150
151 cmd 'move window to workspace 1';
152
153 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated when moving the window');
154
155 kill_all_windows;
156
157 ###############################################################################
158 # _NET_WM_DESKTOP is updated when the floating window is moved to another
159 # workspace on the same output.
160 ###############################################################################
161
162 cmd 'workspace 0';
163 open_window;
164 cmd 'workspace 1';
165 open_window;
166 cmd 'workspace 0';
167 $con = open_window;
168 cmd 'floating enable';
169
170 cmd 'move window to workspace 1';
171
172 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated when moving the window');
173
174 kill_all_windows;
175
176 ###############################################################################
177 # _NET_WM_DESKTOP is removed when the window is withdrawn.
178 ###############################################################################
179
180 $con = open_window;
181 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set (sanity check)');
182
183 $con->unmap;
184 wait_for_unmap($con);
185
186 is(get_net_wm_desktop($con), undef, '_NET_WM_DESKTOP is removed');
187
188 kill_all_windows;
189
190 ###############################################################################
191 # A _NET_WM_DESKTOP client message sent to the root window moves a window
192 # to the correct workspace.
193 ###############################################################################
194
195 cmd 'workspace 0';
196 open_window;
197 cmd 'workspace 1';
198 open_window;
199 cmd 'workspace 0';
200
201 $con = open_window;
202 is_num_children('0', 2, 'The window is on workspace 0');
203
204 send_net_wm_desktop($con, 1);
205
206 is_num_children('0', 1, 'The window is no longer on workspace 0');
207 is_num_children('1', 2, 'The window is now on workspace 1');
208 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated');
209
210 kill_all_windows;
211
212 ###############################################################################
213 # A _NET_WM_DESKTOP client message sent to the root window can make a window
214 # sticky.
215 ###############################################################################
216
217 cmd 'workspace 0';
218 $con = open_window;
219
220 send_net_wm_desktop($con, 0xFFFFFFFF);
221
222 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
223 is(@{get_ws('0')->{floating_nodes}}, 1, 'The window is floating');
224 ok(get_ws('0')->{floating_nodes}->[0]->{nodes}->[0]->{sticky}, 'The window is sticky');
225
226 kill_all_windows;
227
228 ###############################################################################
229 # _NET_WM_DESKTOP is updated when a new workspace with a lower number is
230 # opened and closed.
231 ###############################################################################
232
233 cmd 'workspace 1';
234 $con = open_window;
235 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
236
237 cmd 'workspace 0';
238 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated');
239
240 kill_all_windows;
241
242 ###############################################################################
243 # _NET_WM_DESKTOP is updated when a window is made sticky by command.
244 ###############################################################################
245
246 cmd 'workspace 0';
247 $con = open_window;
248 cmd 'floating enable';
249 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
250
251 cmd 'sticky enable';
252 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
253
254 kill_all_windows;
255
256 ###############################################################################
257 # _NET_WM_DESKTOP is updated when a window is made sticky by client message.
258 ###############################################################################
259
260 cmd 'workspace 0';
261 $con = open_window;
262 cmd 'floating enable';
263 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
264
265 my $msg = pack "CCSLLLLLL",
266     X11::XCB::CLIENT_MESSAGE, 32, 0,
267     $con->{id},
268     $x->atom(name => '_NET_WM_STATE')->id,
269     1,
270     $x->atom(name => '_NET_WM_STATE_STICKY')->id,
271     0, 0, 0;
272
273 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
274 sync_with_i3;
275
276 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
277
278 kill_all_windows;
279
280 ###############################################################################
281 # _NET_WM_DESKTOP is updated when a window is moved to the scratchpad.
282 ###############################################################################
283
284 cmd 'workspace 0';
285 $con = open_window;
286 cmd 'floating enable';
287 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
288
289 cmd 'move scratchpad';
290 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
291
292 cmd 'scratchpad show';
293 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
294
295 kill_all_windows;
296
297 ###############################################################################
298
299 exit_gracefully($pid);
300
301 done_testing;