Codebase list i3-gaps / 97c0d40
Merge remote-tracking branch 'vanilla/next' into gaps-next Ingo Bürk 4 years ago
15 changed file(s) with 384 addition(s) and 106 deletion(s). Raw diff Collapse all Expand all
33 use strict;
44 use warnings;
55 use Pod::Simple::HTML;
6 use Getopt::Long;
67 use v5.10;
8
9 my $stylesurl = '';
10
11 GetOptions("stylesurl=s" => \$stylesurl)
12 or die "parsing flags";
713
814 $Pod::Simple::HTML::Tagmap{'Verbatim'} = '<pre><tt>';
915 $Pod::Simple::HTML::Tagmap{'VerbatimFormatted'} = '<pre><tt>';
2127 my $parser = Pod::Simple::HTML->new();
2228
2329 $parser->index(1);
24 $parser->html_header_before_title(
25 <<'EOF'
30 if ($stylesurl ne '') {
31 $parser->html_header_before_title(
32 <<EOF
2633 <!doctype html>
2734 <html lang="en">
2835 <head>
3037 <meta charset="utf-8">
3138 <meta name="generator" content="Pod::Simple::HTML">
3239 <meta name="description" content="i3 Perl documentation">
33 <link rel="stylesheet" href="https://i3wm.org/css/style.css" type="text/css" />
40 <link rel="stylesheet" href="$stylesurl/style.css" type="text/css" />
3441 <style type="text/css">
3542 .pod pre {
3643 background: #333;
6269 </style>
6370 <title>
6471 EOF
65 );
72 );
73 }
6674 $parser->html_header_after_title(
6775 <<'EOF'
6876 </title>
19161916 to match only the currently focused window.
19171917 floating::
19181918 Only matches floating windows. This criterion requires no value.
1919 floating_from::
1920 Like +floating+ but this criterion takes two possible values: "auto"
1921 and "user". With "auto", only windows that were automatically opened as
1922 floating are matched. With "user", only windows that the user made
1923 floating are matched.
19191924 tiling::
19201925 Only matches tiling windows. This criterion requires no value.
1926 tiling_from::
1927 Like +tiling+ but this criterion takes two possible values: "auto" and
1928 "user". With "auto", only windows that were automatically opened as
1929 tiling are matched. With "user", only windows that the user made tiling
1930 are matched.
19211931
19221932 The criteria +class+, +instance+, +role+, +title+, +workspace+ and +mark+ are
19231933 actually regular expressions (PCRE). See +pcresyntax(3)+ or +perldoc perlre+ for
217217 # quote of the literal. We can do strdup(literal + 1); then :).
218218 $token_name =~ s/'$//;
219219 }
220 # Escape double quotes:
221 $token_name =~ s,",\\",g;
220222 my $next_state = $token->{next_state};
221223 if ($next_state =~ /^call /) {
222224 ($call_identifier) = ($next_state =~ /^call ([0-9]+)$/);
142142 $desktops{$relative} = $File::Find::name;
143143 },
144144 no_chdir => 1,
145 follow_fast => 1,
145146 },
146147 @searchdirs
147148 );
548548 } dock;
549549 xcb_window_t id;
550550 enum { WM_ANY = 0,
551 WM_TILING_AUTO,
552 WM_TILING_USER,
551553 WM_TILING,
554 WM_FLOATING_AUTO,
555 WM_FLOATING_USER,
552556 WM_FLOATING } window_mode;
553557 Con *con_id;
554558
207207
208208 # Criteria: Used by for_window and assign.
209209 state CRITERIA:
210 ctype = 'class' -> CRITERION
211 ctype = 'instance' -> CRITERION
212 ctype = 'window_role' -> CRITERION
213 ctype = 'con_id' -> CRITERION
214 ctype = 'id' -> CRITERION
215 ctype = 'window_type' -> CRITERION
216 ctype = 'con_mark' -> CRITERION
217 ctype = 'title' -> CRITERION
218 ctype = 'urgent' -> CRITERION
219 ctype = 'workspace' -> CRITERION
210 ctype = 'class' -> CRITERION
211 ctype = 'instance' -> CRITERION
212 ctype = 'window_role' -> CRITERION
213 ctype = 'con_id' -> CRITERION
214 ctype = 'id' -> CRITERION
215 ctype = 'window_type' -> CRITERION
216 ctype = 'con_mark' -> CRITERION
217 ctype = 'title' -> CRITERION
218 ctype = 'urgent' -> CRITERION
219 ctype = 'workspace' -> CRITERION
220 ctype = 'floating_from' -> CRITERION_FROM
221 ctype = 'tiling_from' -> CRITERION_FROM
220222 ctype = 'tiling', 'floating'
221223 -> call cfg_criteria_add($ctype, NULL); CRITERIA
222224 ']'
224226
225227 state CRITERION:
226228 '=' -> CRITERION_STR
229
230 state CRITERION_FROM:
231 '=' -> CRITERION_FROM_STR_START
232
233 state CRITERION_FROM_STR_START:
234 '"' -> CRITERION_FROM_STR
235 kind = 'auto', 'user'
236 -> call cfg_criteria_add($ctype, $kind); CRITERIA
237
238 state CRITERION_FROM_STR:
239 kind = 'auto', 'user'
240 -> CRITERION_FROM_STR_END
241
242 state CRITERION_FROM_STR_END:
243 '"'
244 -> call cfg_criteria_add($ctype, $kind); CRITERIA
227245
228246 state CRITERION_STR:
229247 cvalue = word
841841 DLOG("The window was requested to be visible on all workspaces, making it sticky and floating.\n");
842842
843843 floating_enable(con, false);
844 con->floating = FLOATING_AUTO_ON;
844845
845846 con->sticky = true;
846847 ewmh_update_sticky(con->window->id, true);
11551156 return true;
11561157 }
11571158
1159 /*
1160 * Handles the _I3_FLOATING_WINDOW property to properly run assignments for
1161 * floating window changes.
1162 *
1163 * This is needed to correctly run the assignments after changes in floating
1164 * windows which are triggered by user commands (floating enable | disable). In
1165 * that case, we can't call run_assignments because it will modify the parser
1166 * state when it needs to parse the user-specified action, breaking the parser
1167 * state for the original command.
1168 *
1169 */
1170 static bool handle_i3_floating(Con *con, xcb_get_property_reply_t *prop) {
1171 DLOG("floating change for con %p\n", con);
1172
1173 remanage_window(con);
1174
1175 return true;
1176 }
1177
11581178 /* Returns false if the event could not be processed (e.g. the window could not
11591179 * be found), true otherwise */
11601180 typedef bool (*cb_property_handler_t)(Con *con, xcb_get_property_reply_t *property);
11761196 {0, 128, handle_class_change},
11771197 {0, UINT_MAX, handle_strut_partial_change},
11781198 {0, UINT_MAX, handle_window_type},
1199 {0, UINT_MAX, handle_i3_floating},
11791200 {0, 5 * sizeof(uint64_t), handle_motif_hints_change}};
11801201 #define NUM_HANDLERS (sizeof(property_handlers) / sizeof(struct property_handler_t))
11811202
11971218 property_handlers[7].atom = XCB_ATOM_WM_CLASS;
11981219 property_handlers[8].atom = A__NET_WM_STRUT_PARTIAL;
11991220 property_handlers[9].atom = A__NET_WM_WINDOW_TYPE;
1200 property_handlers[10].atom = A__MOTIF_WM_HINTS;
1221 property_handlers[10].atom = A_I3_FLOATING_WINDOW;
1222 property_handlers[11].atom = A__MOTIF_WM_HINTS;
12011223 }
12021224
12031225 static void property_notify(uint8_t state, xcb_window_t window, xcb_atom_t atom) {
170170 con_attach(json_node, json_node->parent, true);
171171 LOG("Creating window\n");
172172 x_con_init(json_node);
173
174 /* Fix erroneous JSON input regarding floating containers to avoid
175 * crashing, see #3901. */
176 const int old_floating_mode = json_node->floating;
177 if (old_floating_mode >= FLOATING_AUTO_ON && json_node->parent->type != CT_FLOATING_CON) {
178 LOG("Fixing floating node without CT_FLOATING_CON parent\n");
179
180 /* Force floating_enable to work */
181 json_node->floating = FLOATING_AUTO_OFF;
182 floating_enable(json_node, false);
183 json_node->floating = old_floating_mode;
184 }
185
173186 json_node = json_node->parent;
174187 incomplete--;
175188 DLOG("incomplete = %d\n", incomplete);
537537 bool automatic_border = (motif_border_style == BS_NORMAL);
538538
539539 floating_enable(nc, automatic_border);
540 nc->floating = FLOATING_AUTO_ON;
540541 }
541542
542543 /* explicitly set the border width to the default */
214214 }
215215
216216 if (match->window_mode != WM_ANY) {
217 if ((con = con_by_window_id(window->id)) == NULL)
218 return false;
219
220 const bool floating = (con_inside_floating(con) != NULL);
221
222 if ((match->window_mode == WM_TILING && floating) ||
223 (match->window_mode == WM_FLOATING && !floating)) {
224 LOG("window_mode does not match\n");
225 return false;
217 if ((con = con_by_window_id(window->id)) == NULL) {
218 return false;
219 }
220
221 switch (match->window_mode) {
222 case WM_TILING_AUTO:
223 if (con->floating != FLOATING_AUTO_OFF) {
224 return false;
225 }
226 break;
227 case WM_TILING_USER:
228 if (con->floating != FLOATING_USER_OFF) {
229 return false;
230 }
231 break;
232 case WM_TILING:
233 if (con_inside_floating(con) != NULL) {
234 return false;
235 }
236 break;
237 case WM_FLOATING_AUTO:
238 if (con->floating != FLOATING_AUTO_ON) {
239 return false;
240 }
241 break;
242 case WM_FLOATING_USER:
243 if (con->floating != FLOATING_USER_ON) {
244 return false;
245 }
246 break;
247 case WM_FLOATING:
248 if (con_inside_floating(con) == NULL) {
249 return false;
250 }
251 break;
252 case WM_ANY:
253 assert(false);
226254 }
227255
228256 LOG("window_mode matches\n");
366394 return;
367395 }
368396
397 if (strcmp(ctype, "tiling_from") == 0 &&
398 cvalue != NULL &&
399 strcmp(cvalue, "auto") == 0) {
400 match->window_mode = WM_TILING_AUTO;
401 return;
402 }
403
404 if (strcmp(ctype, "tiling_from") == 0 &&
405 cvalue != NULL &&
406 strcmp(cvalue, "user") == 0) {
407 match->window_mode = WM_TILING_USER;
408 return;
409 }
410
369411 if (strcmp(ctype, "floating") == 0) {
370412 match->window_mode = WM_FLOATING;
371413 return;
372414 }
373415
416 if (strcmp(ctype, "floating_from") == 0 &&
417 cvalue != NULL &&
418 strcmp(cvalue, "auto") == 0) {
419 match->window_mode = WM_FLOATING_AUTO;
420 return;
421 }
422
423 if (strcmp(ctype, "floating_from") == 0 &&
424 cvalue != NULL &&
425 strcmp(cvalue, "user") == 0) {
426 match->window_mode = WM_FLOATING_USER;
427 return;
428 }
429
374430 ELOG("Unknown criterion: %s\n", ctype);
375431 }
826826 }
827827
828828 /*
829 * Move the content of an outputs container to the first output.
830 *
831 * TODO: Maybe use an on_destroy callback which is implement differently for
832 * different container types (CT_CONTENT vs. CT_DOCKAREA)?
833 *
834 */
835 static void move_content(Con *con) {
836 Con *first = get_first_output()->con;
837 Con *first_content = output_get_content(first);
838
839 /* We need to move the workspaces from the disappearing output to the first output */
840 /* 1: Get the con to focus next */
841 Con *next = focused;
842
843 /* 2: iterate through workspaces and re-assign them, fixing the coordinates
844 * of floating containers as we go */
845 Con *current;
846 Con *old_content = output_get_content(con);
847 while (!TAILQ_EMPTY(&(old_content->nodes_head))) {
848 current = TAILQ_FIRST(&(old_content->nodes_head));
849 if (current != next && TAILQ_EMPTY(&(current->focus_head))) {
850 /* the workspace is empty and not focused, get rid of it */
851 DLOG("Getting rid of current = %p / %s (empty, unfocused)\n", current, current->name);
852 tree_close_internal(current, DONT_KILL_WINDOW, false);
853 continue;
854 }
855 DLOG("Detaching current = %p / %s\n", current, current->name);
856 con_detach(current);
857 DLOG("Re-attaching current = %p / %s\n", current, current->name);
858 con_attach(current, first_content, false);
859 DLOG("Fixing the coordinates of floating containers\n");
860 Con *floating_con;
861 TAILQ_FOREACH (floating_con, &(current->floating_head), floating_windows) {
862 floating_fix_coordinates(floating_con, &(con->rect), &(first->rect));
863 }
864 }
865
866 /* Restore focus after con_detach / con_attach. next can be NULL, see #3523. */
867 if (next) {
868 DLOG("now focusing next = %p\n", next);
869 con_focus(next);
870 workspace_show(con_get_workspace(next));
871 }
872
873 /* 3: move the dock clients to the first output */
874 Con *child;
875 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
876 if (child->type != CT_DOCKAREA) {
877 continue;
878 }
879 DLOG("Handling dock con %p\n", child);
880 Con *dock;
881 while (!TAILQ_EMPTY(&(child->nodes_head))) {
882 dock = TAILQ_FIRST(&(child->nodes_head));
883 Con *nc;
884 Match *match;
885 nc = con_for_window(first, dock->window, &match);
886 DLOG("Moving dock client %p to nc %p\n", dock, nc);
887 con_detach(dock);
888 DLOG("Re-attaching\n");
889 con_attach(dock, nc, false);
890 DLOG("Done\n");
891 }
892 }
893
894 DLOG("Destroying disappearing con %p\n", con);
895 tree_close_internal(con, DONT_KILL_WINDOW, true);
896 }
897
898 /*
829899 * (Re-)queries the outputs via RandR and stores them in the list of outputs.
830900 *
831901 * If no outputs are found use the root window.
867937 other->rect.y != output->rect.y)
868938 continue;
869939
870 DLOG("output %p has the same position, his mode = %d x %d\n",
940 DLOG("output %p has the same position, its mode = %d x %d\n",
871941 other, other->rect.width, other->rect.height);
872942 uint32_t width = min(other->rect.width, output->rect.width);
873943 uint32_t height = min(other->rect.height, output->rect.height);
900970 }
901971 }
902972
973 /* Ensure that all containers with type CT_OUTPUT have a valid
974 * corresponding entry in outputs. This can happen in situations related to
975 * those mentioned #3767 e.g. when a CT_OUTPUT is created from an in-place
976 * restart's layout but the output is disabled by a randr query happening
977 * at the same time. */
978 Con *con;
979 for (con = TAILQ_FIRST(&(croot->nodes_head)); con;) {
980 Con *next = TAILQ_NEXT(con, nodes);
981 if (!con_is_internal(con) && get_output_by_name(con->name, true) == NULL) {
982 DLOG("No output %s found, moving its old content to first output\n", con->name);
983 move_content(con);
984 }
985 con = next;
986 }
987
903988 /* Handle outputs which have a new mode or are disabled now (either
904989 * because the user disabled them or because they are clones) */
905990 TAILQ_FOREACH (output, &outputs, outputs) {
9511036 output->active = false;
9521037 DLOG("Output %s disabled, re-assigning workspaces/docks\n", output_primary_name(output));
9531038
954 Output *first = get_first_output();
955
956 /* TODO: refactor the following code into a nice function. maybe
957 * use an on_destroy callback which is implement differently for
958 * different container types (CT_CONTENT vs. CT_DOCKAREA)? */
959 Con *first_content = output_get_content(first->con);
960
9611039 if (output->con != NULL) {
962 /* We need to move the workspaces from the disappearing output to the first output */
963 /* 1: Get the con to focus next */
964 Con *next = focused;
965
966 /* 2: iterate through workspaces and re-assign them, fixing the coordinates
967 * of floating containers as we go */
968 Con *current;
969 Con *old_content = output_get_content(output->con);
970 while (!TAILQ_EMPTY(&(old_content->nodes_head))) {
971 current = TAILQ_FIRST(&(old_content->nodes_head));
972 if (current != next && TAILQ_EMPTY(&(current->focus_head))) {
973 /* the workspace is empty and not focused, get rid of it */
974 DLOG("Getting rid of current = %p / %s (empty, unfocused)\n", current, current->name);
975 tree_close_internal(current, DONT_KILL_WINDOW, false);
976 continue;
977 }
978 DLOG("Detaching current = %p / %s\n", current, current->name);
979 con_detach(current);
980 DLOG("Re-attaching current = %p / %s\n", current, current->name);
981 con_attach(current, first_content, false);
982 DLOG("Fixing the coordinates of floating containers\n");
983 Con *floating_con;
984 TAILQ_FOREACH (floating_con, &(current->floating_head), floating_windows) {
985 floating_fix_coordinates(floating_con, &(output->con->rect), &(first->con->rect));
986 }
987 }
988
989 /* Restore focus after con_detach / con_attach. next can be NULL, see #3523. */
990 if (next) {
991 DLOG("now focusing next = %p\n", next);
992 con_focus(next);
993 workspace_show(con_get_workspace(next));
994 }
995
996 /* 3: move the dock clients to the first output */
997 Con *child;
998 TAILQ_FOREACH (child, &(output->con->nodes_head), nodes) {
999 if (child->type != CT_DOCKAREA)
1000 continue;
1001 DLOG("Handling dock con %p\n", child);
1002 Con *dock;
1003 while (!TAILQ_EMPTY(&(child->nodes_head))) {
1004 dock = TAILQ_FIRST(&(child->nodes_head));
1005 Con *nc;
1006 Match *match;
1007 nc = con_for_window(first->con, dock->window, &match);
1008 DLOG("Moving dock client %p to nc %p\n", dock, nc);
1009 con_detach(dock);
1010 DLOG("Re-attaching\n");
1011 con_attach(dock, nc, false);
1012 DLOG("Done\n");
1013 }
1014 }
1015
1016 DLOG("destroying disappearing con %p\n", output->con);
1040 /* clear the pointer before move_content calls tree_close_internal in which the memory is freed */
10171041 Con *con = output->con;
1018 /* clear the pointer before calling tree_close_internal in which the memory is freed */
10191042 output->con = NULL;
1020 tree_close_internal(con, DONT_KILL_WINDOW, true);
1021 DLOG("Done. Should be fine now\n");
1043 move_content(con);
10221044 }
10231045
10241046 output->to_be_disabled = false;
9797 ################################################################################
9898
9999 $config = <<'EOT';
100 for_window [] nop empty
100101 for_window [class="^Chrome"] floating enable
101 EOT
102
103 $expected = <<'EOT';
102 for_window [class=^Chrome] floating enable
103 for_window [floating_from = "auto" class= ==Class== ] nop floating
104 for_window [tiling_from=auto class="==Class=="]nop floating
105 EOT
106
107 $expected = <<'EOT';
108 cfg_for_window(nop empty)
104109 cfg_criteria_add(class, ^Chrome)
105110 cfg_for_window(floating enable)
111 cfg_criteria_add(class, ^Chrome)
112 cfg_for_window(floating enable)
113 cfg_criteria_add(floating_from, auto)
114 cfg_criteria_add(class, ==Class==)
115 cfg_for_window(nop floating)
116 cfg_criteria_add(tiling_from, auto)
117 cfg_criteria_add(class, ==Class==)
118 cfg_for_window(nop floating)
106119 EOT
107120
108121 is(parser_calls($config),
109122 $expected,
110123 'for_window okay');
124
125 $config = <<'EOT';
126 for_window [tiling_from=typo] nop typo
127 for_window [tiling_from="typo"] nop typo
128 EOT
129
130 $expected = <<'EOT';
131 ERROR: CONFIG: Expected one of these tokens: '"', 'auto', 'user'
132 ERROR: CONFIG: (in file <stdin>)
133 ERROR: CONFIG: Line 1: for_window [tiling_from=typo] nop typo
134 ERROR: CONFIG: ^^^^^^^^^^^^^^
135 ERROR: CONFIG: Line 2: for_window [tiling_from="typo"] nop typo
136 ERROR: CONFIG: Expected one of these tokens: 'auto', 'user'
137 ERROR: CONFIG: (in file <stdin>)
138 ERROR: CONFIG: Line 1: for_window [tiling_from=typo] nop typo
139 ERROR: CONFIG: Line 2: for_window [tiling_from="typo"] nop typo
140 ERROR: CONFIG: ^^^^^^^^^^^^^^^
141 EOT
142
143 is(parser_calls($config),
144 $expected,
145 'for_window errors okay');
111146
112147 ################################################################################
113148 # assign
211211 EOT
212212 $fh->flush;
213213 $reply = cmd "append_layout $filename";
214 ok(!$reply->[0]->{success}, 'IPC reply indicated success');
214 ok(!$reply->[0]->{success}, 'IPC reply did not indicate success');
215215
216216 does_i3_live;
217217
275275
276276 close($fh);
277277
278 ################################################################################
279 # Issue with floating key being set, without proper parent
280 # See #3901
281 ################################################################################
282 subtest 'issue 3901' => sub {
283 kill_all_windows;
284 $ws = fresh_workspace;
285 is(scalar @{get_ws($ws)->{floating_nodes}}, 0, 'No floating nodes yet');
286
287 ($fh, $filename) = tempfile(UNLINK => 1);
288 print $fh <<'EOT';
289 // vim:ts=4:sw=4:et
290 {
291 "border": "pixel",
292 "current_border_width": 1,
293 "floating": "auto_on", // crashes: user_on, auto_on, no crash: user_off, auto_off
294 "geometry": {
295 "height": 400,
296 "width": 300,
297 "x": 820,
298 "y": 350
299 },
300 "name": "Click me to crash",
301 "percent": 0.5, // still crashes if this field is absent
302 "swallows": [
303 {
304 "class": "^this doesn't matter as long as it doesn't match a new window$"
305 }
306 ],
307 "type": "con"
308 }
309
310 EOT
311 $fh->flush;
312 $reply = cmd "append_layout $filename";
313 ok($reply->[0]->{success}, 'IPC reply indicated success');
314
315 cmd '[floating] focus';
316 is(scalar @{get_ws($ws)->{floating_nodes}}, 1, 'one floating node on this ws');
317
318 does_i3_live;
319
320 close($fh);
321 };
278322
279323 done_testing;
1616 use i3test i3_config => <<EOT;
1717 # i3 config file (v4)
1818 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
19 for_window [tiling] mark tiled
20 for_window [floating] mark floated
19 for_window [tiling] mark --add tiling
20 for_window [floating] mark --add floating
21
22 for_window [tiling_from="auto"] mark --add tiling_auto
23 for_window [floating_from="auto"] mark --add floating_auto
24
25 for_window [tiling_from="user"] mark --add tiling_user
26 for_window [floating_from="user"] mark --add floating_user
2127 EOT
2228 use X11::XCB qw(PROP_MODE_REPLACE);
2329
2430 ##############################################################
25 # 13: check that the tiling / floating criteria work.
31 # Check that the auto tiling / floating criteria work.
2632 ##############################################################
2733
2834 my $tmp = fresh_workspace;
29
30 open_window;
31 open_floating_window;
35 my $A = open_window;
36 my $B = open_floating_window;
3237
3338 my @nodes = @{get_ws($tmp)->{nodes}};
3439 cmp_ok(@nodes, '==', 1, 'one tiling container on this workspace');
35 is_deeply($nodes[0]->{marks}, [ 'tiled' ], "mark set for 'tiling' criterion");
40 is_deeply($nodes[0]->{marks}, [ 'tiling', 'tiling_auto' ], "mark set for 'tiling' criterion");
3641
3742 @nodes = @{get_ws($tmp)->{floating_nodes}};
3843 cmp_ok(@nodes, '==', 1, 'one floating container on this workspace');
39 is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'floated' ], "mark set for 'floating' criterion");
44 is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'floating', 'floating_auto' ], "mark set for 'floating' criterion");
45
46 ################################################################################
47 # Check that the user tiling / floating criteria work.
48 # The following rules are triggered here: 'tiling', 'tiling_user', 'floating',
49 # 'floating_user'. Therefore, the old marks 'tiling' and 'floating' are
50 # replaced but the 'tiling_auto' and 'floating_auto' marks are preserved.
51 ################################################################################
52
53 cmd '[id=' . $A->{id} . '] floating enable';
54 cmd '[id=' . $B->{id} . '] floating disable';
55
56 @nodes = @{get_ws($tmp)->{nodes}};
57 cmp_ok(@nodes, '==', 1, 'one tiling container on this workspace');
58 is_deeply($nodes[0]->{marks}, [ 'floating_auto', 'tiling', 'tiling_user' ], "Marks updated after 'floating_user' criterion");
59
60 @nodes = @{get_ws($tmp)->{floating_nodes}};
61 cmp_ok(@nodes, '==', 1, 'one floating container on this workspace');
62 is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'tiling_auto', 'floating', 'floating_user' ], "Marks updated after 'tiling_user' criterion");
63
64 ################################################################################
65 # Check that the default and auto rules do not re-trigger
66 # Here, the windows are returned to their original state but since the rules
67 # `tiling`, `tiling_auto`, `floating` and `floating_auto` where already
68 # triggered, only the `tiling_user` and `floating_user` rules should trigger.
69 ################################################################################
70
71 # Use 'mark' to clear old marks
72 cmd '[id=' . $A->{id} . '] mark A, floating disable';
73 cmd '[id=' . $B->{id} . '] mark B, floating enable';
74
75 @nodes = @{get_ws($tmp)->{nodes}};
76 cmp_ok(@nodes, '==', 1, 'one tiling container on this workspace');
77 is_deeply($nodes[0]->{marks}, [ 'A', 'tiling_user' ], "Only 'tiling_user' rule triggered");
78
79 @nodes = @{get_ws($tmp)->{floating_nodes}};
80 cmp_ok(@nodes, '==', 1, 'one floating container on this workspace');
81 is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'B', 'floating_user' ], "Only 'floating_user' rule triggered");
4082
4183 ##############################################################
4284
66 do
77 asciidoc -a linkcss -a stylesdir=https://i3wm.org/css -a scriptsdir=https://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf $(dirname $f)/$(basename $f .html)
88 done
9 ./docs/i3-pod2html i3-dmenu-desktop man/i3-dmenu-desktop.html
10 ./docs/i3-pod2html i3-save-tree man/i3-save-tree.html
11 ./docs/i3-pod2html build/testcases/lib/i3test.pm docs/lib-i3test.html
12 ./docs/i3-pod2html testcases/lib/i3test/Test.pm docs/lib-i3test-test.html
9 ./docs/i3-pod2html --stylesurl=https://i3wm.org/css i3-dmenu-desktop man/i3-dmenu-desktop.html
10 ./docs/i3-pod2html --stylesurl=https://i3wm.org/css i3-save-tree man/i3-save-tree.html
11 ./docs/i3-pod2html --stylesurl=https://i3wm.org/css build/testcases/lib/i3test.pm docs/lib-i3test.html
12 ./docs/i3-pod2html --stylesurl=https://i3wm.org/css testcases/lib/i3test/Test.pm docs/lib-i3test-test.html
1313 for file in $(sed 's/\.1$/.man/g' debian/i3-wm.manpages)
1414 do
1515 [ -f "$file" ] && asciidoc -a linkcss -a stylesdir=https://i3wm.org/css -a scriptsdir=https://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf "$file"