diff --git a/include/sway/criteria.h b/include/sway/criteria.h index ad8610cd7..194b5e8a3 100644 --- a/include/sway/criteria.h +++ b/include/sway/criteria.h @@ -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); diff --git a/sway/criteria.c b/sway/criteria.c index 02b04fc89..f0d574113 100644 --- a/sway/criteria.c +++ b/sway/criteria.c @@ -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; } diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 9e42d8972..358bbfcb5 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -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.