From 6afb392823d27ec69bedc8fd74263c3d072cca29 Mon Sep 17 00:00:00 2001 From: Brian Ashworth Date: Thu, 30 May 2019 03:30:08 -0400 Subject: bindings: allow unlocked and locked bindings This changes the behavior of bindings to make the `BINDING_LOCKED` flag conflicting, which will allow for both unlocked and locked bindings. If there are two matching bindings and one has `--locked` and the other does not, the one with `--locked` will be preferred when locked and the one without will be preferred when unlocked. If there are two matching bindings and one has both a matching `--input-device=` and `--locked` and the other has neither, the former will be preferred for both unlocked and locked. This also refactors `get_active_binding` in `sway/input/keyboard.c` to make it easier to read. --- sway/input/keyboard.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) (limited to 'sway/input/keyboard.c') diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 78e8fa0c..dcfaa4fa 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c @@ -146,7 +146,7 @@ static void get_active_binding(const struct sway_shortcut_state *state, uint32_t modifiers, bool release, bool locked, const char *input) { for (int i = 0; i < bindings->length; ++i) { struct sway_binding *binding = bindings->items[i]; - bool binding_locked = binding->flags & BINDING_LOCKED; + bool binding_locked = (binding->flags & BINDING_LOCKED) != 0; bool binding_release = binding->flags & BINDING_RELEASE; if (modifiers ^ binding->modifiers || @@ -178,18 +178,37 @@ static void get_active_binding(const struct sway_shortcut_state *state, continue; } - if (*current_binding && *current_binding != binding && - strcmp((*current_binding)->input, binding->input) == 0) { - sway_log(SWAY_DEBUG, "encountered duplicate bindings %d and %d", - (*current_binding)->order, binding->order); - } else if (!*current_binding || - strcmp((*current_binding)->input, "*") == 0) { - *current_binding = binding; - - if (strcmp((*current_binding)->input, input) == 0) { - // If a binding is found for the exact input, quit searching - return; + if (*current_binding) { + if (*current_binding == binding) { + continue; } + + bool current_locked = + ((*current_binding)->flags & BINDING_LOCKED) != 0; + bool current_input = strcmp((*current_binding)->input, input) == 0; + bool binding_input = strcmp(binding->input, input) == 0; + + if (current_input == binding_input + && current_locked == binding_locked) { + sway_log(SWAY_DEBUG, + "Encountered conflicting bindings %d and %d", + (*current_binding)->order, binding->order); + continue; + } + + if (current_input && !binding_input) { + continue; // Prefer the correct input + } + + if (current_input == binding_input && current_locked == locked) { + continue; // Prefer correct lock state for matching inputs + } + } + + *current_binding = binding; + if (strcmp((*current_binding)->input, input) == 0 && + (((*current_binding)->flags & BINDING_LOCKED) == locked)) { + return; // If a perfect match is found, quit searching } } } -- cgit v1.2.3