diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2019-07-26 12:02:18 -0400 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2019-08-01 18:54:58 +0300 |
commit | 8ee054b1b95b7466c0dd89bfc9026f4083fb0016 (patch) | |
tree | bce2d4bfba93e6889c1aa57085297e4a997af2d8 /sway/input | |
parent | input/keyboard: don't reset layout for same keymap (diff) | |
download | sway-8ee054b1b95b7466c0dd89bfc9026f4083fb0016.tar.gz sway-8ee054b1b95b7466c0dd89bfc9026f4083fb0016.tar.zst sway-8ee054b1b95b7466c0dd89bfc9026f4083fb0016.zip |
bindsym/code: add group support
This adds support for specifying a binding for a specific group. Any
binding without a group listed will be available in all groups. The
priority for matching bindings is as follows: input device, group, and
locked state.
For full compatibility with i3, this also adds Mode_switch as an alias
for Group2. Since i3 only supports this for backwards compatibility
with older versions of i3, it is implemented here, but not documented.
Diffstat (limited to 'sway/input')
-rw-r--r-- | sway/input/keyboard.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index aecabbf4..680d1f69 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c | |||
@@ -143,7 +143,8 @@ static void update_shortcut_state(struct sway_shortcut_state *state, | |||
143 | */ | 143 | */ |
144 | static void get_active_binding(const struct sway_shortcut_state *state, | 144 | static void get_active_binding(const struct sway_shortcut_state *state, |
145 | list_t *bindings, struct sway_binding **current_binding, | 145 | list_t *bindings, struct sway_binding **current_binding, |
146 | uint32_t modifiers, bool release, bool locked, const char *input) { | 146 | uint32_t modifiers, bool release, bool locked, const char *input, |
147 | xkb_layout_index_t group) { | ||
147 | for (int i = 0; i < bindings->length; ++i) { | 148 | for (int i = 0; i < bindings->length; ++i) { |
148 | struct sway_binding *binding = bindings->items[i]; | 149 | struct sway_binding *binding = bindings->items[i]; |
149 | bool binding_locked = (binding->flags & BINDING_LOCKED) != 0; | 150 | bool binding_locked = (binding->flags & BINDING_LOCKED) != 0; |
@@ -152,6 +153,8 @@ static void get_active_binding(const struct sway_shortcut_state *state, | |||
152 | if (modifiers ^ binding->modifiers || | 153 | if (modifiers ^ binding->modifiers || |
153 | release != binding_release || | 154 | release != binding_release || |
154 | locked > binding_locked || | 155 | locked > binding_locked || |
156 | (binding->group != XKB_LAYOUT_INVALID && | ||
157 | binding->group != group) || | ||
155 | (strcmp(binding->input, input) != 0 && | 158 | (strcmp(binding->input, input) != 0 && |
156 | strcmp(binding->input, "*") != 0)) { | 159 | strcmp(binding->input, "*") != 0)) { |
157 | continue; | 160 | continue; |
@@ -186,10 +189,14 @@ static void get_active_binding(const struct sway_shortcut_state *state, | |||
186 | bool current_locked = | 189 | bool current_locked = |
187 | ((*current_binding)->flags & BINDING_LOCKED) != 0; | 190 | ((*current_binding)->flags & BINDING_LOCKED) != 0; |
188 | bool current_input = strcmp((*current_binding)->input, input) == 0; | 191 | bool current_input = strcmp((*current_binding)->input, input) == 0; |
192 | bool current_group_set = | ||
193 | (*current_binding)->group != XKB_LAYOUT_INVALID; | ||
189 | bool binding_input = strcmp(binding->input, input) == 0; | 194 | bool binding_input = strcmp(binding->input, input) == 0; |
195 | bool binding_group_set = binding->group != XKB_LAYOUT_INVALID; | ||
190 | 196 | ||
191 | if (current_input == binding_input | 197 | if (current_input == binding_input |
192 | && current_locked == binding_locked) { | 198 | && current_locked == binding_locked |
199 | && current_group_set == binding_group_set) { | ||
193 | sway_log(SWAY_DEBUG, | 200 | sway_log(SWAY_DEBUG, |
194 | "Encountered conflicting bindings %d and %d", | 201 | "Encountered conflicting bindings %d and %d", |
195 | (*current_binding)->order, binding->order); | 202 | (*current_binding)->order, binding->order); |
@@ -200,14 +207,22 @@ static void get_active_binding(const struct sway_shortcut_state *state, | |||
200 | continue; // Prefer the correct input | 207 | continue; // Prefer the correct input |
201 | } | 208 | } |
202 | 209 | ||
203 | if (current_input == binding_input && current_locked == locked) { | 210 | if (current_input == binding_input && |
204 | continue; // Prefer correct lock state for matching inputs | 211 | (*current_binding)->group == group) { |
212 | continue; // Prefer correct group for matching inputs | ||
213 | } | ||
214 | |||
215 | if (current_input == binding_input && | ||
216 | current_group_set == binding_group_set && | ||
217 | current_locked == locked) { | ||
218 | continue; // Prefer correct lock state for matching input+group | ||
205 | } | 219 | } |
206 | } | 220 | } |
207 | 221 | ||
208 | *current_binding = binding; | 222 | *current_binding = binding; |
209 | if (strcmp((*current_binding)->input, input) == 0 && | 223 | if (strcmp((*current_binding)->input, input) == 0 && |
210 | (((*current_binding)->flags & BINDING_LOCKED) == locked)) { | 224 | (((*current_binding)->flags & BINDING_LOCKED) == locked) && |
225 | (*current_binding)->group == group) { | ||
211 | return; // If a perfect match is found, quit searching | 226 | return; // If a perfect match is found, quit searching |
212 | } | 227 | } |
213 | } | 228 | } |
@@ -344,13 +359,16 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { | |||
344 | struct sway_binding *binding_released = NULL; | 359 | struct sway_binding *binding_released = NULL; |
345 | get_active_binding(&keyboard->state_keycodes, | 360 | get_active_binding(&keyboard->state_keycodes, |
346 | config->current_mode->keycode_bindings, &binding_released, | 361 | config->current_mode->keycode_bindings, &binding_released, |
347 | code_modifiers, true, input_inhibited, device_identifier); | 362 | code_modifiers, true, input_inhibited, device_identifier, |
363 | keyboard->effective_layout); | ||
348 | get_active_binding(&keyboard->state_keysyms_raw, | 364 | get_active_binding(&keyboard->state_keysyms_raw, |
349 | config->current_mode->keysym_bindings, &binding_released, | 365 | config->current_mode->keysym_bindings, &binding_released, |
350 | raw_modifiers, true, input_inhibited, device_identifier); | 366 | raw_modifiers, true, input_inhibited, device_identifier, |
367 | keyboard->effective_layout); | ||
351 | get_active_binding(&keyboard->state_keysyms_translated, | 368 | get_active_binding(&keyboard->state_keysyms_translated, |
352 | config->current_mode->keysym_bindings, &binding_released, | 369 | config->current_mode->keysym_bindings, &binding_released, |
353 | translated_modifiers, true, input_inhibited, device_identifier); | 370 | translated_modifiers, true, input_inhibited, device_identifier, |
371 | keyboard->effective_layout); | ||
354 | 372 | ||
355 | // Execute stored release binding once no longer active | 373 | // Execute stored release binding once no longer active |
356 | if (keyboard->held_binding && binding_released != keyboard->held_binding && | 374 | if (keyboard->held_binding && binding_released != keyboard->held_binding && |
@@ -370,14 +388,16 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { | |||
370 | if (event->state == WLR_KEY_PRESSED) { | 388 | if (event->state == WLR_KEY_PRESSED) { |
371 | get_active_binding(&keyboard->state_keycodes, | 389 | get_active_binding(&keyboard->state_keycodes, |
372 | config->current_mode->keycode_bindings, &binding, | 390 | config->current_mode->keycode_bindings, &binding, |
373 | code_modifiers, false, input_inhibited, device_identifier); | 391 | code_modifiers, false, input_inhibited, device_identifier, |
392 | keyboard->effective_layout); | ||
374 | get_active_binding(&keyboard->state_keysyms_raw, | 393 | get_active_binding(&keyboard->state_keysyms_raw, |
375 | config->current_mode->keysym_bindings, &binding, | 394 | config->current_mode->keysym_bindings, &binding, |
376 | raw_modifiers, false, input_inhibited, device_identifier); | 395 | raw_modifiers, false, input_inhibited, device_identifier, |
396 | keyboard->effective_layout); | ||
377 | get_active_binding(&keyboard->state_keysyms_translated, | 397 | get_active_binding(&keyboard->state_keysyms_translated, |
378 | config->current_mode->keysym_bindings, &binding, | 398 | config->current_mode->keysym_bindings, &binding, |
379 | translated_modifiers, false, input_inhibited, | 399 | translated_modifiers, false, input_inhibited, |
380 | device_identifier); | 400 | device_identifier, keyboard->effective_layout); |
381 | } | 401 | } |
382 | 402 | ||
383 | // Set up (or clear) keyboard repeat for a pressed binding. Since the | 403 | // Set up (or clear) keyboard repeat for a pressed binding. Since the |