From 224576afcc44853d3f28d9b6efcb3a743ded9bea Mon Sep 17 00:00:00 2001 From: Michael Weiser Date: Thu, 12 Mar 2020 23:45:06 +0100 Subject: [PATCH] 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 --- include/sway/criteria.h | 9 ++++++ sway/criteria.c | 63 ++++++++++++++++++++++++++++++++++++++++- sway/sway.5.scd | 8 ++++++ 3 files changed, 79 insertions(+), 1 deletion(-) 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.