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).
This commit is contained in:
parent
abbf6a85d7
commit
3a818c0f20
@ -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 │
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
*
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
18
src/match.c
18
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);
|
||||
}
|
||||
|
90
testcases/t/315-all-criterion.t
Normal file
90
testcases/t/315-all-criterion.t
Normal file
@ -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;
|
Loading…
Reference in New Issue
Block a user