aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input')
-rw-r--r--sway/input/input-manager.c2
-rw-r--r--sway/input/keyboard.c272
-rw-r--r--sway/input/seat.c9
3 files changed, 245 insertions, 38 deletions
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index 4f9ed891..cfd39bab 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -47,7 +47,7 @@ struct sway_seat *input_manager_get_seat(const char *seat_name, bool create) {
47char *input_device_get_identifier(struct wlr_input_device *device) { 47char *input_device_get_identifier(struct wlr_input_device *device) {
48 int vendor = device->vendor; 48 int vendor = device->vendor;
49 int product = device->product; 49 int product = device->product;
50 char *name = strdup(device->name); 50 char *name = strdup(device->name ? device->name : "");
51 strip_whitespace(name); 51 strip_whitespace(name);
52 52
53 char *p = name; 53 char *p = name;
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c
index cdc4258d..e925c00d 100644
--- a/sway/input/keyboard.c
+++ b/sway/input/keyboard.c
@@ -3,8 +3,9 @@
3#include <strings.h> 3#include <strings.h>
4#include <wlr/backend/multi.h> 4#include <wlr/backend/multi.h>
5#include <wlr/backend/session.h> 5#include <wlr/backend/session.h>
6#include <wlr/types/wlr_idle.h>
7#include <wlr/interfaces/wlr_keyboard.h> 6#include <wlr/interfaces/wlr_keyboard.h>
7#include <wlr/types/wlr_idle.h>
8#include <wlr/types/wlr_keyboard_group.h>
8#include <xkbcommon/xkbcommon-names.h> 9#include <xkbcommon/xkbcommon-names.h>
9#include "sway/commands.h" 10#include "sway/commands.h"
10#include "sway/desktop/transaction.h" 11#include "sway/desktop/transaction.h"
@@ -150,7 +151,7 @@ static bool update_shortcut_state(struct sway_shortcut_state *state,
150static void get_active_binding(const struct sway_shortcut_state *state, 151static void get_active_binding(const struct sway_shortcut_state *state,
151 list_t *bindings, struct sway_binding **current_binding, 152 list_t *bindings, struct sway_binding **current_binding,
152 uint32_t modifiers, bool release, bool locked, const char *input, 153 uint32_t modifiers, bool release, bool locked, const char *input,
153 xkb_layout_index_t group) { 154 bool exact_input, xkb_layout_index_t group) {
154 for (int i = 0; i < bindings->length; ++i) { 155 for (int i = 0; i < bindings->length; ++i) {
155 struct sway_binding *binding = bindings->items[i]; 156 struct sway_binding *binding = bindings->items[i];
156 bool binding_locked = (binding->flags & BINDING_LOCKED) != 0; 157 bool binding_locked = (binding->flags & BINDING_LOCKED) != 0;
@@ -162,7 +163,7 @@ static void get_active_binding(const struct sway_shortcut_state *state,
162 (binding->group != XKB_LAYOUT_INVALID && 163 (binding->group != XKB_LAYOUT_INVALID &&
163 binding->group != group) || 164 binding->group != group) ||
164 (strcmp(binding->input, input) != 0 && 165 (strcmp(binding->input, input) != 0 &&
165 strcmp(binding->input, "*") != 0)) { 166 (strcmp(binding->input, "*") != 0 || exact_input))) {
166 continue; 167 continue;
167 } 168 }
168 169
@@ -317,16 +318,15 @@ void sway_keyboard_disarm_key_repeat(struct sway_keyboard *keyboard) {
317 } 318 }
318} 319}
319 320
320static void handle_keyboard_key(struct wl_listener *listener, void *data) { 321static void handle_key_event(struct sway_keyboard *keyboard,
321 struct sway_keyboard *keyboard = 322 struct wlr_event_keyboard_key *event) {
322 wl_container_of(listener, keyboard, keyboard_key);
323 struct sway_seat* seat = keyboard->seat_device->sway_seat; 323 struct sway_seat* seat = keyboard->seat_device->sway_seat;
324 struct wlr_seat *wlr_seat = seat->wlr_seat; 324 struct wlr_seat *wlr_seat = seat->wlr_seat;
325 struct wlr_input_device *wlr_device = 325 struct wlr_input_device *wlr_device =
326 keyboard->seat_device->input_device->wlr_device; 326 keyboard->seat_device->input_device->wlr_device;
327 char *device_identifier = input_device_get_identifier(wlr_device); 327 char *device_identifier = input_device_get_identifier(wlr_device);
328 bool exact_identifier = wlr_device->keyboard->group != NULL;
328 wlr_idle_notify_activity(server.idle, wlr_seat); 329 wlr_idle_notify_activity(server.idle, wlr_seat);
329 struct wlr_event_keyboard_key *event = data;
330 bool input_inhibited = seat->exclusive_client != NULL; 330 bool input_inhibited = seat->exclusive_client != NULL;
331 331
332 // Identify new keycode, raw keysym(s), and translated keysym(s) 332 // Identify new keycode, raw keysym(s), and translated keysym(s)
@@ -360,21 +360,20 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
360 } 360 }
361 361
362 bool handled = false; 362 bool handled = false;
363
364 // Identify active release binding 363 // Identify active release binding
365 struct sway_binding *binding_released = NULL; 364 struct sway_binding *binding_released = NULL;
366 get_active_binding(&keyboard->state_keycodes, 365 get_active_binding(&keyboard->state_keycodes,
367 config->current_mode->keycode_bindings, &binding_released, 366 config->current_mode->keycode_bindings, &binding_released,
368 code_modifiers, true, input_inhibited, device_identifier, 367 code_modifiers, true, input_inhibited, device_identifier,
369 keyboard->effective_layout); 368 exact_identifier, keyboard->effective_layout);
370 get_active_binding(&keyboard->state_keysyms_raw, 369 get_active_binding(&keyboard->state_keysyms_raw,
371 config->current_mode->keysym_bindings, &binding_released, 370 config->current_mode->keysym_bindings, &binding_released,
372 raw_modifiers, true, input_inhibited, device_identifier, 371 raw_modifiers, true, input_inhibited, device_identifier,
373 keyboard->effective_layout); 372 exact_identifier, keyboard->effective_layout);
374 get_active_binding(&keyboard->state_keysyms_translated, 373 get_active_binding(&keyboard->state_keysyms_translated,
375 config->current_mode->keysym_bindings, &binding_released, 374 config->current_mode->keysym_bindings, &binding_released,
376 translated_modifiers, true, input_inhibited, device_identifier, 375 translated_modifiers, true, input_inhibited, device_identifier,
377 keyboard->effective_layout); 376 exact_identifier, keyboard->effective_layout);
378 377
379 // Execute stored release binding once no longer active 378 // Execute stored release binding once no longer active
380 if (keyboard->held_binding && binding_released != keyboard->held_binding && 379 if (keyboard->held_binding && binding_released != keyboard->held_binding &&
@@ -395,15 +394,16 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
395 get_active_binding(&keyboard->state_keycodes, 394 get_active_binding(&keyboard->state_keycodes,
396 config->current_mode->keycode_bindings, &binding, 395 config->current_mode->keycode_bindings, &binding,
397 code_modifiers, false, input_inhibited, device_identifier, 396 code_modifiers, false, input_inhibited, device_identifier,
398 keyboard->effective_layout); 397 exact_identifier, keyboard->effective_layout);
399 get_active_binding(&keyboard->state_keysyms_raw, 398 get_active_binding(&keyboard->state_keysyms_raw,
400 config->current_mode->keysym_bindings, &binding, 399 config->current_mode->keysym_bindings, &binding,
401 raw_modifiers, false, input_inhibited, device_identifier, 400 raw_modifiers, false, input_inhibited, device_identifier,
402 keyboard->effective_layout); 401 exact_identifier, keyboard->effective_layout);
403 get_active_binding(&keyboard->state_keysyms_translated, 402 get_active_binding(&keyboard->state_keysyms_translated,
404 config->current_mode->keysym_bindings, &binding, 403 config->current_mode->keysym_bindings, &binding,
405 translated_modifiers, false, input_inhibited, 404 translated_modifiers, false, input_inhibited,
406 device_identifier, keyboard->effective_layout); 405 device_identifier, exact_identifier,
406 keyboard->effective_layout);
407 } 407 }
408 408
409 // Set up (or clear) keyboard repeat for a pressed binding. Since the 409 // Set up (or clear) keyboard repeat for a pressed binding. Since the
@@ -423,6 +423,12 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
423 handled = true; 423 handled = true;
424 } 424 }
425 425
426 if (!handled && wlr_device->keyboard->group) {
427 // Only handle device specific bindings for keyboards in a group
428 free(device_identifier);
429 return;
430 }
431
426 // Compositor bindings 432 // Compositor bindings
427 if (!handled && event->state == WLR_KEY_PRESSED) { 433 if (!handled && event->state == WLR_KEY_PRESSED) {
428 handled = keyboard_execute_compositor_binding( 434 handled = keyboard_execute_compositor_binding(
@@ -450,6 +456,19 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
450 free(device_identifier); 456 free(device_identifier);
451} 457}
452 458
459static void handle_keyboard_key(struct wl_listener *listener, void *data) {
460 struct sway_keyboard *keyboard =
461 wl_container_of(listener, keyboard, keyboard_key);
462 handle_key_event(keyboard, data);
463}
464
465static void handle_keyboard_group_key(struct wl_listener *listener,
466 void *data) {
467 struct sway_keyboard_group *sway_group =
468 wl_container_of(listener, sway_group, keyboard_key);
469 handle_key_event(sway_group->seat_device->keyboard, data);
470}
471
453static int handle_keyboard_repeat(void *data) { 472static int handle_keyboard_repeat(void *data) {
454 struct sway_keyboard *keyboard = (struct sway_keyboard *)data; 473 struct sway_keyboard *keyboard = (struct sway_keyboard *)data;
455 struct wlr_keyboard *wlr_device = 474 struct wlr_keyboard *wlr_device =
@@ -491,25 +510,40 @@ static void determine_bar_visibility(uint32_t modifiers) {
491 } 510 }
492} 511}
493 512
494static void handle_keyboard_modifiers(struct wl_listener *listener, 513static void handle_modifier_event(struct sway_keyboard *keyboard) {
495 void *data) {
496 struct sway_keyboard *keyboard =
497 wl_container_of(listener, keyboard, keyboard_modifiers);
498 struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat;
499 struct wlr_input_device *wlr_device = 514 struct wlr_input_device *wlr_device =
500 keyboard->seat_device->input_device->wlr_device; 515 keyboard->seat_device->input_device->wlr_device;
501 wlr_seat_set_keyboard(wlr_seat, wlr_device); 516 if (!wlr_device->keyboard->group) {
502 wlr_seat_keyboard_notify_modifiers(wlr_seat, &wlr_device->keyboard->modifiers); 517 struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat;
518 wlr_seat_set_keyboard(wlr_seat, wlr_device);
519 wlr_seat_keyboard_notify_modifiers(wlr_seat,
520 &wlr_device->keyboard->modifiers);
503 521
504 uint32_t modifiers = wlr_keyboard_get_modifiers(wlr_device->keyboard); 522 uint32_t modifiers = wlr_keyboard_get_modifiers(wlr_device->keyboard);
505 determine_bar_visibility(modifiers); 523 determine_bar_visibility(modifiers);
524 }
506 525
507 if (wlr_device->keyboard->modifiers.group != keyboard->effective_layout) { 526 if (wlr_device->keyboard->modifiers.group != keyboard->effective_layout &&
527 !wlr_keyboard_group_from_wlr_keyboard(wlr_device->keyboard)) {
508 keyboard->effective_layout = wlr_device->keyboard->modifiers.group; 528 keyboard->effective_layout = wlr_device->keyboard->modifiers.group;
509 ipc_event_input("xkb_layout", keyboard->seat_device->input_device); 529 ipc_event_input("xkb_layout", keyboard->seat_device->input_device);
510 } 530 }
511} 531}
512 532
533static void handle_keyboard_modifiers(struct wl_listener *listener,
534 void *data) {
535 struct sway_keyboard *keyboard =
536 wl_container_of(listener, keyboard, keyboard_modifiers);
537 handle_modifier_event(keyboard);
538}
539
540static void handle_keyboard_group_modifiers(struct wl_listener *listener,
541 void *data) {
542 struct sway_keyboard_group *group =
543 wl_container_of(listener, group, keyboard_modifiers);
544 handle_modifier_event(group->seat_device->keyboard);
545}
546
513struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, 547struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
514 struct sway_seat_device *device) { 548 struct sway_seat_device *device) {
515 struct sway_keyboard *keyboard = 549 struct sway_keyboard *keyboard =
@@ -616,6 +650,163 @@ cleanup:
616 return keymap; 650 return keymap;
617} 651}
618 652
653static bool keymaps_match(struct xkb_keymap *km1, struct xkb_keymap *km2) {
654 char *km1_str = xkb_keymap_get_as_string(km1, XKB_KEYMAP_FORMAT_TEXT_V1);
655 char *km2_str = xkb_keymap_get_as_string(km2, XKB_KEYMAP_FORMAT_TEXT_V1);
656 bool result = strcmp(km1_str, km2_str) == 0;
657 free(km1_str);
658 free(km2_str);
659 return result;
660}
661
662static void sway_keyboard_group_remove(struct sway_keyboard *keyboard) {
663 struct sway_input_device *device = keyboard->seat_device->input_device;
664 struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard;
665 struct wlr_keyboard_group *wlr_group = wlr_keyboard->group;
666
667 sway_log(SWAY_DEBUG, "Removing keyboard %s from group %p",
668 device->identifier, wlr_group);
669
670 wlr_keyboard_group_remove_keyboard(wlr_keyboard->group, wlr_keyboard);
671
672 if (wl_list_empty(&wlr_group->devices)) {
673 sway_log(SWAY_DEBUG, "Destroying empty keyboard group %p",
674 wlr_group);
675 struct sway_keyboard_group *sway_group = wlr_group->data;
676 wlr_group->data = NULL;
677 wl_list_remove(&sway_group->link);
678 wl_list_remove(&sway_group->keyboard_key.link);
679 wl_list_remove(&sway_group->keyboard_modifiers.link);
680 free(sway_group->seat_device->keyboard);
681 free(sway_group->seat_device->input_device);
682 free(sway_group->seat_device);
683 free(sway_group);
684 wlr_keyboard_group_destroy(wlr_group);
685 }
686}
687
688static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) {
689 struct sway_input_device *device = keyboard->seat_device->input_device;
690 struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard;
691 if (!wlr_keyboard->group) {
692 return;
693 }
694
695 struct sway_seat *seat = keyboard->seat_device->sway_seat;
696 struct seat_config *sc = seat_get_config(seat);
697 if (!sc) {
698 sc = seat_get_config_by_name("*");
699 }
700
701 switch (sc ? sc->keyboard_grouping : KEYBOARD_GROUP_DEFAULT) {
702 case KEYBOARD_GROUP_NONE:
703 sway_keyboard_group_remove(keyboard);
704 break;
705 case KEYBOARD_GROUP_DEFAULT: /* fallthrough */
706 case KEYBOARD_GROUP_KEYMAP:;
707 struct wlr_keyboard_group *group = wlr_keyboard->group;
708 if (!keymaps_match(keyboard->keymap, group->keyboard.keymap)) {
709 sway_keyboard_group_remove(keyboard);
710 }
711 break;
712 }
713}
714
715static void sway_keyboard_group_add(struct sway_keyboard *keyboard) {
716 struct sway_input_device *device = keyboard->seat_device->input_device;
717 struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard;
718 struct sway_seat *seat = keyboard->seat_device->sway_seat;
719 struct seat_config *sc = seat_get_config(seat);
720 if (!sc) {
721 sc = seat_get_config_by_name("*");
722 }
723
724 if (sc && sc->keyboard_grouping == KEYBOARD_GROUP_NONE) {
725 // Keyboard grouping is disabled for the seat
726 return;
727 }
728
729 struct sway_keyboard_group *group;
730 wl_list_for_each(group, &seat->keyboard_groups, link) {
731 switch (sc ? sc->keyboard_grouping : KEYBOARD_GROUP_DEFAULT) {
732 case KEYBOARD_GROUP_NONE:
733 // Nothing to do. This shouldn't even be reached
734 return;
735 case KEYBOARD_GROUP_DEFAULT: /* fallthrough */
736 case KEYBOARD_GROUP_KEYMAP:;
737 struct wlr_keyboard_group *wlr_group = group->wlr_group;
738 if (keymaps_match(keyboard->keymap, wlr_group->keyboard.keymap)) {
739 sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p",
740 device->identifier, wlr_group);
741 wlr_keyboard_group_add_keyboard(wlr_group, wlr_keyboard);
742 return;
743 }
744 break;
745 }
746 }
747
748 struct sway_keyboard_group *sway_group =
749 calloc(1, sizeof(struct sway_keyboard_group));
750 if (!sway_group) {
751 sway_log(SWAY_ERROR, "Failed to allocate sway_keyboard_group");
752 return;
753 }
754
755 sway_group->wlr_group = wlr_keyboard_group_create();
756 if (!sway_group->wlr_group) {
757 sway_log(SWAY_ERROR, "Failed to create keyboard group");
758 goto cleanup;
759 }
760 sway_group->wlr_group->data = sway_group;
761 wlr_keyboard_set_keymap(&sway_group->wlr_group->keyboard, keyboard->keymap);
762 sway_log(SWAY_DEBUG, "Created keyboard group %p", sway_group->wlr_group);
763
764 sway_group->seat_device = calloc(1, sizeof(struct sway_seat_device));
765 if (!sway_group->seat_device) {
766 sway_log(SWAY_ERROR, "Failed to allocate sway_seat_device for group");
767 goto cleanup;
768 }
769 sway_group->seat_device->sway_seat = seat;
770
771 sway_group->seat_device->input_device =
772 calloc(1, sizeof(struct sway_input_device));
773 if (!sway_group->seat_device->input_device) {
774 sway_log(SWAY_ERROR, "Failed to allocate sway_input_device for group");
775 goto cleanup;
776 }
777 sway_group->seat_device->input_device->wlr_device =
778 sway_group->wlr_group->input_device;
779
780 if (!sway_keyboard_create(seat, sway_group->seat_device)) {
781 sway_log(SWAY_ERROR, "Failed to allocate sway_keyboard for group");
782 goto cleanup;
783 }
784
785 sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p",
786 device->identifier, sway_group->wlr_group);
787 wlr_keyboard_group_add_keyboard(sway_group->wlr_group, wlr_keyboard);
788
789 wl_list_insert(&seat->keyboard_groups, &sway_group->link);
790
791 wl_signal_add(&sway_group->wlr_group->keyboard.events.key,
792 &sway_group->keyboard_key);
793 sway_group->keyboard_key.notify = handle_keyboard_group_key;
794
795 wl_signal_add(&sway_group->wlr_group->keyboard.events.modifiers,
796 &sway_group->keyboard_modifiers);
797 sway_group->keyboard_modifiers.notify = handle_keyboard_group_modifiers;
798 return;
799
800cleanup:
801 if (sway_group && sway_group->wlr_group) {
802 wlr_keyboard_group_destroy(sway_group->wlr_group);
803 }
804 free(sway_group->seat_device->keyboard);
805 free(sway_group->seat_device->input_device);
806 free(sway_group->seat_device);
807 free(sway_group);
808}
809
619void sway_keyboard_configure(struct sway_keyboard *keyboard) { 810void sway_keyboard_configure(struct sway_keyboard *keyboard) {
620 struct input_config *input_config = 811 struct input_config *input_config =
621 input_device_get_config(keyboard->seat_device->input_device); 812 input_device_get_config(keyboard->seat_device->input_device);
@@ -633,26 +824,23 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
633 } 824 }
634 } 825 }
635 826
636 bool keymap_changed = false; 827 bool keymap_changed =
828 keyboard->keymap ? !keymaps_match(keyboard->keymap, keymap) : true;
637 bool effective_layout_changed = keyboard->effective_layout != 0; 829 bool effective_layout_changed = keyboard->effective_layout != 0;
638 if (keyboard->keymap) {
639 char *old_keymap_string = xkb_keymap_get_as_string(keyboard->keymap,
640 XKB_KEYMAP_FORMAT_TEXT_V1);
641 char *new_keymap_string = xkb_keymap_get_as_string(keymap,
642 XKB_KEYMAP_FORMAT_TEXT_V1);
643 keymap_changed = strcmp(old_keymap_string, new_keymap_string);
644 free(old_keymap_string);
645 free(new_keymap_string);
646 } else {
647 keymap_changed = true;
648 }
649 830
650 if (keymap_changed || config->reloading) { 831 if (keymap_changed || config->reloading) {
651 xkb_keymap_unref(keyboard->keymap); 832 xkb_keymap_unref(keyboard->keymap);
652 keyboard->keymap = keymap; 833 keyboard->keymap = keymap;
653 keyboard->effective_layout = 0; 834 keyboard->effective_layout = 0;
835
836 sway_keyboard_group_remove_invalid(keyboard);
837
654 wlr_keyboard_set_keymap(wlr_device->keyboard, keyboard->keymap); 838 wlr_keyboard_set_keymap(wlr_device->keyboard, keyboard->keymap);
655 839
840 if (!wlr_device->keyboard->group) {
841 sway_keyboard_group_add(keyboard);
842 }
843
656 xkb_mod_mask_t locked_mods = 0; 844 xkb_mod_mask_t locked_mods = 0;
657 if (input_config && input_config->xkb_numlock > 0) { 845 if (input_config && input_config->xkb_numlock > 0) {
658 xkb_mod_index_t mod_index = xkb_map_mod_get_index(keymap, 846 xkb_mod_index_t mod_index = xkb_map_mod_get_index(keymap,
@@ -679,10 +867,19 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
679 leds |= (1 << i); 867 leds |= (1 << i);
680 } 868 }
681 } 869 }
682 wlr_keyboard_led_update(wlr_device->keyboard, leds); 870 if (wlr_device->keyboard->group) {
871 wlr_keyboard_led_update(
872 &wlr_device->keyboard->group->keyboard, leds);
873 } else {
874 wlr_keyboard_led_update(wlr_device->keyboard, leds);
875 }
683 } 876 }
684 } else { 877 } else {
685 xkb_keymap_unref(keymap); 878 xkb_keymap_unref(keymap);
879 sway_keyboard_group_remove_invalid(keyboard);
880 if (!wlr_device->keyboard->group) {
881 sway_keyboard_group_add(keyboard);
882 }
686 } 883 }
687 884
688 int repeat_rate = 25; 885 int repeat_rate = 25;
@@ -721,6 +918,7 @@ void sway_keyboard_destroy(struct sway_keyboard *keyboard) {
721 if (!keyboard) { 918 if (!keyboard) {
722 return; 919 return;
723 } 920 }
921 sway_keyboard_group_remove(keyboard);
724 if (keyboard->keymap) { 922 if (keyboard->keymap) {
725 xkb_keymap_unref(keyboard->keymap); 923 xkb_keymap_unref(keyboard->keymap);
726 } 924 }
diff --git a/sway/input/seat.c b/sway/input/seat.c
index f486d5e7..fb3e68ee 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -102,6 +102,14 @@ static struct sway_keyboard *sway_keyboard_for_wlr_keyboard(
102 return seat_device->keyboard; 102 return seat_device->keyboard;
103 } 103 }
104 } 104 }
105 struct sway_keyboard_group *group;
106 wl_list_for_each(group, &seat->keyboard_groups, link) {
107 struct sway_input_device *input_device =
108 group->seat_device->input_device;
109 if (input_device->wlr_device->keyboard == wlr_keyboard) {
110 return group->seat_device->keyboard;
111 }
112 }
105 return NULL; 113 return NULL;
106} 114}
107 115
@@ -519,6 +527,7 @@ struct sway_seat *seat_create(const char *seat_name) {
519 handle_request_set_primary_selection; 527 handle_request_set_primary_selection;
520 528
521 wl_list_init(&seat->devices); 529 wl_list_init(&seat->devices);
530 wl_list_init(&seat->keyboard_groups);
522 531
523 wl_list_insert(&server.input->seats, &seat->link); 532 wl_list_insert(&server.input->seats, &seat->link);
524 533