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=<input>` 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.
This commit is contained in:
parent
2c6a10c4ba
commit
6afb392823
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
```
|
||||
|
|
Loading…
Reference in a new issue