summaryrefslogtreecommitdiffstats
path: root/sway/input
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 /sway/input
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.
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,
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);