aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sway/commands/bind.c6
-rw-r--r--sway/input/keyboard.c43
-rw-r--r--sway/input/switch.c16
-rw-r--r--sway/sway.5.scd28
4 files changed, 67 insertions, 26 deletions
diff --git a/sway/commands/bind.c b/sway/commands/bind.c
index ea8179bb..d43c87fb 100644
--- a/sway/commands/bind.c
+++ b/sway/commands/bind.c
@@ -49,6 +49,10 @@ static bool binding_switch_compare(struct sway_switch_binding *binding_a,
if (binding_a->state != binding_b->state) {
return false;
}
+ if ((binding_a->flags & BINDING_LOCKED) !=
+ (binding_b->flags & BINDING_LOCKED)) {
+ return false;
+ }
return true;
}
@@ -68,7 +72,7 @@ static bool binding_key_compare(struct sway_binding *binding_a,
}
uint32_t conflict_generating_flags = BINDING_RELEASE | BINDING_BORDER
- | BINDING_CONTENTS | BINDING_TITLEBAR;
+ | BINDING_CONTENTS | BINDING_TITLEBAR | BINDING_LOCKED;
if ((binding_a->flags & conflict_generating_flags) !=
(binding_b->flags & conflict_generating_flags)) {
return false;
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);
diff --git a/sway/sway.5.scd b/sway/sway.5.scd
index 74963c9d..6d098d94 100644
--- a/sway/sway.5.scd
+++ b/sway/sway.5.scd
@@ -331,12 +331,17 @@ runtime.
Binds _key combo_ to execute the sway command _command_ when pressed. You
may use XKB key names here (*xev*(1) is a good tool for discovering these).
With the flag _--release_, the command is executed when the key combo is
- released. Unless the flag _--locked_ is set, the command will not be run
- when a screen locking program is active. If _input-device_ is given, the
- binding will only be executed for that input device and will be executed
- instead of any binding that is generic to all devices. By default, if you
- overwrite a binding, swaynag will give you a warning. To silence this, use
- the _--no-warn_ flag.
+ released. If _input-device_ is given, the binding will only be executed for
+ that input device and will be executed instead of any binding that is
+ generic to all devices. By default, if you overwrite a binding, swaynag
+ will give you a warning. To silence this, use the _--no-warn_ flag.
+
+ Unless the flag _--locked_ is set, the command will not be run when a
+ screen locking program is active. If there is a matching binding with
+ and without _--locked_, the one with will be preferred when locked and the
+ one without will be preferred when unlocked. If there are matching bindings
+ and one has both _--input-device_ and _--locked_ and the other has neither,
+ the former will be preferred even when unlocked.
Bindings to keysyms are layout-dependent. This can be changed with the
_--to-code_ flag. In this case, the keysyms will be translated into the
@@ -380,10 +385,13 @@ runtime.
respectively. _toggle_ is also supported to run a command both when the
switch is toggled on or off.
- Unless the flag _--locked_ is set, the command will not be run
- when a screen locking program is active. By default, if you
- overwrite a binding, swaynag will give you a warning. To silence this, use
- the _--no-warn_ flag.
+ Unless the flag _--locked_ is set, the command will not be run when a
+ screen locking program is active. If there is a matching binding with
+ and without _--locked_, the one with will be preferred when locked and the
+ one without will be preferred when unlocked.
+
+ By default, if you overwrite a binding, swaynag will give you a warning. To
+ silence this, use the _--no-warn_ flag.
Example:
```