criteria: Add keyboard shortcuts inhibitor selector

Add a criteria selector that allows to match presence and state of
keyboard shortcuts inhibitors on views. This allows to give visual
feedback to the user on the state of an inhibitor through e.g.:

for_window [shortcuts_inhibitor=inactive] title_format !-%title
for_window [shortcuts_inhibitor=active] title_format !+%title
for_window [shortcuts_inhibitor=present] title_format !%title
for_window [shortcuts_inhibitor=absent] title_format %title

Beware: present in the example above overrides inactive and active
criteria because when active or inactive an inhbitor is obviously
present. Ordering does matter here.

Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
This commit is contained in:
Michael Weiser 2020-03-12 23:45:06 +01:00
parent aa48b926be
commit 224576afcc
3 changed files with 79 additions and 1 deletions

View file

@ -24,6 +24,14 @@ struct pattern {
pcre *regex;
};
enum criteria_keyboard_shortcuts_inhibitor {
// implicit: C_KEYBOARD_SHORTCUTS_INHIBITOR_UNSPEC = 0,
C_KEYBOARD_SHORTCUTS_INHIBITOR_PRESENT = 1,
C_KEYBOARD_SHORTCUTS_INHIBITOR_ABSENT,
C_KEYBOARD_SHORTCUTS_INHIBITOR_ACTIVE,
C_KEYBOARD_SHORTCUTS_INHIBITOR_INACTIVE,
};
struct criteria {
enum criteria_type type;
char *raw; // entire criteria string (for logging)
@ -47,6 +55,7 @@ struct criteria {
char urgent; // 'l' for latest or 'o' for oldest
struct pattern *workspace;
pid_t pid;
enum criteria_keyboard_shortcuts_inhibitor keyboard_shortcuts_inhibitor;
};
bool criteria_is_empty(struct criteria *criteria);

View file

@ -32,7 +32,8 @@ bool criteria_is_empty(struct criteria *criteria) {
&& !criteria->tiling
&& !criteria->urgent
&& !criteria->workspace
&& !criteria->pid;
&& !criteria->pid
&& !criteria->keyboard_shortcuts_inhibitor;
}
// The error pointer is used for parsing functions, and saves having to pass it
@ -377,6 +378,44 @@ static bool criteria_matches_view(struct criteria *criteria,
}
}
if (criteria->keyboard_shortcuts_inhibitor) {
bool present = false;
bool active = false;
if (view->surface) {
const struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor =
keyboard_shortcuts_inhibitor_get_for_surface(
seat, view->surface);
if (sway_inhibitor) {
present = true;
active = sway_inhibitor->inhibitor->active;
}
}
switch (criteria->keyboard_shortcuts_inhibitor) {
case C_KEYBOARD_SHORTCUTS_INHIBITOR_PRESENT:
if (!present) {
return false;
}
break;
case C_KEYBOARD_SHORTCUTS_INHIBITOR_ABSENT:
if (present) {
return false;
}
break;
case C_KEYBOARD_SHORTCUTS_INHIBITOR_ACTIVE:
if (!present || !active) {
return false;
}
break;
case C_KEYBOARD_SHORTCUTS_INHIBITOR_INACTIVE:
if (!present || active) {
return false;
}
break;
}
}
return true;
}
@ -466,6 +505,7 @@ enum criteria_token {
T_URGENT,
T_WORKSPACE,
T_PID,
T_KEYBOARD_SHORTCUTS_INHIBITOR,
T_INVALID,
};
@ -503,6 +543,8 @@ static enum criteria_token token_from_name(char *name) {
return T_FLOATING;
} else if (strcmp(name, "pid") == 0) {
return T_PID;
} else if (strcmp(name, "shortcuts_inhibitor") == 0) {
return T_KEYBOARD_SHORTCUTS_INHIBITOR;
}
return T_INVALID;
}
@ -603,6 +645,25 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) {
error = strdup("The value for 'pid' should be numeric");
}
break;
case T_KEYBOARD_SHORTCUTS_INHIBITOR:
if (strcmp(value, "present") == 0) {
criteria->keyboard_shortcuts_inhibitor =
C_KEYBOARD_SHORTCUTS_INHIBITOR_PRESENT;
} else if (strcmp(value, "absent") == 0) {
criteria->keyboard_shortcuts_inhibitor =
C_KEYBOARD_SHORTCUTS_INHIBITOR_ABSENT;
} else if (strcmp(value, "active") == 0) {
criteria->keyboard_shortcuts_inhibitor =
C_KEYBOARD_SHORTCUTS_INHIBITOR_ACTIVE;
} else if (strcmp(value, "inactive") == 0) {
criteria->keyboard_shortcuts_inhibitor =
C_KEYBOARD_SHORTCUTS_INHIBITOR_INACTIVE;
} else {
error = strdup("The value for 'shortcuts_inhibitor' "
"must be 'present', 'absent', "
"'active' or 'inactive'");
}
break;
case T_INVALID:
break;
}

View file

@ -902,6 +902,14 @@ The following attributes may be matched with:
Can be a regular expression. If value is \_\_focused\_\_, then the shell
must be the same as that of the currently focused window.
*shortcuts_inhibitor*
Matches the state of keyboard shortcuts inhibitors on windows. Values
can be "present", "absent", "active" or "inactive" and will match
windows where an inhibitor is present, absent, active or inactive,
respectively. Note that currently any existing inhibitor (present) will
either be active or inactive, so criteria can overlap and revert each
others changes depdending on their order in the config file.
*tiling*
Matches tiling windows.