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 # Checks if the 'move [window/container] to workspace' command works correctly
21 my $i3 = i3(get_socket_path());
23 # We move the pointer out of our way to avoid a bug where the focus will
24 # be set to the window under the cursor
25 $x->root->warp_pointer(0, 0);
27 sub move_workspace_test {
30 my $tmp = get_unused_workspace();
31 my $tmp2 = get_unused_workspace();
34 is_num_children($tmp, 0, 'no containers yet');
36 my $first = open_empty_con($i3);
37 my $second = open_empty_con($i3);
38 is_num_children($tmp, 2, 'two containers on first ws');
40 cmd "workspace $tmp2";
41 is_num_children($tmp2, 0, 'no containers on second ws yet');
46 is_num_children($tmp, 1, 'one container on first ws anymore');
47 is_num_children($tmp2, 1, 'one container on second ws');
48 my ($nodes, $focus) = get_ws_content($tmp2);
50 is($focus->[0], $second, 'same container on different ws');
52 ($nodes, $focus) = get_ws_content($tmp);
53 ok($nodes->[0]->{focused}, 'first container focused on first ws');
56 move_workspace_test('move workspace'); # supported for legacy reasons
57 move_workspace_test('move to workspace');
58 # Those are just synonyms and more verbose ways of saying the same thing:
59 move_workspace_test('move window to workspace');
60 move_workspace_test('move container to workspace');
62 ################################################################################
63 # Check that 'move to workspace number <number>' works to move a window to
64 # named workspaces which start with <number>.
65 ################################################################################
67 cmd 'workspace 13: meh';
69 is_num_children('13: meh', 1, 'one container on 13: meh');
71 ok(!workspace_exists('13'), 'workspace 13 does not exist yet');
76 cmd 'move to workspace number 13';
77 is_num_children('13: meh', 2, 'one container on 13: meh');
78 is_num_children('12', 0, 'no container on 12 anymore');
80 ok(!workspace_exists('13'), 'workspace 13 does still not exist');
82 ################################################################################
83 # Check that 'move to workspace number <number><name>' works to move a window to
84 # named workspaces which start with <number>.
85 ################################################################################
87 cmd 'workspace 15: meh';
89 is_num_children('15: meh', 1, 'one container on 15: meh');
91 ok(!workspace_exists('15'), 'workspace 15 does not exist yet');
92 ok(!workspace_exists('15: duh'), 'workspace 15: duh does not exist yet');
97 cmd 'move to workspace number 15: duh';
98 is_num_children('15: meh', 2, 'two containers on 15: meh');
99 is_num_children('14', 0, 'no container on 14 anymore');
101 ok(!workspace_exists('15'), 'workspace 15 does still not exist');
102 ok(!workspace_exists('15: duh'), 'workspace 15 does still not exist');
104 ###################################################################
105 # check if 'move workspace next' and 'move workspace prev' work
106 ###################################################################
108 # Open two containers on the first workspace, one container on the second
109 # workspace. Because the workspaces are named, they will be sorted by order of
111 my $tmp = get_unused_workspace();
112 my $tmp2 = get_unused_workspace();
113 cmd "workspace $tmp";
114 is_num_children($tmp, 0, 'no containers yet');
115 my $first = open_empty_con($i3);
116 my $second = open_empty_con($i3);
117 is_num_children($tmp, 2, 'two containers');
119 cmd "workspace $tmp2";
120 is_num_children($tmp2, 0, 'no containers yet');
121 my $third = open_empty_con($i3);
122 is_num_children($tmp2, 1, 'one container on second ws');
124 # go back to the first workspace, move one of the containers to the next one
125 cmd "workspace $tmp";
126 cmd 'move workspace next';
127 is_num_children($tmp, 1, 'one container on first ws');
128 is_num_children($tmp2, 2, 'two containers on second ws');
130 # go to the second workspace and move two containers to the first one
131 cmd "workspace $tmp2";
132 cmd 'move workspace prev';
133 cmd 'move workspace prev';
134 is_num_children($tmp, 3, 'three containers on first ws');
135 is_num_children($tmp2, 0, 'no containers on second ws');
137 ###################################################################
138 # check if 'move workspace current' works
139 ###################################################################
141 $tmp = get_unused_workspace();
142 $tmp2 = get_unused_workspace();
144 cmd "workspace $tmp";
145 $first = open_window(name => 'win-name');
146 is_num_children($tmp, 1, 'one container on first ws');
148 cmd "workspace $tmp2";
149 is_num_children($tmp2, 0, 'no containers yet');
151 cmd qq|[title="win-name"] move workspace $tmp2|;
152 is_num_children($tmp2, 1, 'one container on second ws');
154 cmd qq|[title="win-name"] move workspace $tmp|;
155 is_num_children($tmp2, 0, 'no containers on second ws');
157 ###################################################################
158 # check if floating cons are moved to new workspaces properly
159 # (that is, if they are floating on the target ws, too)
160 ###################################################################
162 $tmp = get_unused_workspace();
163 $tmp2 = get_unused_workspace();
164 cmd "workspace $tmp";
167 cmd "floating toggle";
169 my $ws = get_ws($tmp);
170 is(@{$ws->{nodes}}, 0, 'no nodes on workspace');
171 is(@{$ws->{floating_nodes}}, 1, 'one floating node on workspace');
173 cmd "move workspace $tmp2";
176 is(@{$ws->{nodes}}, 0, 'no nodes on workspace');
177 is(@{$ws->{floating_nodes}}, 1, 'one floating node on workspace');
179 ################################################################################
180 # Check that 'move workspace number' works correctly.
181 ################################################################################
183 $tmp = get_unused_workspace();
188 is_num_children('16', 1, 'one node on ws 16');
190 cmd "workspace $tmp";
192 cmd 'move workspace number 16';
193 is_num_children('16', 2, 'two nodes on ws 16');
195 ok(!workspace_exists('17'), 'workspace 17 does not exist yet');
197 cmd 'move workspace number 17';
198 ok(workspace_exists('17'), 'workspace 17 created by moving');
199 is(@{get_ws('17')->{nodes}}, 1, 'one node on ws 16');
201 ################################################################################
202 # The following four tests verify the various 'move workspace' commands when
203 # the selection is itself a workspace.
204 ################################################################################
206 # borrowed from 122-split.t
207 # recursively sums up all nodes and their children
211 return 0 if !@{$nodes};
213 my @children = (map { @{$_->{nodes}} } @{$nodes},
214 map { @{$_->{'floating_nodes'}} } @{$nodes});
216 return @{$nodes} + sum_nodes(\@children);
219 ############################################################
220 # move workspace 'next|prev'
221 ############################################################
222 $tmp = get_unused_workspace();
223 $tmp2 = get_unused_workspace();
225 cmd "workspace $tmp";
227 is_num_children($tmp, 1, 'one container on first ws');
229 cmd "workspace $tmp2";
231 is_num_children($tmp2, 1, 'one container on second ws');
233 is_num_children($tmp2, 2, 'two containers on second ws');
236 cmd 'move workspace prev';
238 is_num_children($tmp, 2, 'two child containers on first ws');
239 is(sum_nodes(get_ws_content($tmp)), 4, 'four total containers on first ws');
240 is_num_children($tmp2, 0, 'no containers on second ws');
242 ############################################################
243 # move workspace current
244 # This is a special case that should be a no-op.
245 ############################################################
246 $tmp = fresh_workspace();
249 is_num_children($tmp, 1, 'one container on first ws');
250 my $tmpcount = sum_nodes(get_ws_content($tmp));
253 cmd "move workspace $tmp";
255 is(sum_nodes(get_ws_content($tmp)), $tmpcount, 'number of containers in first ws unchanged');
257 ############################################################
258 # move workspace '<name>'
259 ############################################################
260 $tmp2 = get_unused_workspace();
261 $tmp = fresh_workspace();
264 is_num_children($tmp, 1, 'one container on first ws');
266 cmd "workspace $tmp2";
268 is_num_children($tmp2, 1, 'one container on second ws');
270 is_num_children($tmp2, 2, 'two containers on second ws');
273 cmd "move workspace $tmp";
275 is_num_children($tmp, 2, 'two child containers on first ws');
276 is(sum_nodes(get_ws_content($tmp)), 4, 'four total containers on first ws');
277 is_num_children($tmp2, 0, 'no containers on second ws');
279 ############################################################
280 # move workspace number '<number>'
281 ############################################################
284 is_num_children('18', 1, 'one container on ws 18');
288 is_num_children('19', 1, 'one container on ws 19');
290 is_num_children('19', 2, 'two containers on ws 19');
293 cmd 'move workspace number 18';
295 is_num_children('18', 2, 'two child containers on ws 18');
296 is(sum_nodes(get_ws_content('18')), 4, 'four total containers on ws 18');
297 is_num_children('19', 0, 'no containers on ws 19');
299 ###################################################################
300 # move workspace '<name>' with a floating child
301 ###################################################################
302 $tmp2 = get_unused_workspace();
303 $tmp = fresh_workspace();
305 cmd 'floating toggle';
307 cmd 'floating toggle';
311 is_num_children($tmp, 1, 'one container on first workspace');
312 is(@{$ws->{floating_nodes}}, 2, 'two floating nodes on first workspace');
315 cmd "move workspace $tmp2";
318 is_num_children($tmp2, 1, 'one container on second workspace');
319 is(@{$ws->{floating_nodes}}, 2, 'two floating nodes on second workspace');