aboutsummaryrefslogtreecommitdiff
path: root/sway/input
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input')
-rw-r--r--sway/input/keyboard.c43
-rw-r--r--sway/input/switch.c16
2 files changed, 44 insertions, 15 deletions
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
}
}
}
diff --git a/sway/input/switch.c b/sway/input/switch.c
index a8769713..d825c5c3 100644
--- a/sway/input/switch.c
+++ b/sway/input/switch.c
@@ -38,6 +38,7 @@ static void handle_switch_toggle(struct wl_listener *listener, void *data) {
sway_log(SWAY_DEBUG, "%s: type %d state %d", device_identifier, type, state);
list_t *bindings = config->current_mode->switch_bindings;
+ struct sway_switch_binding *matched_binding = NULL;
for (int i = 0; i < bindings->length; ++i) {
struct sway_switch_binding *binding = bindings->items[i];
if (binding->type != type) {
@@ -52,10 +53,19 @@ static void handle_switch_toggle(struct wl_listener *listener, void *data) {
continue;
}
- struct sway_binding *dummy_binding = calloc(1, sizeof(struct sway_binding));
+ matched_binding = binding;
+
+ if (binding_locked == input_inhibited) {
+ break;
+ }
+ }
+
+ if (matched_binding) {
+ struct sway_binding *dummy_binding =
+ calloc(1, sizeof(struct sway_binding));
dummy_binding->type = BINDING_SWITCH;
- dummy_binding->flags = binding->flags;
- dummy_binding->command = binding->command;
+ dummy_binding->flags = matched_binding->flags;
+ dummy_binding->command = matched_binding->command;
seat_execute_command(seat, dummy_binding);
free(dummy_binding);