Implement new criterion 'workspace'.
If the match expression is a plain number (e.g., '99'), the number of a workspace will be compared strictly. Otherwise, the match expression is taken as a regular expression and compared against the workspace's name. This allows all of the following: for_window [workspace=5] ... for_window [workspace="5:foo"] ... for_window [workspace="foo"] ... fixes #1769
This commit is contained in:
parent
8df7e4ecb9
commit
be406d036d
|
@ -1597,14 +1597,16 @@ urgent::
|
||||||
Compares the urgent state of the window. Can be "latest" or "oldest".
|
Compares the urgent state of the window. Can be "latest" or "oldest".
|
||||||
Matches the latest or oldest urgent window, respectively.
|
Matches the latest or oldest urgent window, respectively.
|
||||||
(The following aliases are also available: newest, last, recent, first)
|
(The following aliases are also available: newest, last, recent, first)
|
||||||
|
workspace::
|
||||||
|
Compares the workspace name of the workspace the window belongs to.
|
||||||
con_mark::
|
con_mark::
|
||||||
Compares the mark set for this container, see <<vim_like_marks>>.
|
Compares the mark set for this container, see <<vim_like_marks>>.
|
||||||
con_id::
|
con_id::
|
||||||
Compares the i3-internal container ID, which you can get via the IPC
|
Compares the i3-internal container ID, which you can get via the IPC
|
||||||
interface. Handy for scripting.
|
interface. Handy for scripting.
|
||||||
|
|
||||||
The criteria +class+, +instance+, +role+, +title+ and +mark+ are actually
|
The criteria +class+, +instance+, +role+, +title+, +workspace+ and +mark+ are
|
||||||
regular expressions (PCRE). See +pcresyntax(3)+ or +perldoc perlre+ for
|
actually regular expressions (PCRE). See +pcresyntax(3)+ or +perldoc perlre+ for
|
||||||
information on how to use them.
|
information on how to use them.
|
||||||
|
|
||||||
[[exec]]
|
[[exec]]
|
||||||
|
|
|
@ -417,6 +417,7 @@ struct Match {
|
||||||
struct regex *instance;
|
struct regex *instance;
|
||||||
struct regex *mark;
|
struct regex *mark;
|
||||||
struct regex *window_role;
|
struct regex *window_role;
|
||||||
|
struct regex *workspace;
|
||||||
xcb_atom_t window_type;
|
xcb_atom_t window_type;
|
||||||
enum {
|
enum {
|
||||||
U_DONTCHECK = -1,
|
U_DONTCHECK = -1,
|
||||||
|
|
|
@ -51,6 +51,7 @@ state CRITERIA:
|
||||||
ctype = 'con_mark' -> CRITERION
|
ctype = 'con_mark' -> CRITERION
|
||||||
ctype = 'title' -> CRITERION
|
ctype = 'title' -> CRITERION
|
||||||
ctype = 'urgent' -> CRITERION
|
ctype = 'urgent' -> CRITERION
|
||||||
|
ctype = 'workspace' -> CRITERION
|
||||||
']' -> call cmd_criteria_match_windows(); INITIAL
|
']' -> call cmd_criteria_match_windows(); INITIAL
|
||||||
|
|
||||||
state CRITERION:
|
state CRITERION:
|
||||||
|
|
|
@ -170,6 +170,7 @@ state CRITERIA:
|
||||||
ctype = 'con_mark' -> CRITERION
|
ctype = 'con_mark' -> CRITERION
|
||||||
ctype = 'title' -> CRITERION
|
ctype = 'title' -> CRITERION
|
||||||
ctype = 'urgent' -> CRITERION
|
ctype = 'urgent' -> CRITERION
|
||||||
|
ctype = 'workspace' -> CRITERION
|
||||||
']'
|
']'
|
||||||
-> call cfg_criteria_pop_state()
|
-> call cfg_criteria_pop_state()
|
||||||
|
|
||||||
|
|
|
@ -411,6 +411,11 @@ void cmd_criteria_add(I3_CMD, char *ctype, char *cvalue) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcmp(ctype, "workspace") == 0) {
|
||||||
|
current_match->workspace = regex_new(cvalue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ELOG("Unknown criterion: %s\n", ctype);
|
ELOG("Unknown criterion: %s\n", ctype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,11 @@ CFGFUN(criteria_add, const char *ctype, const char *cvalue) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcmp(ctype, "workspace") == 0) {
|
||||||
|
current_match->workspace = regex_new(cvalue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ELOG("Unknown criterion: %s\n", ctype);
|
ELOG("Unknown criterion: %s\n", ctype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
src/match.c
15
src/match.c
|
@ -48,6 +48,7 @@ bool match_is_empty(Match *match) {
|
||||||
match->class == NULL &&
|
match->class == NULL &&
|
||||||
match->instance == NULL &&
|
match->instance == NULL &&
|
||||||
match->window_role == NULL &&
|
match->window_role == NULL &&
|
||||||
|
match->workspace == NULL &&
|
||||||
match->urgent == U_DONTCHECK &&
|
match->urgent == U_DONTCHECK &&
|
||||||
match->id == XCB_NONE &&
|
match->id == XCB_NONE &&
|
||||||
match->window_type == UINT32_MAX &&
|
match->window_type == UINT32_MAX &&
|
||||||
|
@ -78,6 +79,7 @@ void match_copy(Match *dest, Match *src) {
|
||||||
DUPLICATE_REGEX(class);
|
DUPLICATE_REGEX(class);
|
||||||
DUPLICATE_REGEX(instance);
|
DUPLICATE_REGEX(instance);
|
||||||
DUPLICATE_REGEX(window_role);
|
DUPLICATE_REGEX(window_role);
|
||||||
|
DUPLICATE_REGEX(workspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -172,6 +174,19 @@ bool match_matches_window(Match *match, i3Window *window) {
|
||||||
LOG("urgent matches oldest\n");
|
LOG("urgent matches oldest\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match->workspace != NULL) {
|
||||||
|
Con *con = con_by_window_id(window->id);
|
||||||
|
assert(con != NULL);
|
||||||
|
Con *ws = con_get_workspace(con);
|
||||||
|
assert(ws != NULL);
|
||||||
|
|
||||||
|
if (regex_matches(match->workspace, ws->name)) {
|
||||||
|
LOG("workspace matches (%s)\n", ws->name);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (match->dock != M_DONTCHECK) {
|
if (match->dock != M_DONTCHECK) {
|
||||||
if ((window->dock == W_DOCK_TOP && match->dock == M_DOCK_TOP) ||
|
if ((window->dock == W_DOCK_TOP && match->dock == M_DOCK_TOP) ||
|
||||||
(window->dock == W_DOCK_BOTTOM && match->dock == M_DOCK_BOTTOM) ||
|
(window->dock == W_DOCK_BOTTOM && match->dock == M_DOCK_BOTTOM) ||
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
use i3test i3_autostart => 0;
|
use i3test i3_autostart => 0;
|
||||||
use X11::XCB qw(PROP_MODE_REPLACE);
|
use X11::XCB qw(PROP_MODE_REPLACE);
|
||||||
|
|
||||||
|
my (@nodes);
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
# 1: test the following directive:
|
# 1: test the following directive:
|
||||||
# for_window [class="borderless"] border none
|
# for_window [class="borderless"] border none
|
||||||
|
@ -435,6 +437,27 @@ EOT
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# 12: check that the criterion 'workspace' works
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
$config = <<"EOT";
|
||||||
|
# i3 config file (v4)
|
||||||
|
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
|
||||||
|
for_window [workspace="trigger"] floating enable, mark triggered
|
||||||
|
EOT
|
||||||
|
|
||||||
|
$pid = launch_with_config($config);
|
||||||
|
|
||||||
|
cmd 'workspace trigger';
|
||||||
|
$window = open_window;
|
||||||
|
|
||||||
|
@nodes = @{get_ws('trigger')->{floating_nodes}};
|
||||||
|
cmp_ok(@nodes, '==', 1, 'one floating container on this workspace');
|
||||||
|
is($nodes[0]->{nodes}[0]->{mark}, 'triggered', "mark set for workspace criterion");
|
||||||
|
|
||||||
|
exit_gracefully($pid);
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
|
|
||||||
done_testing;
|
done_testing;
|
||||||
|
|
Loading…
Reference in New Issue