Skip to content
This repository has been archived by the owner on Apr 18, 2023. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge remote-tracking branch 'vanilla/next' into gaps-next
  • Loading branch information
Airblader committed Jul 26, 2021
2 parents 991824a + fee005b commit 01a45d2
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 12 deletions.
1 change: 1 addition & 0 deletions RELEASE-NOTES-next
Expand Up @@ -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 │
Expand Down
5 changes: 5 additions & 0 deletions docs/userguide
Expand Up @@ -1976,12 +1976,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
Expand Down
1 change: 1 addition & 0 deletions include/data.h
Expand Up @@ -549,6 +549,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:
*
Expand Down
17 changes: 8 additions & 9 deletions libi3/get_process_filename.c
Expand Up @@ -27,15 +27,14 @@ char *get_process_filename(const char *prefix) {
char *tmp;
sasprintf(&tmp, "%s/i3", dir);
dir = tmp;
struct stat buf;
if (stat(dir, &buf) != 0) {
if (mkdir(dir, 0700) == -1) {
warn("Could not mkdir(%s)", dir);
errx(EXIT_FAILURE, "Check permissions of $XDG_RUNTIME_DIR = '%s'",
getenv("XDG_RUNTIME_DIR"));
perror("mkdir()");
return NULL;
}
/* mkdirp() should prevent race between multiple i3 instances started
* in parallel from causing problem */
if (mkdirp(dir, 0700) == -1) {
warn("Could not mkdirp(%s)", dir);
errx(EXIT_FAILURE, "Check permissions of $XDG_RUNTIME_DIR = '%s'",
getenv("XDG_RUNTIME_DIR"));
perror("mkdirp()");
return NULL;
}
} else {
/* If not, we create a (secure) temp directory using the template
Expand Down
2 changes: 1 addition & 1 deletion parser-specs/commands.spec
Expand Up @@ -57,7 +57,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

Expand Down
2 changes: 1 addition & 1 deletion parser-specs/config.spec
Expand Up @@ -227,7 +227,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()
Expand Down
18 changes: 17 additions & 1 deletion src/match.c
Expand Up @@ -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);
}

/*
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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 changes: 90 additions & 0 deletions 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;

0 comments on commit 01a45d2

Please sign in to comment.