2 # vim:ts=4:sw=4:expandtab
4 # Tests if assignments work
6 use i3test i3_autostart => 0;
7 use X11::XCB qw(PROP_MODE_REPLACE);
9 # TODO: move to X11::XCB
11 my ($id, $class, $instance) = @_;
13 # Add a _NET_WM_STRUT_PARTIAL hint
14 my $atomname = $x->atom(name => 'WM_CLASS');
15 my $atomtype = $x->atom(name => 'STRING');
23 length($class) + length($instance) + 2,
24 "$instance\x00$class\x00"
30 my $wm_class = delete($args{wm_class}) || 'special';
31 $args{name} //= 'special window';
33 # We use dont_map because i3 will not map the window on the current
34 # workspace. Thus, open_window would time out in wait_for_map (2 seconds).
35 my $window = open_window(
37 before_map => sub { set_wm_class($_->id, $wm_class, $wm_class) },
44 #####################################################################
45 # start a window and see that it does not get assigned with an empty config
46 #####################################################################
50 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
53 my $pid = launch_with_config($config);
55 my $tmp = fresh_workspace;
57 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
59 my $window = open_special;
60 wait_for_map($window);
62 ok(@{get_ws_content($tmp)} == 1, 'special window got managed to current (random) workspace');
64 exit_gracefully($pid);
68 #####################################################################
69 # start a window and see that it gets assigned to a formerly unused
71 #####################################################################
75 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
76 assign "special" → targetws
79 $pid = launch_with_config($config);
81 $tmp = fresh_workspace;
83 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
84 my $workspaces = get_workspace_names;
85 ok(!("targetws" ~~ @{$workspaces}), 'targetws does not exist yet');
87 $window = open_special;
89 ok(@{get_ws_content($tmp)} == 0, 'still no containers');
90 ok("targetws" ~~ @{get_workspace_names()}, 'targetws exists');
94 exit_gracefully($pid);
96 #####################################################################
97 # start a window and see that it gets assigned to a workspace which has content
98 # already, next to the existing node.
99 #####################################################################
101 $pid = launch_with_config($config);
103 # initialize the target workspace, then go to a fresh one
104 ok(!("targetws" ~~ @{get_workspace_names()}), 'targetws does not exist yet');
105 cmd 'workspace targetws';
106 cmp_ok(@{get_ws_content('targetws')}, '==', 0, 'no containers on targetws yet');
108 cmp_ok(@{get_ws_content('targetws')}, '==', 1, 'one container on targetws');
109 $tmp = fresh_workspace;
111 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
112 ok("targetws" ~~ @{get_workspace_names()}, 'targetws does not exist yet');
115 # We use sync_with_i3 instead of wait_for_map here because i3 will not actually
116 # map the window -- it will be assigned to a different workspace and will only
117 # be mapped once you switch to that workspace
118 $window = open_special(dont_map => 1);
122 ok(@{get_ws_content($tmp)} == 0, 'still no containers');
123 ok(@{get_ws_content('targetws')} == 2, 'two containers on targetws');
125 exit_gracefully($pid);
127 #####################################################################
128 # start a window and see that it gets assigned to a workspace which has content
129 # already, next to the existing node.
130 #####################################################################
133 # i3 config file (v4)
134 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
138 $pid = launch_with_config($config);
140 $tmp = fresh_workspace;
142 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
143 $workspaces = get_workspace_names;
144 ok(!("targetws" ~~ @{$workspaces}), 'targetws does not exist yet');
146 $window = open_special;
148 my $content = get_ws($tmp);
149 ok(@{$content->{nodes}} == 0, 'no tiling cons');
150 ok(@{$content->{floating_nodes}} == 1, 'one floating con');
154 exit_gracefully($pid);
156 #####################################################################
157 # make sure that assignments are case-insensitive in the old syntax.
158 #####################################################################
161 # i3 config file (v4)
162 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
166 $pid = launch_with_config($config);
168 $tmp = fresh_workspace;
170 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
171 $workspaces = get_workspace_names;
172 ok(!("targetws" ~~ @{$workspaces}), 'targetws does not exist yet');
174 $window = open_special(wm_class => 'SPEcial');
175 wait_for_map $window;
177 $content = get_ws($tmp);
178 ok(@{$content->{nodes}} == 0, 'no tiling cons');
179 ok(@{$content->{floating_nodes}} == 1, 'one floating con');
183 exit_gracefully($pid);
185 #####################################################################
186 # regression test: dock clients with floating assignments should not crash
187 # (instead, nothing should happen - dock clients can’t float)
189 #####################################################################
191 # Walks /proc to figure out whether a child process of $i3pid with the name
192 # 'i3-nagbar' exists.
193 sub i3nagbar_running {
196 my @procfiles = grep { m,^/proc/[0-9]+$, } </proc/*>;
197 for my $path (@procfiles) {
198 open(my $fh, '<', "$path/stat") or next;
201 my ($comm, $ppid) = ($line =~ /^[0-9]+ \(([^)]+)\) . ([0-9]+)/);
202 return 1 if $ppid == $i3pid && $comm eq 'i3-nagbar';
208 # i3 config file (v4)
209 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
210 for_window [title="special"] floating enable
213 $pid = launch_with_config($config);
215 $tmp = fresh_workspace;
217 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
218 my @docked = get_dock_clients;
219 is(@docked, 0, 'one dock client yet');
221 $window = open_special(
222 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
225 $content = get_ws($tmp);
226 ok(@{$content->{nodes}} == 0, 'no tiling cons');
227 ok(@{$content->{floating_nodes}} == 0, 'one floating con');
228 @docked = get_dock_clients;
229 is(@docked, 1, 'one dock client now');
235 exit_gracefully($pid);