aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/keyboard.c
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2019-07-26 12:02:18 -0400
committerLibravatar Simon Ser <contact@emersion.fr>2019-08-01 18:54:58 +0300
commit8ee054b1b95b7466c0dd89bfc9026f4083fb0016 (patch)
treebce2d4bfba93e6889c1aa57085297e4a997af2d8 /sway/input/keyboard.c
parentinput/keyboard: don't reset layout for same keymap (diff)
downloadsway-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/keyboard.c')
-rw-r--r--sway/input/keyboard.c42
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 */
144static void get_active_binding(const struct sway_shortcut_state *state, 144static 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