2 # vim:ts=4:sw=4:expandtab
3 # !NO_I3_INSTANCE! will prevent complete-run.pl from starting i3
7 use X11::XCB qw(PROP_MODE_REPLACE);
9 ##############################################################
10 # 1: test the following directive:
11 # for_window [class="borderless"] border none
12 # by first creating a window with a different class (should get
13 # the normal border), then creating a window with the class
14 # "borderless" (should get no border)
15 ##############################################################
19 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
20 for_window [class="borderless"] border none
21 for_window [title="special borderless title"] border none
24 my $pid = launch_with_config($config);
26 my $tmp = fresh_workspace;
28 my $window = open_window(name => 'Border window');
30 my @content = @{get_ws_content($tmp)};
31 cmp_ok(@content, '==', 1, 'one node on this workspace now');
32 is($content[0]->{border}, 'normal', 'normal border');
35 wait_for_unmap $window;
37 @content = @{get_ws_content($tmp)};
38 cmp_ok(@content, '==', 0, 'no more nodes');
39 diag('content = '. Dumper(\@content));
42 # TODO: move this to X11::XCB::Window
44 my ($id, $class, $instance) = @_;
46 # Add a _NET_WM_STRUT_PARTIAL hint
47 my $atomname = $x->atom(name => 'WM_CLASS');
48 my $atomtype = $x->atom(name => 'STRING');
56 length($class) + length($instance) + 2,
57 "$instance\x00$class\x00"
61 $window = open_window(
62 name => 'Borderless window',
63 before_map => sub { set_wm_class($_->id, 'borderless', 'borderless') },
66 @content = @{get_ws_content($tmp)};
67 cmp_ok(@content, '==', 1, 'one node on this workspace now');
68 is($content[0]->{border}, 'none', 'no border');
71 wait_for_unmap $window;
73 @content = @{get_ws_content($tmp)};
74 cmp_ok(@content, '==', 0, 'no more nodes');
76 exit_gracefully($pid);
78 ##############################################################
79 # 2: match on the title, check if for_window is really executed
81 ##############################################################
85 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
86 for_window [class="borderless"] border none
87 for_window [title="special borderless title"] border none
90 $pid = launch_with_config($config);
92 $tmp = fresh_workspace;
94 $window = open_window(name => 'special title');
96 @content = @{get_ws_content($tmp)};
97 cmp_ok(@content, '==', 1, 'one node on this workspace now');
98 is($content[0]->{border}, 'normal', 'normal border');
100 $window->name('special borderless title');
103 @content = @{get_ws_content($tmp)};
104 is($content[0]->{border}, 'none', 'no border');
106 $window->name('special title');
111 @content = @{get_ws_content($tmp)};
112 is($content[0]->{border}, 'normal', 'border reset to normal');
114 $window->name('special borderless title');
117 @content = @{get_ws_content($tmp)};
118 is($content[0]->{border}, 'normal', 'still normal border');
121 wait_for_unmap $window;
123 @content = @{get_ws_content($tmp)};
124 cmp_ok(@content, '==', 0, 'no more nodes');
126 exit_gracefully($pid);
128 ##############################################################
129 # 3: match on the title, set border style *and* a mark
130 ##############################################################
133 # i3 config file (v4)
134 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
135 for_window [class="borderless" title="usethis"] border none
136 for_window [class="borderless"] border none
137 for_window [title="special borderless title"] border none
138 for_window [title="special mark title"] border none, mark bleh
141 $pid = launch_with_config($config);
143 $tmp = fresh_workspace;
145 $window = open_window(name => 'special mark title');
147 @content = @{get_ws_content($tmp)};
148 cmp_ok(@content, '==', 1, 'one node on this workspace now');
149 is($content[0]->{border}, 'none', 'no border');
151 my $other = open_window;
153 @content = @{get_ws_content($tmp)};
154 cmp_ok(@content, '==', 2, 'two nodes');
155 is($content[0]->{border}, 'none', 'no border');
156 is($content[1]->{border}, 'normal', 'normal border');
157 ok(!$content[0]->{focused}, 'first one not focused');
159 cmd qq|[con_mark="bleh"] focus|;
161 @content = @{get_ws_content($tmp)};
162 ok($content[0]->{focused}, 'first node focused');
164 exit_gracefully($pid);
166 ##############################################################
167 # 4: multiple criteria for the for_window command
168 ##############################################################
171 # i3 config file (v4)
172 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
173 for_window [class="borderless" title="usethis"] border none
176 $pid = launch_with_config($config);
178 $tmp = fresh_workspace;
180 $window = open_window(
182 before_map => sub { set_wm_class($_->id, 'borderless', 'borderless') },
185 @content = @{get_ws_content($tmp)};
186 cmp_ok(@content, '==', 1, 'one node on this workspace now');
187 is($content[0]->{border}, 'none', 'no border');
190 wait_for_unmap $window;
193 # give i3 a chance to delete the window from its tree
196 @content = @{get_ws_content($tmp)};
197 cmp_ok(@content, '==', 0, 'no nodes on this workspace now');
201 set_wm_class($window->id, 'borderless', 'borderless');
202 $window->name('notthis');
204 wait_for_map $window;
206 @content = @{get_ws_content($tmp)};
207 cmp_ok(@content, '==', 1, 'one node on this workspace now');
208 is($content[0]->{border}, 'normal', 'no border');
211 exit_gracefully($pid);
213 ##############################################################
214 # 5: check that a class criterion does not match the instance
215 ##############################################################
218 # i3 config file (v4)
219 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
220 for_window [class="foo"] border 1pixel
223 $pid = launch_with_config($config);
225 $tmp = fresh_workspace;
228 $window = open_window(
230 before_map => sub { set_wm_class($_->id, 'bar', 'foo') },
233 @content = @{get_ws_content($tmp)};
234 cmp_ok(@content, '==', 1, 'one node on this workspace now');
235 is($content[0]->{border}, 'normal', 'normal border, not matched');
237 exit_gracefully($pid);
239 ##############################################################
240 # 6: check that the 'instance' criterion works
241 ##############################################################
244 # i3 config file (v4)
245 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
246 for_window [class="foo"] border 1pixel
247 for_window [instance="foo"] border none
250 $pid = launch_with_config($config);
252 $tmp = fresh_workspace;
254 $window = open_window(
256 before_map => sub { set_wm_class($_->id, 'bar', 'foo') },
259 @content = @{get_ws_content($tmp)};
260 cmp_ok(@content, '==', 1, 'one node on this workspace now');
261 is($content[0]->{border}, 'none', 'no border');
263 exit_gracefully($pid);
265 ##############################################################
266 # 7: check that invalid criteria don’t end up matching all windows
267 ##############################################################
269 # this configuration is broken because "asdf" is not a valid integer
270 # the for_window should therefore recognize this error and don’t add the
273 # i3 config file (v4)
274 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
275 for_window [id="asdf"] border none
278 $pid = launch_with_config($config);
280 $tmp = fresh_workspace;
282 $window = open_window(
284 before_map => sub { set_wm_class($_->id, 'bar', 'foo') },
287 @content = @{get_ws_content($tmp)};
288 cmp_ok(@content, '==', 1, 'one node on this workspace now');
289 is($content[0]->{border}, 'normal', 'normal border');
291 exit_gracefully($pid);
293 ##############################################################
294 # 8: check that the role criterion works properly
295 ##############################################################
297 # this configuration is broken because "asdf" is not a valid integer
298 # the for_window should therefore recognize this error and don’t add the
301 # i3 config file (v4)
302 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
303 for_window [window_role="i3test"] border none
306 $pid = launch_with_config($config);
308 $tmp = fresh_workspace;
310 $window = open_window(
314 my $atomname = $x->atom(name => 'WM_WINDOW_ROLE');
315 my $atomtype = $x->atom(name => 'STRING');
322 length("i3test") + 1,
328 @content = @{get_ws_content($tmp)};
329 cmp_ok(@content, '==', 1, 'one node on this workspace now');
330 is($content[0]->{border}, 'none', 'no border (window_role)');
332 exit_gracefully($pid);
334 ##############################################################
335 # 9: another test for the window_role, but this time it changes
336 # *after* the window has been mapped
337 ##############################################################
339 # this configuration is broken because "asdf" is not a valid integer
340 # the for_window should therefore recognize this error and don’t add the
343 # i3 config file (v4)
344 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
345 for_window [window_role="i3test"] border none
348 $pid = launch_with_config($config);
350 $tmp = fresh_workspace;
352 $window = open_window(name => 'usethis');
354 @content = @{get_ws_content($tmp)};
355 cmp_ok(@content, '==', 1, 'one node on this workspace now');
356 is($content[0]->{border}, 'normal', 'normal border (window_role 2)');
358 my $atomname = $x->atom(name => 'WM_WINDOW_ROLE');
359 my $atomtype = $x->atom(name => 'STRING');
366 length("i3test") + 1,
374 @content = @{get_ws_content($tmp)};
375 cmp_ok(@content, '==', 1, 'one node on this workspace now');
376 is($content[0]->{border}, 'none', 'no border (window_role 2)');
378 exit_gracefully($pid);