diff options
Diffstat (limited to 'sway')
-rw-r--r-- | sway/commands/bind.c | 6 | ||||
-rw-r--r-- | sway/input/keyboard.c | 43 | ||||
-rw-r--r-- | sway/input/switch.c | 16 | ||||
-rw-r--r-- | sway/sway.5.scd | 28 |
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 | ``` |