summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Garzon <iscgarzon@gmail.com>2021-07-23 14:19:36 +0300
committerIsaac Garzon <iscgarzon@gmail.com>2021-07-24 22:18:58 +0300
commit3a818c0f20d08160380a4dca52e1e87f54e8efa3 (patch)
tree209f5808fb0a2bcd2363b276bac7260eb248a116
parentabbf6a85d712ef1790b02122eb432e4bafe20576 (diff)
downloadi3-3a818c0f20d08160380a4dca52e1e87f54e8efa3.tar.gz
i3-3a818c0f20d08160380a4dca52e1e87f54e8efa3.zip
Implement 'all' matching criterion
This criterion matches all open windows, as a more readable (and correct) version of the 'class=".*"' criterion (more correct because it'll also match windows which don't have WM_CLASS set yet).
-rw-r--r--RELEASE-NOTES-next1
-rw-r--r--docs/userguide5
-rw-r--r--include/data.h1
-rw-r--r--parser-specs/commands.spec2
-rw-r--r--parser-specs/config.spec2
-rw-r--r--src/match.c18
-rw-r--r--testcases/t/315-all-criterion.t90
7 files changed, 116 insertions, 3 deletions
diff --git a/RELEASE-NOTES-next b/RELEASE-NOTES-next
index 3b6de271..77e290cf 100644
--- a/RELEASE-NOTES-next
+++ b/RELEASE-NOTES-next
@@ -41,6 +41,7 @@ option is enabled and only then sets a screenshot as background.
• Add %machine placeholder (WM_CLIENT_MACHINE) to title_format
• Allow multiple output names in 'move container|workspace to output'
• Add 'move container|workspace to output next'
+ • Add 'all' window matching criterion
┌────────────────────────────┐
│ Bugfixes │
diff --git a/docs/userguide b/docs/userguide
index 05eb4aac..9f28e689 100644
--- a/docs/userguide
+++ b/docs/userguide
@@ -1959,12 +1959,17 @@ bindsym $mod+x [class="Firefox" window_role="About"] kill
# enable floating mode and move container to workspace 4
for_window [class="^evil-app$"] floating enable, move container to workspace 4
+# enable window icons for all windows with extra horizontal padding of 1px
+for_window [all] title_window_icon padding 1px
+
# move all floating windows to the scratchpad
bindsym $mod+x [floating] move scratchpad
------------------------------------
The criteria which are currently implemented are:
+all::
+ Matches all windows. This criterion requires no value.
class::
Compares the window class (the second part of WM_CLASS). Use the
special value +\_\_focused__+ to match all windows having the same window
diff --git a/include/data.h b/include/data.h
index 0679adf7..95acd66d 100644
--- a/include/data.h
+++ b/include/data.h
@@ -530,6 +530,7 @@ struct Match {
WM_FLOATING_USER,
WM_FLOATING } window_mode;
Con *con_id;
+ bool match_all_windows;
/* Where the window looking for a match should be inserted:
*
diff --git a/parser-specs/commands.spec b/parser-specs/commands.spec
index 43c784a2..7d3367ea 100644
--- a/parser-specs/commands.spec
+++ b/parser-specs/commands.spec
@@ -56,7 +56,7 @@ state CRITERIA:
ctype = 'urgent' -> CRITERION
ctype = 'workspace' -> CRITERION
ctype = 'machine' -> CRITERION
- ctype = 'tiling', 'floating'
+ ctype = 'tiling', 'floating', 'all'
-> call cmd_criteria_add($ctype, NULL); CRITERIA
']' -> call cmd_criteria_match_windows(); INITIAL
diff --git a/parser-specs/config.spec b/parser-specs/config.spec
index 1b6d7340..a52a769f 100644
--- a/parser-specs/config.spec
+++ b/parser-specs/config.spec
@@ -200,7 +200,7 @@ state CRITERIA:
ctype = 'machine' -> CRITERION
ctype = 'floating_from' -> CRITERION_FROM
ctype = 'tiling_from' -> CRITERION_FROM
- ctype = 'tiling', 'floating'
+ ctype = 'tiling', 'floating', 'all'
-> call cfg_criteria_add($ctype, NULL); CRITERIA
']'
-> call cfg_criteria_pop_state()
diff --git a/src/match.c b/src/match.c
index 65646f9e..34314e25 100644
--- a/src/match.c
+++ b/src/match.c
@@ -53,7 +53,8 @@ bool match_is_empty(Match *match) {
match->window_type == UINT32_MAX &&
match->con_id == NULL &&
match->dock == M_NODOCK &&
- match->window_mode == WM_ANY);
+ match->window_mode == WM_ANY &&
+ match->match_all_windows == false);
}
/*
@@ -260,6 +261,10 @@ bool match_matches_window(Match *match, i3Window *window) {
LOG("window_mode matches\n");
}
+ /* NOTE: See the comment regarding 'all' in match_parse_property()
+ * for an explanation of why match_all_windows isn't explicitly
+ * checked. */
+
return true;
}
@@ -438,5 +443,16 @@ void match_parse_property(Match *match, const char *ctype, const char *cvalue) {
return;
}
+ /* match_matches_window() only checks negatively, so match_all_windows
+ * won't actually be used there, but that's OK because if no negative
+ * match is found (e.g. because of a more restrictive criterion) the
+ * return value of match_matches_window() is true.
+ * Setting it here only serves to cause match_is_empty() to return false,
+ * otherwise empty criteria rules apply, and that's not what we want. */
+ if (strcmp(ctype, "all") == 0) {
+ match->match_all_windows = true;
+ return;
+ }
+
ELOG("Unknown criterion: %s\n", ctype);
}
diff --git a/testcases/t/315-all-criterion.t b/testcases/t/315-all-criterion.t
new file mode 100644
index 00000000..f11410fd
--- /dev/null
+++ b/testcases/t/315-all-criterion.t
@@ -0,0 +1,90 @@
+#!perl
+# vim:ts=4:sw=4:expandtab
+#
+# Please read the following documents before working on tests:
+# • https://build.i3wm.org/docs/testsuite.html
+# (or docs/testsuite)
+#
+# • https://build.i3wm.org/docs/lib-i3test.html
+# (alternatively: perldoc ./testcases/lib/i3test.pm)
+#
+# • https://build.i3wm.org/docs/ipc.html
+# (or docs/ipc)
+#
+# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
+# (unless you are already familiar with Perl)
+#
+# Tests all kinds of matching methods
+#
+use i3test;
+
+my $tmp = fresh_workspace;
+
+ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
+
+# Open a new window
+my $window = open_window;
+my $content = get_ws_content($tmp);
+ok(@{$content} == 1, 'window mapped');
+my $win = $content->[0];
+
+######################################################################
+# check that simple matching works.
+######################################################################
+cmd '[all] kill';
+
+sync_with_i3;
+
+is_num_children($tmp, 0, 'window killed');
+
+######################################################################
+# check that simple matching against multiple windows works.
+######################################################################
+
+$tmp = fresh_workspace;
+
+my $left = open_window;
+ok($left->mapped, 'left window mapped');
+
+my $right = open_window;
+ok($right->mapped, 'right window mapped');
+
+# two windows should be here
+is_num_children($tmp, 2, 'two windows opened');
+
+cmd '[all] kill';
+
+sync_with_i3;
+
+is_num_children($tmp, 0, 'two windows killed');
+
+######################################################################
+# check that multiple criteria work are checked with a logical AND,
+# not a logical OR (that is, matching is not cancelled after the first
+# criterion matches).
+######################################################################
+
+$tmp = fresh_workspace;
+
+my $left = open_window(name => 'left');
+ok($left->mapped, 'left window mapped');
+
+my $right = open_window(name => 'right');
+ok($right->mapped, 'right window mapped');
+
+# two windows should be here
+is_num_children($tmp, 2, 'two windows opened');
+
+cmd '[all title="left"] kill';
+
+sync_with_i3;
+
+is_num_children($tmp, 1, 'one window still there');
+
+cmd '[all] kill';
+
+sync_with_i3;
+
+is_num_children($tmp, 0, 'all windows killed');
+
+done_testing;