2 # vim:ts=4:sw=4:expandtab
3 # !NO_I3_INSTANCE! will prevent complete-run.pl from starting i3
7 use X11::XCB::Connection;
10 my $x = X11::XCB::Connection->new;
12 ##############################################################
13 # 1: test the following directive:
14 # for_window [class="borderless"] border none
15 # by first creating a window with a different class (should get
16 # the normal border), then creating a window with the class
17 # "borderless" (should get no border)
18 ##############################################################
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23 for_window [class="borderless"] border none
24 for_window [title="special borderless title"] border none
27 my $process = launch_with_config($config);
29 my $tmp = fresh_workspace;
31 my $window = $x->root->create_child(
32 class => WINDOW_CLASS_INPUT_OUTPUT,
33 rect => [ 0, 0, 30, 30 ],
34 background_color => '#00ff00',
35 event_mask => [ 'structure_notify' ],
38 $window->name('Border window');
42 my @content = @{get_ws_content($tmp)};
43 cmp_ok(@content, '==', 1, 'one node on this workspace now');
44 is($content[0]->{border}, 'normal', 'normal border');
49 my @content = @{get_ws_content($tmp)};
50 cmp_ok(@content, '==', 0, 'no more nodes');
51 diag('content = '. Dumper(\@content));
53 $window = $x->root->create_child(
54 class => WINDOW_CLASS_INPUT_OUTPUT,
55 rect => [ 0, 0, 30, 30 ],
56 background_color => '#00ff00',
57 event_mask => [ 'structure_notify' ],
62 # TODO: move this to X11::XCB::Window
64 my ($id, $class, $instance) = @_;
66 # Add a _NET_WM_STRUT_PARTIAL hint
67 my $atomname = $x->atom(name => 'WM_CLASS');
68 my $atomtype = $x->atom(name => 'STRING');
76 length($class) + length($instance) + 2,
77 "$instance\x00$class\x00"
81 set_wm_class($window->id, 'borderless', 'borderless');
82 $window->name('Borderless window');
86 @content = @{get_ws_content($tmp)};
87 cmp_ok(@content, '==', 1, 'one node on this workspace now');
88 is($content[0]->{border}, 'none', 'no border');
93 @content = @{get_ws_content($tmp)};
94 cmp_ok(@content, '==', 0, 'no more nodes');
96 exit_gracefully($process->pid);
98 ##############################################################
99 # 2: match on the title, check if for_window is really executed
101 ##############################################################
104 # i3 config file (v4)
105 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
106 for_window [class="borderless"] border none
107 for_window [title="special borderless title"] border none
110 $process = launch_with_config($config);
112 $tmp = fresh_workspace;
114 $window = $x->root->create_child(
115 class => WINDOW_CLASS_INPUT_OUTPUT,
116 rect => [ 0, 0, 30, 30 ],
117 background_color => '#00ff00',
118 event_mask => [ 'structure_notify' ],
121 $window->name('special title');
125 @content = @{get_ws_content($tmp)};
126 cmp_ok(@content, '==', 1, 'one node on this workspace now');
127 is($content[0]->{border}, 'normal', 'normal border');
129 $window->name('special borderless title');
132 @content = @{get_ws_content($tmp)};
133 is($content[0]->{border}, 'none', 'no border');
135 $window->name('special title');
140 @content = @{get_ws_content($tmp)};
141 is($content[0]->{border}, 'normal', 'border reset to normal');
143 $window->name('special borderless title');
146 @content = @{get_ws_content($tmp)};
147 is($content[0]->{border}, 'normal', 'still normal border');
152 @content = @{get_ws_content($tmp)};
153 cmp_ok(@content, '==', 0, 'no more nodes');
155 exit_gracefully($process->pid);
157 ##############################################################
158 # 3: match on the title, set border style *and* a mark
159 ##############################################################
162 # i3 config file (v4)
163 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
164 for_window [class="borderless" title="usethis"] border none
165 for_window [class="borderless"] border none
166 for_window [title="special borderless title"] border none
167 for_window [title="special mark title"] border none, mark bleh
170 $process = launch_with_config($config);
172 $tmp = fresh_workspace;
174 $window = $x->root->create_child(
175 class => WINDOW_CLASS_INPUT_OUTPUT,
176 rect => [ 0, 0, 30, 30 ],
177 background_color => '#00ff00',
178 event_mask => [ 'structure_notify' ],
181 $window->name('special mark title');
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');
189 my $other = open_standard_window($x);
191 @content = @{get_ws_content($tmp)};
192 cmp_ok(@content, '==', 2, 'two nodes');
193 is($content[0]->{border}, 'none', 'no border');
194 is($content[1]->{border}, 'normal', 'normal border');
195 ok(!$content[0]->{focused}, 'first one not focused');
197 cmd qq|[con_mark="bleh"] focus|;
199 @content = @{get_ws_content($tmp)};
200 ok($content[0]->{focused}, 'first node focused');
202 exit_gracefully($process->pid);
204 ##############################################################
205 # 4: multiple criteria for the for_window command
206 ##############################################################
209 # i3 config file (v4)
210 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
211 for_window [class="borderless" title="usethis"] border none
214 $process = launch_with_config($config);
216 $tmp = fresh_workspace;
218 $window = $x->root->create_child(
219 class => WINDOW_CLASS_INPUT_OUTPUT,
220 rect => [ 0, 0, 30, 30 ],
221 background_color => '#00ff00',
222 event_mask => [ 'structure_notify' ],
227 set_wm_class($window->id, 'borderless', 'borderless');
228 $window->name('usethis');
232 @content = @{get_ws_content($tmp)};
233 cmp_ok(@content, '==', 1, 'one node on this workspace now');
234 is($content[0]->{border}, 'none', 'no border');
239 @content = @{get_ws_content($tmp)};
240 cmp_ok(@content, '==', 0, 'no nodes on this workspace now');
242 set_wm_class($window->id, 'borderless', 'borderless');
243 $window->name('notthis');
247 @content = @{get_ws_content($tmp)};
248 cmp_ok(@content, '==', 1, 'one node on this workspace now');
249 is($content[0]->{border}, 'normal', 'no border');
252 exit_gracefully($process->pid);
254 ##############################################################
255 # 5: check that a class criterion does not match the instance
256 ##############################################################
259 # i3 config file (v4)
260 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
261 for_window [class="foo"] border 1pixel
264 $process = launch_with_config($config);
266 $tmp = fresh_workspace;
268 $window = $x->root->create_child(
269 class => WINDOW_CLASS_INPUT_OUTPUT,
270 rect => [ 0, 0, 30, 30 ],
271 background_color => '#00ff00',
272 event_mask => [ 'structure_notify' ],
277 set_wm_class($window->id, 'bar', 'foo');
278 $window->name('usethis');
282 @content = @{get_ws_content($tmp)};
283 cmp_ok(@content, '==', 1, 'one node on this workspace now');
284 is($content[0]->{border}, 'normal', 'normal border, not matched');
286 exit_gracefully($process->pid);
288 ##############################################################
289 # 6: check that the 'instance' criterion works
290 ##############################################################
293 # i3 config file (v4)
294 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
295 for_window [class="foo"] border 1pixel
296 for_window [instance="foo"] border none
299 $process = launch_with_config($config);
301 $tmp = fresh_workspace;
303 $window = $x->root->create_child(
304 class => WINDOW_CLASS_INPUT_OUTPUT,
305 rect => [ 0, 0, 30, 30 ],
306 background_color => '#00ff00',
307 event_mask => [ 'structure_notify' ],
312 set_wm_class($window->id, 'bar', 'foo');
313 $window->name('usethis');
317 @content = @{get_ws_content($tmp)};
318 cmp_ok(@content, '==', 1, 'one node on this workspace now');
319 is($content[0]->{border}, 'none', 'no border');
321 exit_gracefully($process->pid);
323 ##############################################################
324 # 7: check that invalid criteria don’t end up matching all windows
325 ##############################################################
327 # this configuration is broken because "asdf" is not a valid integer
328 # the for_window should therefore recognize this error and don’t add the
331 # i3 config file (v4)
332 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
333 for_window [id="asdf"] border none
336 $process = launch_with_config($config);
338 $tmp = fresh_workspace;
340 $window = $x->root->create_child(
341 class => WINDOW_CLASS_INPUT_OUTPUT,
342 rect => [ 0, 0, 30, 30 ],
343 background_color => '#00ff00',
344 event_mask => [ 'structure_notify' ],
349 set_wm_class($window->id, 'bar', 'foo');
350 $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');
358 exit_gracefully($process->pid);
360 ##############################################################
361 # 8: check that the role criterion works properly
362 ##############################################################
364 # this configuration is broken because "asdf" is not a valid integer
365 # the for_window should therefore recognize this error and don’t add the
368 # i3 config file (v4)
369 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
370 for_window [window_role="i3test"] border none
373 $process = launch_with_config($config);
375 $tmp = fresh_workspace;
377 $window = $x->root->create_child(
378 class => WINDOW_CLASS_INPUT_OUTPUT,
379 rect => [ 0, 0, 30, 30 ],
380 background_color => '#00ff00',
381 event_mask => [ 'structure_notify' ],
386 my $atomname = $x->atom(name => 'WM_WINDOW_ROLE');
387 my $atomtype = $x->atom(name => 'STRING');
394 length("i3test") + 1,
398 $window->name('usethis');
402 @content = @{get_ws_content($tmp)};
403 cmp_ok(@content, '==', 1, 'one node on this workspace now');
404 is($content[0]->{border}, 'none', 'no border (window_role)');
406 exit_gracefully($process->pid);
408 ##############################################################
409 # 9: another test for the window_role, but this time it changes
410 # *after* the window has been mapped
411 ##############################################################
413 # this configuration is broken because "asdf" is not a valid integer
414 # the for_window should therefore recognize this error and don’t add the
417 # i3 config file (v4)
418 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
419 for_window [window_role="i3test"] border none
422 $process = launch_with_config($config);
424 $tmp = fresh_workspace;
426 $window = $x->root->create_child(
427 class => WINDOW_CLASS_INPUT_OUTPUT,
428 rect => [ 0, 0, 30, 30 ],
429 background_color => '#00ff00',
430 event_mask => [ 'structure_notify' ],
435 $window->name('usethis');
439 @content = @{get_ws_content($tmp)};
440 cmp_ok(@content, '==', 1, 'one node on this workspace now');
441 is($content[0]->{border}, 'normal', 'normal border (window_role 2)');
443 $atomname = $x->atom(name => 'WM_WINDOW_ROLE');
444 $atomtype = $x->atom(name => 'STRING');
451 length("i3test") + 1,
459 @content = @{get_ws_content($tmp)};
460 cmp_ok(@content, '==', 1, 'one node on this workspace now');
461 is($content[0]->{border}, 'none', 'no border (window_role 2)');
463 exit_gracefully($process->pid);