]> git.sur5r.net Git - i3/i3/blob - testcases/t/65-for_window.t
t/65-for_window: add a testcase for multiple criteria
[i3/i3] / testcases / t / 65-for_window.t
1 #!perl
2 # vim:ts=4:sw=4:expandtab
3 # !NO_I3_INSTANCE! will prevent complete-run.pl from starting i3
4 #
5 #
6 use X11::XCB qw(:all);
7 use X11::XCB::Connection;
8 use i3test;
9 use Cwd qw(abs_path);
10 use Proc::Background;
11 use File::Temp qw(tempfile tempdir);
12
13 my $x = X11::XCB::Connection->new;
14
15 # assuming we are run by complete-run.pl
16 my $i3_path = abs_path("../i3");
17
18 ##############################################################
19 # 1: test the following directive:
20 #    for_window [class="borderless"] border none
21 # by first creating a window with a different class (should get
22 # the normal border), then creating a window with the class
23 # "borderless" (should get no border)
24 ##############################################################
25
26 my $socketpath = File::Temp::tempnam('/tmp', 'i3-test-socket-');
27
28 my ($fh, $tmpfile) = tempfile();
29 say $fh "# i3 config file (v4)";
30 say $fh "font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
31 say $fh "ipc-socket $socketpath";
32 say $fh q|for_window [class="borderless"] border none|;
33 close($fh);
34
35 diag("Starting i3");
36 my $i3cmd = "exec " . abs_path("../i3") . " -V -d all --disable-signalhandler -c $tmpfile >/dev/null 2>/dev/null";
37 my $process = Proc::Background->new($i3cmd);
38 sleep 1;
39
40 # force update of the cached socket path in lib/i3test
41 get_socket_path(0);
42
43 my $tmp = fresh_workspace;
44
45 my $window = $x->root->create_child(
46     class => WINDOW_CLASS_INPUT_OUTPUT,
47     rect => [ 0, 0, 30, 30 ],
48     background_color => '#00ff00',
49 );
50
51 $window->name('Border window');
52 $window->map;
53 sleep 0.25;
54
55 my @content = @{get_ws_content($tmp)};
56 cmp_ok(@content, '==', 1, 'one node on this workspace now');
57 is($content[0]->{border}, 'normal', 'normal border');
58
59 $window->unmap;
60 sleep 0.25;
61
62 my @content = @{get_ws_content($tmp)};
63 cmp_ok(@content, '==', 0, 'no more nodes');
64 diag('content = '. Dumper(\@content));
65
66 $window = $x->root->create_child(
67     class => WINDOW_CLASS_INPUT_OUTPUT,
68     rect => [ 0, 0, 30, 30 ],
69     background_color => '#00ff00',
70 );
71
72 $window->_create;
73
74 # TODO: move this to X11::XCB::Window
75 sub set_wm_class {
76     my ($id, $class, $instance) = @_;
77
78     # Add a _NET_WM_STRUT_PARTIAL hint
79     my $atomname = $x->atom(name => 'WM_CLASS');
80     my $atomtype = $x->atom(name => 'STRING');
81
82     $x->change_property(
83         PROP_MODE_REPLACE,
84         $id,
85         $atomname->id,
86         $atomtype->id,
87         8,
88         length($class) + length($instance) + 2,
89         "$instance\x00$class\x00"
90     );
91 }
92
93 set_wm_class($window->id, 'borderless', 'borderless');
94 $window->name('Borderless window');
95 $window->map;
96 sleep 0.25;
97
98 @content = @{get_ws_content($tmp)};
99 cmp_ok(@content, '==', 1, 'one node on this workspace now');
100 is($content[0]->{border}, 'none', 'no border');
101
102 $window->unmap;
103 sleep 0.25;
104
105 @content = @{get_ws_content($tmp)};
106 cmp_ok(@content, '==', 0, 'no more nodes');
107
108 exit_gracefully($process->pid);
109
110 ##############################################################
111 # 2: match on the title, check if for_window is really executed
112 # only once
113 ##############################################################
114
115 ($fh, $tmpfile) = tempfile();
116 say $fh "# i3 config file (v4)";
117 say $fh "font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
118 say $fh "ipc-socket $socketpath";
119 say $fh q|for_window [class="borderless"] border none|;
120 say $fh q|for_window [title="special borderless title"] border none|;
121 close($fh);
122
123 diag("Starting i3");
124 my $i3cmd = "exec " . abs_path("../i3") . " -V -d all --disable-signalhandler -c $tmpfile >/dev/null 2>/dev/null";
125 my $process = Proc::Background->new($i3cmd);
126 sleep 1;
127
128 # force update of the cached socket path in lib/i3test
129 get_socket_path(0);
130
131 $tmp = fresh_workspace;
132
133 $window = $x->root->create_child(
134     class => WINDOW_CLASS_INPUT_OUTPUT,
135     rect => [ 0, 0, 30, 30 ],
136     background_color => '#00ff00',
137 );
138
139 $window->name('special title');
140 $window->map;
141 sleep 0.25;
142
143 @content = @{get_ws_content($tmp)};
144 cmp_ok(@content, '==', 1, 'one node on this workspace now');
145 is($content[0]->{border}, 'normal', 'normal border');
146
147 $window->name('special borderless title');
148 sleep 0.25;
149
150 @content = @{get_ws_content($tmp)};
151 is($content[0]->{border}, 'none', 'no border');
152
153 $window->name('special title');
154 sleep 0.25;
155
156 cmd 'border normal';
157
158 @content = @{get_ws_content($tmp)};
159 is($content[0]->{border}, 'normal', 'border reset to normal');
160
161 $window->name('special borderless title');
162 sleep 0.25;
163
164 @content = @{get_ws_content($tmp)};
165 is($content[0]->{border}, 'normal', 'still normal border');
166
167 $window->unmap;
168 sleep 0.25;
169
170 @content = @{get_ws_content($tmp)};
171 cmp_ok(@content, '==', 0, 'no more nodes');
172
173 exit_gracefully($process->pid);
174
175 ##############################################################
176 # 3: match on the title, set border style *and* a mark
177 ##############################################################
178
179 ($fh, $tmpfile) = tempfile();
180 say $fh "# i3 config file (v4)";
181 say $fh "font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
182 say $fh "ipc-socket $socketpath";
183 say $fh q|for_window [class="borderless"] border none|;
184 say $fh q|for_window [title="special borderless title"] border none|;
185 say $fh q|for_window [title="special mark title"] border none, mark bleh|;
186 close($fh);
187
188 diag("Starting i3");
189 my $i3cmd = "exec " . abs_path("../i3") . " -V -d all --disable-signalhandler -c $tmpfile >/dev/null 2>/dev/null";
190 my $process = Proc::Background->new($i3cmd);
191 sleep 1;
192
193 # force update of the cached socket path in lib/i3test
194 get_socket_path(0);
195
196 $tmp = fresh_workspace;
197
198 $window = $x->root->create_child(
199     class => WINDOW_CLASS_INPUT_OUTPUT,
200     rect => [ 0, 0, 30, 30 ],
201     background_color => '#00ff00',
202 );
203
204 $window->name('special mark title');
205 $window->map;
206 sleep 0.25;
207
208 @content = @{get_ws_content($tmp)};
209 cmp_ok(@content, '==', 1, 'one node on this workspace now');
210 is($content[0]->{border}, 'none', 'no border');
211
212 my $other = open_standard_window($x);
213
214 @content = @{get_ws_content($tmp)};
215 cmp_ok(@content, '==', 2, 'two nodes');
216 is($content[0]->{border}, 'none', 'no border');
217 is($content[1]->{border}, 'normal', 'normal border');
218 ok(!$content[0]->{focused}, 'first one not focused');
219
220 cmd qq|[con_mark="bleh"] focus|;
221
222 @content = @{get_ws_content($tmp)};
223 ok($content[0]->{focused}, 'first node focused');
224
225 exit_gracefully($process->pid);
226
227 ##############################################################
228 # 4: multiple criteria for the for_window command
229 ##############################################################
230
231 ($fh, $tmpfile) = tempfile();
232 say $fh "# i3 config file (v4)";
233 say $fh "font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
234 say $fh "ipc-socket $socketpath";
235 say $fh q|for_window [class="borderless" title="usethis"] border none|;
236 close($fh);
237
238 diag("Starting i3");
239 my $i3cmd = "exec " . abs_path("../i3") . " -V -d all --disable-signalhandler -c $tmpfile >/tmp/a 2>/dev/null";
240 my $process = Proc::Background->new($i3cmd);
241 sleep 1;
242
243 # force update of the cached socket path in lib/i3test
244 get_socket_path(0);
245
246 $tmp = fresh_workspace;
247
248 $window = $x->root->create_child(
249     class => WINDOW_CLASS_INPUT_OUTPUT,
250     rect => [ 0, 0, 30, 30 ],
251     background_color => '#00ff00',
252 );
253
254 $window->_create;
255
256 set_wm_class($window->id, 'borderless', 'borderless');
257 $window->name('usethis');
258 $window->map;
259 sleep 0.25;
260
261 @content = @{get_ws_content($tmp)};
262 cmp_ok(@content, '==', 1, 'one node on this workspace now');
263 is($content[0]->{border}, 'none', 'no border');
264
265 $window->unmap;
266 sleep 0.25;
267
268 @content = @{get_ws_content($tmp)};
269 cmp_ok(@content, '==', 0, 'no nodes on this workspace now');
270
271 set_wm_class($window->id, 'borderless', 'borderless');
272 $window->name('notthis');
273 $window->map;
274 sleep 0.25;
275
276 @content = @{get_ws_content($tmp)};
277 cmp_ok(@content, '==', 1, 'one node on this workspace now');
278 is($content[0]->{border}, 'normal', 'no border');
279
280
281 exit_gracefully($process->pid);
282
283 done_testing;