aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2019-05-30 03:30:08 -0400
committerLibravatar Simon Ser <contact@emersion.fr>2019-05-30 10:47:42 +0300
commit6afb392823d27ec69bedc8fd74263c3d072cca29 (patch)
treea1a72a233a2ef8e89240b7702d7c9eabb3444bf0
parentProvide current DPMS state in GET_OUTPUTS (diff)
downloadsway-6afb392823d27ec69bedc8fd74263c3d072cca29.tar.gz
sway-6afb392823d27ec69bedc8fd74263c3d072cca29.tar.zst
sway-6afb392823d27ec69bedc8fd74263c3d072cca29.zip
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.
-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,
49 if (binding_a->state != binding_b->state) { 49 if (binding_a->state != binding_b->state) {
50 return false; 50 return false;
51 } 51 }
52 if ((binding_a->flags & BINDING_LOCKED) !=
53 (binding_b->flags & BINDING_LOCKED)) {
54 return false;
55 }
52 return true; 56 return true;
53} 57}
54 58
@@ -68,7 +72,7 @@ static bool binding_key_compare(struct sway_binding *binding_a,
68 } 72 }
69 73
70 uint32_t conflict_generating_flags = BINDING_RELEASE | BINDING_BORDER 74 uint32_t conflict_generating_flags = BINDING_RELEASE | BINDING_BORDER
71 | BINDING_CONTENTS | BINDING_TITLEBAR; 75 | BINDING_CONTENTS | BINDING_TITLEBAR | BINDING_LOCKED;
72 if ((binding_a->flags & conflict_generating_flags) != 76 if ((binding_a->flags & conflict_generating_flags) !=
73 (binding_b->flags & conflict_generating_flags)) { 77 (binding_b->flags & conflict_generating_flags)) {
74 return false; 78 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,
146 uint32_t modifiers, bool release, bool locked, const char *input) { 146 uint32_t modifiers, bool release, bool locked, const char *input) {
147 for (int i = 0; i < bindings->length; ++i) { 147 for (int i = 0; i < bindings->length; ++i) {
148 struct sway_binding *binding = bindings->items[i]; 148 struct sway_binding *binding = bindings->items[i];
149 bool binding_locked = binding->flags & BINDING_LOCKED; 149 bool binding_locked = (binding->flags & BINDING_LOCKED) != 0;
150 bool binding_release = binding->flags & BINDING_RELEASE; 150 bool binding_release = binding->flags & BINDING_RELEASE;
151 151
152 if (modifiers ^ binding->modifiers || 152 if (modifiers ^ binding->modifiers ||
@@ -178,18 +178,37 @@ static void get_active_binding(const struct sway_shortcut_state *state,
178 continue; 178 continue;
179 } 179 }
180 180
181 if (*current_binding && *current_binding != binding && 181 if (*current_binding) {
182 strcmp((*current_binding)->input, binding->input) == 0) { 182 if (*current_binding == binding) {
183 sway_log(SWAY_DEBUG, "encountered duplicate bindings %d and %d", 183 continue;
184 (*current_binding)->order, binding->order);
185 } else if (!*current_binding ||
186 strcmp((*current_binding)->input, "*") == 0) {
187 *current_binding = binding;
188
189 if (strcmp((*current_binding)->input, input) == 0) {
190 // If a binding is found for the exact input, quit searching
191 return;
192 } 184 }
185
186 bool current_locked =
187 ((*current_binding)->flags & BINDING_LOCKED) != 0;
188 bool current_input = strcmp((*current_binding)->input, input) == 0;
189 bool binding_input = strcmp(binding->input, input) == 0;
190
191 if (current_input == binding_input
192 && current_locked == binding_locked) {
193 sway_log(SWAY_DEBUG,
194 "Encountered conflicting bindings %d and %d",
195 (*current_binding)->order, binding->order);
196 continue;
197 }
198
199 if (current_input && !binding_input) {
200 continue; // Prefer the correct input
201 }
202
203 if (current_input == binding_input && current_locked == locked) {
204 continue; // Prefer correct lock state for matching inputs
205 }
206 }
207
208 *current_binding = binding;
209 if (strcmp((*current_binding)->input, input) == 0 &&
210 (((*current_binding)->flags & BINDING_LOCKED) == locked)) {
211 return; // If a perfect match is found, quit searching
193 } 212 }
194 } 213 }
195} 214}
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) {
38 sway_log(SWAY_DEBUG, "%s: type %d state %d", device_identifier, type, state); 38 sway_log(SWAY_DEBUG, "%s: type %d state %d", device_identifier, type, state);
39 39
40 list_t *bindings = config->current_mode->switch_bindings; 40 list_t *bindings = config->current_mode->switch_bindings;
41 struct sway_switch_binding *matched_binding = NULL;
41 for (int i = 0; i < bindings->length; ++i) { 42 for (int i = 0; i < bindings->length; ++i) {
42 struct sway_switch_binding *binding = bindings->items[i]; 43 struct sway_switch_binding *binding = bindings->items[i];
43 if (binding->type != type) { 44 if (binding->type != type) {
@@ -52,10 +53,19 @@ static void handle_switch_toggle(struct wl_listener *listener, void *data) {
52 continue; 53 continue;
53 } 54 }
54 55
55 struct sway_binding *dummy_binding = calloc(1, sizeof(struct sway_binding)); 56 matched_binding = binding;
57
58 if (binding_locked == input_inhibited) {
59 break;
60 }
61 }
62
63 if (matched_binding) {
64 struct sway_binding *dummy_binding =
65 calloc(1, sizeof(struct sway_binding));
56 dummy_binding->type = BINDING_SWITCH; 66 dummy_binding->type = BINDING_SWITCH;
57 dummy_binding->flags = binding->flags; 67 dummy_binding->flags = matched_binding->flags;
58 dummy_binding->command = binding->command; 68 dummy_binding->command = matched_binding->command;
59 69
60 seat_execute_command(seat, dummy_binding); 70 seat_execute_command(seat, dummy_binding);
61 free(dummy_binding); 71 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.
331 Binds _key combo_ to execute the sway command _command_ when pressed. You 331 Binds _key combo_ to execute the sway command _command_ when pressed. You
332 may use XKB key names here (*xev*(1) is a good tool for discovering these). 332 may use XKB key names here (*xev*(1) is a good tool for discovering these).
333 With the flag _--release_, the command is executed when the key combo is 333 With the flag _--release_, the command is executed when the key combo is
334 released. Unless the flag _--locked_ is set, the command will not be run 334 released. If _input-device_ is given, the binding will only be executed for
335 when a screen locking program is active. If _input-device_ is given, the 335 that input device and will be executed instead of any binding that is
336 binding will only be executed for that input device and will be executed 336 generic to all devices. By default, if you overwrite a binding, swaynag
337 instead of any binding that is generic to all devices. By default, if you 337 will give you a warning. To silence this, use the _--no-warn_ flag.
338 overwrite a binding, swaynag will give you a warning. To silence this, use 338
339 the _--no-warn_ flag. 339 Unless the flag _--locked_ is set, the command will not be run when a
340 screen locking program is active. If there is a matching binding with
341 and without _--locked_, the one with will be preferred when locked and the
342 one without will be preferred when unlocked. If there are matching bindings
343 and one has both _--input-device_ and _--locked_ and the other has neither,
344 the former will be preferred even when unlocked.
340 345
341 Bindings to keysyms are layout-dependent. This can be changed with the 346 Bindings to keysyms are layout-dependent. This can be changed with the
342 _--to-code_ flag. In this case, the keysyms will be translated into the 347 _--to-code_ flag. In this case, the keysyms will be translated into the
@@ -380,10 +385,13 @@ runtime.
380 respectively. _toggle_ is also supported to run a command both when the 385 respectively. _toggle_ is also supported to run a command both when the
381 switch is toggled on or off. 386 switch is toggled on or off.
382 387
383 Unless the flag _--locked_ is set, the command will not be run 388 Unless the flag _--locked_ is set, the command will not be run when a
384 when a screen locking program is active. By default, if you 389 screen locking program is active. If there is a matching binding with
385 overwrite a binding, swaynag will give you a warning. To silence this, use 390 and without _--locked_, the one with will be preferred when locked and the
386 the _--no-warn_ flag. 391 one without will be preferred when unlocked.
392
393 By default, if you overwrite a binding, swaynag will give you a warning. To
394 silence this, use the _--no-warn_ flag.
387 395
388 Example: 396 Example:
389``` 397```