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 use i3test i3_autostart => 0;
18 use List::Util qw(first);
20 my $_NET_WM_STATE_REMOVE = 0;
21 my $_NET_WM_STATE_ADD = 1;
22 my $_NET_WM_STATE_TOGGLE = 2;
25 my ($win, $urgent_flag, $type) = @_;
27 $win->add_hint('urgency') if ($urgent_flag);
28 $win->delete_hint('urgency') if (!$urgent_flag);
29 } elsif ($type == 2) {
30 my $msg = pack "CCSLLLLLL",
31 X11::XCB::CLIENT_MESSAGE, # response_type
35 $x->atom(name => '_NET_WM_STATE')->id, # message type
36 ($urgent_flag ? $_NET_WM_STATE_ADD : $_NET_WM_STATE_REMOVE), # data32[0]
37 $x->atom(name => '_NET_WM_STATE_DEMANDS_ATTENTION')->id, # data32[1]
42 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
48 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
50 force_display_urgency_hint 0ms
54 for ($type = 1; $type <= 2; $type++) {
55 my $pid = launch_with_config($config);
56 my $tmp = fresh_workspace;
58 #####################################################################
59 # Create two windows and put them in stacking mode
60 #####################################################################
64 my $top = open_window;
65 my $bottom = open_window;
67 my @urgent = grep { $_->{urgent} } @{get_ws_content($tmp)};
68 is(@urgent, 0, 'no window got the urgent flag');
70 # cmd 'layout stacking';
72 #####################################################################
73 # Add the urgency hint, switch to a different workspace and back again
74 #####################################################################
75 set_urgency($top, 1, $type);
78 my @content = @{get_ws_content($tmp)};
79 @urgent = grep { $_->{urgent} } @content;
80 my $top_info = first { $_->{window} == $top->id } @content;
81 my $bottom_info = first { $_->{window} == $bottom->id } @content;
83 ok($top_info->{urgent}, 'top window is marked urgent');
84 ok(!$bottom_info->{urgent}, 'bottom window is not marked urgent');
85 is(@urgent, 1, 'exactly one window got the urgent flag');
87 cmd '[id="' . $top->id . '"] focus';
89 @urgent = grep { $_->{urgent} } @{get_ws_content($tmp)};
90 is(@urgent, 0, 'no window got the urgent flag after focusing');
92 set_urgency($top, 1, $type);
95 @urgent = grep { $_->{urgent} } @{get_ws_content($tmp)};
96 is(@urgent, 0, 'no window got the urgent flag after re-setting urgency hint');
98 #####################################################################
99 # Check if the workspace urgency hint gets set/cleared correctly
100 #####################################################################
102 my $ws = get_ws($tmp);
103 ok(!$ws->{urgent}, 'urgent flag not set on workspace');
105 my $otmp = fresh_workspace;
107 set_urgency($top, 1, $type);
111 ok($ws->{urgent}, 'urgent flag set on workspace');
113 cmd "workspace $tmp";
116 ok(!$ws->{urgent}, 'urgent flag not set on workspace after switching');
118 ################################################################################
119 # Use the 'urgent' criteria to switch to windows which have the urgency hint set.
120 ################################################################################
122 # Go to a new workspace, open a different window, verify focus is on it.
123 $otmp = fresh_workspace;
124 my $different_window = open_window;
125 is($x->input_focus, $different_window->id, 'new window focused');
127 # Add the urgency hint on the other window.
128 set_urgency($top, 1, $type);
131 # Now try to switch to that window and see if focus changes.
132 cmd '[urgent=latest] focus';
133 isnt($x->input_focus, $different_window->id, 'window no longer focused');
134 is($x->input_focus, $top->id, 'urgent window focused');
136 ################################################################################
137 # Same thing, but with multiple windows and using the 'urgency=latest' criteria
138 # (verify that it works in the correct order).
139 ################################################################################
141 cmd "workspace $otmp";
142 is($x->input_focus, $different_window->id, 'new window focused again');
144 set_urgency($top, 1, $type);
147 set_urgency($bottom, 1, $type);
150 cmd '[urgent=latest] focus';
151 is($x->input_focus, $bottom->id, 'latest urgent window focused');
152 set_urgency($bottom, 0, $type);
155 cmd '[urgent=latest] focus';
156 is($x->input_focus, $top->id, 'second urgent window focused');
157 set_urgency($top, 0, $type);
160 ################################################################################
161 # Same thing, but with multiple windows and using the 'urgency=oldest' criteria
162 # (verify that it works in the correct order).
163 ################################################################################
165 cmd "workspace $otmp";
166 is($x->input_focus, $different_window->id, 'new window focused again');
168 set_urgency($top, 1, $type);
171 set_urgency($bottom, 1, $type);
174 cmd '[urgent=oldest] focus';
175 is($x->input_focus, $top->id, 'oldest urgent window focused');
176 set_urgency($top, 0, $type);
179 cmd '[urgent=oldest] focus';
180 is($x->input_focus, $bottom->id, 'oldest urgent window focused');
181 set_urgency($bottom, 0, $type);
184 ################################################################################
185 # Check if urgent flag gets propagated to parent containers
186 ################################################################################
195 my @children = (@{$con->{nodes}}, @{$con->{floating_nodes}});
196 my $urgent = grep { $_->{urgent} } @children;
197 $urgent += count_urgent($_) for @children;
201 $tmp = fresh_workspace;
203 my $win1 = open_window;
204 my $win2 = open_window;
205 cmd 'layout stacked';
206 cmd 'split vertical';
207 my $win3 = open_window;
208 my $win4 = open_window;
209 cmd 'split horizontal' ;
210 my $win5 = open_window;
211 my $win6 = open_window;
216 my $urgent = count_urgent(get_ws($tmp));
217 is($urgent, 0, 'no window got the urgent flag');
219 cmd '[id="' . $win2->id . '"] focus';
221 set_urgency($win5, 1, $type);
222 set_urgency($win6, 1, $type);
225 # we should have 5 urgent cons. win5, win6 and their 3 split parents.
227 $urgent = count_urgent(get_ws($tmp));
228 is($urgent, 5, '2 windows and 3 split containers got the urgent flag');
230 cmd '[id="' . $win5->id . '"] focus';
233 # now win5 and still the split parents should be urgent.
234 $urgent = count_urgent(get_ws($tmp));
235 is($urgent, 4, '1 window and 3 split containers got the urgent flag');
237 cmd '[id="' . $win6->id . '"] focus';
240 # now now window should be urgent.
241 $urgent = count_urgent(get_ws($tmp));
242 is($urgent, 0, 'All urgent flags got cleared');
244 ################################################################################
245 # Regression test: Check that urgent floating containers work properly (ticket
247 ################################################################################
249 $tmp = fresh_workspace;
250 my $floating_win = open_floating_window;
255 set_urgency($floating_win, 1, $type);
258 cmd "workspace $tmp";
262 ###############################################################################
263 # Check if the urgency hint is still set when the urgent window is killed
264 ###############################################################################
266 my $ws1 = fresh_workspace;
267 my $ws2 = fresh_workspace;
268 cmd "workspace $ws1";
269 my $w1 = open_window;
270 my $w2 = open_window;
271 cmd "workspace $ws2";
273 set_urgency($w1, 1, $type);
275 cmd '[id="' . $w1->id . '"] kill';
277 my $w = get_ws($ws1);
278 is($w->{urgent}, 0, 'Urgent flag no longer set after killing the window ' .
279 'from another workspace');
281 ##############################################################################
282 # Check if urgent flag can be unset if we move the window out of the container
283 ##############################################################################
284 my $tmp = fresh_workspace;
286 my $w1 = open_window;
287 my $w2 = open_window;
289 cmd '[id="' . $w2->id . '"] focus';
292 cmd 'layout stacked';
293 my $w3 = open_window;
295 cmd '[id="' . $w2->id . '"] focus';
297 set_urgency($w3, 1, $type);
302 cmd '[id="' . $w3->id . '"] focus';
304 my $ws = get_ws($tmp);
305 ok(!$ws->{urgent}, 'urgent flag not set on workspace');
307 exit_gracefully($pid);