aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/keyboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input/keyboard.c')
-rw-r--r--sway/input/keyboard.c250
1 files changed, 136 insertions, 114 deletions
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c
index ce259eb2..b97f0152 100644
--- a/sway/input/keyboard.c
+++ b/sway/input/keyboard.c
@@ -1,15 +1,13 @@
1#include <assert.h> 1#include <assert.h>
2#include <limits.h> 2#include <limits.h>
3#include <strings.h> 3#include <strings.h>
4#include <wlr/config.h>
4#include <wlr/backend/multi.h> 5#include <wlr/backend/multi.h>
5#include <wlr/backend/session.h>
6#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.h> 7#include <wlr/types/wlr_keyboard.h>
9#include <wlr/types/wlr_keyboard_group.h> 8#include <wlr/types/wlr_keyboard_group.h>
10#include <xkbcommon/xkbcommon-names.h> 9#include <xkbcommon/xkbcommon-names.h>
11#include "sway/commands.h" 10#include "sway/commands.h"
12#include "sway/desktop/transaction.h"
13#include "sway/input/input-manager.h" 11#include "sway/input/input-manager.h"
14#include "sway/input/keyboard.h" 12#include "sway/input/keyboard.h"
15#include "sway/input/seat.h" 13#include "sway/input/seat.h"
@@ -17,6 +15,10 @@
17#include "sway/ipc-server.h" 15#include "sway/ipc-server.h"
18#include "log.h" 16#include "log.h"
19 17
18#if WLR_HAS_SESSION
19#include <wlr/backend/session.h>
20#endif
21
20static struct modifier_key { 22static struct modifier_key {
21 char *name; 23 char *name;
22 uint32_t mod; 24 uint32_t mod;
@@ -265,14 +267,12 @@ static bool keyboard_execute_compositor_binding(struct sway_keyboard *keyboard,
265 xkb_keysym_t keysym = pressed_keysyms[i]; 267 xkb_keysym_t keysym = pressed_keysyms[i];
266 if (keysym >= XKB_KEY_XF86Switch_VT_1 && 268 if (keysym >= XKB_KEY_XF86Switch_VT_1 &&
267 keysym <= XKB_KEY_XF86Switch_VT_12) { 269 keysym <= XKB_KEY_XF86Switch_VT_12) {
268 if (wlr_backend_is_multi(server.backend)) { 270#if WLR_HAS_SESSION
269 struct wlr_session *session = 271 if (server.session) {
270 wlr_backend_get_session(server.backend); 272 unsigned vt = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
271 if (session) { 273 wlr_session_change_vt(server.session, vt);
272 unsigned vt = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
273 wlr_session_change_vt(session, vt);
274 }
275 } 274 }
275#endif
276 return true; 276 return true;
277 } 277 }
278 } 278 }
@@ -292,14 +292,12 @@ static bool keyboard_execute_compositor_binding(struct sway_keyboard *keyboard,
292static size_t keyboard_keysyms_translated(struct sway_keyboard *keyboard, 292static size_t keyboard_keysyms_translated(struct sway_keyboard *keyboard,
293 xkb_keycode_t keycode, const xkb_keysym_t **keysyms, 293 xkb_keycode_t keycode, const xkb_keysym_t **keysyms,
294 uint32_t *modifiers) { 294 uint32_t *modifiers) {
295 struct wlr_input_device *device = 295 *modifiers = wlr_keyboard_get_modifiers(keyboard->wlr);
296 keyboard->seat_device->input_device->wlr_device;
297 *modifiers = wlr_keyboard_get_modifiers(device->keyboard);
298 xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods2( 296 xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods2(
299 device->keyboard->xkb_state, keycode, XKB_CONSUMED_MODE_XKB); 297 keyboard->wlr->xkb_state, keycode, XKB_CONSUMED_MODE_XKB);
300 *modifiers = *modifiers & ~consumed; 298 *modifiers = *modifiers & ~consumed;
301 299
302 return xkb_state_key_get_syms(device->keyboard->xkb_state, 300 return xkb_state_key_get_syms(keyboard->wlr->xkb_state,
303 keycode, keysyms); 301 keycode, keysyms);
304} 302}
305 303
@@ -315,13 +313,11 @@ static size_t keyboard_keysyms_translated(struct sway_keyboard *keyboard,
315static size_t keyboard_keysyms_raw(struct sway_keyboard *keyboard, 313static size_t keyboard_keysyms_raw(struct sway_keyboard *keyboard,
316 xkb_keycode_t keycode, const xkb_keysym_t **keysyms, 314 xkb_keycode_t keycode, const xkb_keysym_t **keysyms,
317 uint32_t *modifiers) { 315 uint32_t *modifiers) {
318 struct wlr_input_device *device = 316 *modifiers = wlr_keyboard_get_modifiers(keyboard->wlr);
319 keyboard->seat_device->input_device->wlr_device;
320 *modifiers = wlr_keyboard_get_modifiers(device->keyboard);
321 317
322 xkb_layout_index_t layout_index = xkb_state_key_get_layout( 318 xkb_layout_index_t layout_index = xkb_state_key_get_layout(
323 device->keyboard->xkb_state, keycode); 319 keyboard->wlr->xkb_state, keycode);
324 return xkb_keymap_key_get_syms_by_level(device->keyboard->keymap, 320 return xkb_keymap_key_get_syms_by_level(keyboard->wlr->keymap,
325 keycode, layout_index, 0, keysyms); 321 keycode, layout_index, 0, keysyms);
326} 322}
327 323
@@ -361,8 +357,7 @@ static void update_keyboard_state(struct sway_keyboard *keyboard,
361 keyinfo->keycode, &keyinfo->translated_keysyms, 357 keyinfo->keycode, &keyinfo->translated_keysyms,
362 &keyinfo->translated_modifiers); 358 &keyinfo->translated_modifiers);
363 359
364 keyinfo->code_modifiers = wlr_keyboard_get_modifiers( 360 keyinfo->code_modifiers = wlr_keyboard_get_modifiers(keyboard->wlr);
365 keyboard->seat_device->input_device->wlr_device->keyboard);
366 361
367 // Update shortcut model keyinfo 362 // Update shortcut model keyinfo
368 update_shortcut_state(&keyboard->state_keycodes, raw_keycode, keystate, 363 update_shortcut_state(&keyboard->state_keycodes, raw_keycode, keystate,
@@ -379,16 +374,38 @@ static void update_keyboard_state(struct sway_keyboard *keyboard,
379 } 374 }
380} 375}
381 376
377/**
378 * Get keyboard grab of the seat from sway_keyboard if we should forward events
379 * to it.
380 *
381 * Returns NULL if the keyboard is not grabbed by an input method,
382 * or if event is from virtual keyboard of the same client as grab.
383 * TODO: see swaywm/wlroots#2322
384 */
385static struct wlr_input_method_keyboard_grab_v2 *keyboard_get_im_grab(
386 struct sway_keyboard *keyboard) {
387 struct wlr_input_method_v2 *input_method = keyboard->seat_device->
388 sway_seat->im_relay.input_method;
389 struct wlr_virtual_keyboard_v1 *virtual_keyboard =
390 wlr_input_device_get_virtual_keyboard(keyboard->seat_device->input_device->wlr_device);
391 if (!input_method || !input_method->keyboard_grab || (virtual_keyboard &&
392 wl_resource_get_client(virtual_keyboard->resource) ==
393 wl_resource_get_client(input_method->keyboard_grab->resource))) {
394 return NULL;
395 }
396 return input_method->keyboard_grab;
397}
398
382static void handle_key_event(struct sway_keyboard *keyboard, 399static void handle_key_event(struct sway_keyboard *keyboard,
383 struct wlr_event_keyboard_key *event) { 400 struct wlr_keyboard_key_event *event) {
384 struct sway_seat *seat = keyboard->seat_device->sway_seat; 401 struct sway_seat *seat = keyboard->seat_device->sway_seat;
385 struct wlr_seat *wlr_seat = seat->wlr_seat; 402 struct wlr_seat *wlr_seat = seat->wlr_seat;
386 struct wlr_input_device *wlr_device = 403 struct wlr_input_device *wlr_device =
387 keyboard->seat_device->input_device->wlr_device; 404 keyboard->seat_device->input_device->wlr_device;
388 char *device_identifier = input_device_get_identifier(wlr_device); 405 char *device_identifier = input_device_get_identifier(wlr_device);
389 bool exact_identifier = wlr_device->keyboard->group != NULL; 406 bool exact_identifier = keyboard->wlr->group != NULL;
390 seat_idle_notify_activity(seat, IDLE_SOURCE_KEYBOARD); 407 seat_idle_notify_activity(seat, IDLE_SOURCE_KEYBOARD);
391 bool input_inhibited = seat->exclusive_client != NULL; 408 bool locked = server.session_lock.lock;
392 struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor = 409 struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor =
393 keyboard_shortcuts_inhibitor_get_for_focused_surface(seat); 410 keyboard_shortcuts_inhibitor_get_for_focused_surface(seat);
394 bool shortcuts_inhibited = sway_inhibitor && sway_inhibitor->inhibitor->active; 411 bool shortcuts_inhibited = sway_inhibitor && sway_inhibitor->inhibitor->active;
@@ -406,17 +423,17 @@ static void handle_key_event(struct sway_keyboard *keyboard,
406 struct sway_binding *binding_released = NULL; 423 struct sway_binding *binding_released = NULL;
407 get_active_binding(&keyboard->state_keycodes, 424 get_active_binding(&keyboard->state_keycodes,
408 config->current_mode->keycode_bindings, &binding_released, 425 config->current_mode->keycode_bindings, &binding_released,
409 keyinfo.code_modifiers, true, input_inhibited, 426 keyinfo.code_modifiers, true, locked,
410 shortcuts_inhibited, device_identifier, 427 shortcuts_inhibited, device_identifier,
411 exact_identifier, keyboard->effective_layout); 428 exact_identifier, keyboard->effective_layout);
412 get_active_binding(&keyboard->state_keysyms_raw, 429 get_active_binding(&keyboard->state_keysyms_raw,
413 config->current_mode->keysym_bindings, &binding_released, 430 config->current_mode->keysym_bindings, &binding_released,
414 keyinfo.raw_modifiers, true, input_inhibited, 431 keyinfo.raw_modifiers, true, locked,
415 shortcuts_inhibited, device_identifier, 432 shortcuts_inhibited, device_identifier,
416 exact_identifier, keyboard->effective_layout); 433 exact_identifier, keyboard->effective_layout);
417 get_active_binding(&keyboard->state_keysyms_translated, 434 get_active_binding(&keyboard->state_keysyms_translated,
418 config->current_mode->keysym_bindings, &binding_released, 435 config->current_mode->keysym_bindings, &binding_released,
419 keyinfo.translated_modifiers, true, input_inhibited, 436 keyinfo.translated_modifiers, true, locked,
420 shortcuts_inhibited, device_identifier, 437 shortcuts_inhibited, device_identifier,
421 exact_identifier, keyboard->effective_layout); 438 exact_identifier, keyboard->effective_layout);
422 439
@@ -438,17 +455,17 @@ static void handle_key_event(struct sway_keyboard *keyboard,
438 if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { 455 if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
439 get_active_binding(&keyboard->state_keycodes, 456 get_active_binding(&keyboard->state_keycodes,
440 config->current_mode->keycode_bindings, &binding, 457 config->current_mode->keycode_bindings, &binding,
441 keyinfo.code_modifiers, false, input_inhibited, 458 keyinfo.code_modifiers, false, locked,
442 shortcuts_inhibited, device_identifier, 459 shortcuts_inhibited, device_identifier,
443 exact_identifier, keyboard->effective_layout); 460 exact_identifier, keyboard->effective_layout);
444 get_active_binding(&keyboard->state_keysyms_raw, 461 get_active_binding(&keyboard->state_keysyms_raw,
445 config->current_mode->keysym_bindings, &binding, 462 config->current_mode->keysym_bindings, &binding,
446 keyinfo.raw_modifiers, false, input_inhibited, 463 keyinfo.raw_modifiers, false, locked,
447 shortcuts_inhibited, device_identifier, 464 shortcuts_inhibited, device_identifier,
448 exact_identifier, keyboard->effective_layout); 465 exact_identifier, keyboard->effective_layout);
449 get_active_binding(&keyboard->state_keysyms_translated, 466 get_active_binding(&keyboard->state_keysyms_translated,
450 config->current_mode->keysym_bindings, &binding, 467 config->current_mode->keysym_bindings, &binding,
451 keyinfo.translated_modifiers, false, input_inhibited, 468 keyinfo.translated_modifiers, false, locked,
452 shortcuts_inhibited, device_identifier, 469 shortcuts_inhibited, device_identifier,
453 exact_identifier, keyboard->effective_layout); 470 exact_identifier, keyboard->effective_layout);
454 } 471 }
@@ -456,10 +473,10 @@ static void handle_key_event(struct sway_keyboard *keyboard,
456 // Set up (or clear) keyboard repeat for a pressed binding. Since the 473 // Set up (or clear) keyboard repeat for a pressed binding. Since the
457 // binding may remove the keyboard, the timer needs to be updated first 474 // binding may remove the keyboard, the timer needs to be updated first
458 if (binding && !(binding->flags & BINDING_NOREPEAT) && 475 if (binding && !(binding->flags & BINDING_NOREPEAT) &&
459 wlr_device->keyboard->repeat_info.delay > 0) { 476 keyboard->wlr->repeat_info.delay > 0) {
460 keyboard->repeat_binding = binding; 477 keyboard->repeat_binding = binding;
461 if (wl_event_source_timer_update(keyboard->key_repeat_source, 478 if (wl_event_source_timer_update(keyboard->key_repeat_source,
462 wlr_device->keyboard->repeat_info.delay) < 0) { 479 keyboard->wlr->repeat_info.delay) < 0) {
463 sway_log(SWAY_DEBUG, "failed to set key repeat timer"); 480 sway_log(SWAY_DEBUG, "failed to set key repeat timer");
464 } 481 }
465 } else if (keyboard->repeat_binding) { 482 } else if (keyboard->repeat_binding) {
@@ -471,7 +488,7 @@ static void handle_key_event(struct sway_keyboard *keyboard,
471 handled = true; 488 handled = true;
472 } 489 }
473 490
474 if (!handled && wlr_device->keyboard->group) { 491 if (!handled && keyboard->wlr->group) {
475 // Only handle device specific bindings for keyboards in a group 492 // Only handle device specific bindings for keyboards in a group
476 free(device_identifier); 493 free(device_identifier);
477 return; 494 return;
@@ -489,18 +506,41 @@ static void handle_key_event(struct sway_keyboard *keyboard,
489 keyinfo.raw_keysyms_len); 506 keyinfo.raw_keysyms_len);
490 } 507 }
491 508
492 if (!handled || event->state == WL_KEYBOARD_KEY_STATE_RELEASED) { 509 if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
510 // If the pressed event was sent to a client, also send the released
511 // event. In particular, don't send the released event to the IM grab.
493 bool pressed_sent = update_shortcut_state( 512 bool pressed_sent = update_shortcut_state(
494 &keyboard->state_pressed_sent, event->keycode, event->state, 513 &keyboard->state_pressed_sent, event->keycode,
495 keyinfo.keycode, 0); 514 event->state, keyinfo.keycode, 0);
496 if (pressed_sent || event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { 515 if (pressed_sent) {
497 wlr_seat_set_keyboard(wlr_seat, wlr_device); 516 wlr_seat_set_keyboard(wlr_seat, keyboard->wlr);
498 wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec, 517 wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec,
499 event->keycode, event->state); 518 event->keycode, event->state);
519 handled = true;
520 }
521 }
522
523 if (!handled) {
524 struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(keyboard);
525
526 if (kb_grab) {
527 wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab, keyboard->wlr);
528 wlr_input_method_keyboard_grab_v2_send_key(kb_grab,
529 event->time_msec, event->keycode, event->state);
530 handled = true;
500 } 531 }
501 } 532 }
502 533
503 transaction_commit_dirty(); 534 if (!handled && event->state != WL_KEYBOARD_KEY_STATE_RELEASED) {
535 // If a released event failed pressed sent test, and not in sent to
536 // keyboard grab, it is still not handled. Don't handle released here.
537 update_shortcut_state(
538 &keyboard->state_pressed_sent, event->keycode, event->state,
539 keyinfo.keycode, 0);
540 wlr_seat_set_keyboard(wlr_seat, keyboard->wlr);
541 wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec,
542 event->keycode, event->state);
543 }
504 544
505 free(device_identifier); 545 free(device_identifier);
506} 546}
@@ -573,21 +613,18 @@ static void handle_keyboard_group_leave(struct wl_listener *listener,
573} 613}
574 614
575static int handle_keyboard_repeat(void *data) { 615static int handle_keyboard_repeat(void *data) {
576 struct sway_keyboard *keyboard = (struct sway_keyboard *)data; 616 struct sway_keyboard *keyboard = data;
577 struct wlr_keyboard *wlr_device =
578 keyboard->seat_device->input_device->wlr_device->keyboard;
579 if (keyboard->repeat_binding) { 617 if (keyboard->repeat_binding) {
580 if (wlr_device->repeat_info.rate > 0) { 618 if (keyboard->wlr->repeat_info.rate > 0) {
581 // We queue the next event first, as the command might cancel it 619 // We queue the next event first, as the command might cancel it
582 if (wl_event_source_timer_update(keyboard->key_repeat_source, 620 if (wl_event_source_timer_update(keyboard->key_repeat_source,
583 1000 / wlr_device->repeat_info.rate) < 0) { 621 1000 / keyboard->wlr->repeat_info.rate) < 0) {
584 sway_log(SWAY_DEBUG, "failed to update key repeat timer"); 622 sway_log(SWAY_DEBUG, "failed to update key repeat timer");
585 } 623 }
586 } 624 }
587 625
588 seat_execute_command(keyboard->seat_device->sway_seat, 626 seat_execute_command(keyboard->seat_device->sway_seat,
589 keyboard->repeat_binding); 627 keyboard->repeat_binding);
590 transaction_commit_dirty();
591 } 628 }
592 return 0; 629 return 0;
593} 630}
@@ -614,22 +651,28 @@ static void determine_bar_visibility(uint32_t modifiers) {
614} 651}
615 652
616static void handle_modifier_event(struct sway_keyboard *keyboard) { 653static void handle_modifier_event(struct sway_keyboard *keyboard) {
617 struct wlr_input_device *wlr_device = 654 if (!keyboard->wlr->group) {
618 keyboard->seat_device->input_device->wlr_device; 655 struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(keyboard);
619 if (!wlr_device->keyboard->group) {
620 struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat;
621 wlr_seat_set_keyboard(wlr_seat, wlr_device);
622 wlr_seat_keyboard_notify_modifiers(wlr_seat,
623 &wlr_device->keyboard->modifiers);
624 656
625 uint32_t modifiers = wlr_keyboard_get_modifiers(wlr_device->keyboard); 657 if (kb_grab) {
658 wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab, keyboard->wlr);
659 wlr_input_method_keyboard_grab_v2_send_modifiers(kb_grab,
660 &keyboard->wlr->modifiers);
661 } else {
662 struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat;
663 wlr_seat_set_keyboard(wlr_seat, keyboard->wlr);
664 wlr_seat_keyboard_notify_modifiers(wlr_seat,
665 &keyboard->wlr->modifiers);
666 }
667
668 uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->wlr);
626 determine_bar_visibility(modifiers); 669 determine_bar_visibility(modifiers);
627 } 670 }
628 671
629 if (wlr_device->keyboard->modifiers.group != keyboard->effective_layout) { 672 if (keyboard->wlr->modifiers.group != keyboard->effective_layout) {
630 keyboard->effective_layout = wlr_device->keyboard->modifiers.group; 673 keyboard->effective_layout = keyboard->wlr->modifiers.group;
631 674
632 if (!wlr_keyboard_group_from_wlr_keyboard(wlr_device->keyboard)) { 675 if (!wlr_keyboard_group_from_wlr_keyboard(keyboard->wlr)) {
633 ipc_event_input("xkb_layout", keyboard->seat_device->input_device); 676 ipc_event_input("xkb_layout", keyboard->seat_device->input_device);
634 } 677 }
635 } 678 }
@@ -658,6 +701,7 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
658 } 701 }
659 702
660 keyboard->seat_device = device; 703 keyboard->seat_device = device;
704 keyboard->wlr = wlr_keyboard_from_input_device(device->input_device->wlr_device);
661 device->keyboard = keyboard; 705 device->keyboard = keyboard;
662 706
663 wl_list_init(&keyboard->keyboard_key.link); 707 wl_list_init(&keyboard->keyboard_key.link);
@@ -671,23 +715,11 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
671 715
672static void handle_xkb_context_log(struct xkb_context *context, 716static void handle_xkb_context_log(struct xkb_context *context,
673 enum xkb_log_level level, const char *format, va_list args) { 717 enum xkb_log_level level, const char *format, va_list args) {
674 va_list args_copy; 718 char *error = vformat_str(format, args);
675 va_copy(args_copy, args);
676 size_t length = vsnprintf(NULL, 0, format, args_copy) + 1;
677 va_end(args_copy);
678
679 char *error = malloc(length);
680 if (!error) {
681 sway_log(SWAY_ERROR, "Failed to allocate libxkbcommon log message");
682 return;
683 }
684
685 va_copy(args_copy, args);
686 vsnprintf(error, length, format, args_copy);
687 va_end(args_copy);
688 719
689 if (error[length - 2] == '\n') { 720 size_t len = strlen(error);
690 error[length - 2] = '\0'; 721 if (error[len - 1] == '\n') {
722 error[len - 1] = '\0';
691 } 723 }
692 724
693 sway_log_importance_t importance = SWAY_DEBUG; 725 sway_log_importance_t importance = SWAY_DEBUG;
@@ -708,7 +740,7 @@ static void handle_xkb_context_log(struct xkb_context *context,
708 740
709struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic, 741struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic,
710 char **error) { 742 char **error) {
711 struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); 743 struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_SECURE_GETENV);
712 if (!sway_assert(context, "cannot create XKB context")) { 744 if (!sway_assert(context, "cannot create XKB context")) {
713 return NULL; 745 return NULL;
714 } 746 }
@@ -722,13 +754,8 @@ struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic,
722 if (!keymap_file) { 754 if (!keymap_file) {
723 sway_log_errno(SWAY_ERROR, "cannot read xkb file %s", ic->xkb_file); 755 sway_log_errno(SWAY_ERROR, "cannot read xkb file %s", ic->xkb_file);
724 if (error) { 756 if (error) {
725 size_t len = snprintf(NULL, 0, "cannot read xkb file %s: %s", 757 *error = format_str("cannot read xkb file %s: %s",
726 ic->xkb_file, strerror(errno)) + 1; 758 ic->xkb_file, strerror(errno));
727 *error = malloc(len);
728 if (*error) {
729 snprintf(*error, len, "cannot read xkb_file %s: %s",
730 ic->xkb_file, strerror(errno));
731 }
732 } 759 }
733 goto cleanup; 760 goto cleanup;
734 } 761 }
@@ -766,13 +793,12 @@ static void destroy_empty_wlr_keyboard_group(void *data) {
766 793
767static void sway_keyboard_group_remove(struct sway_keyboard *keyboard) { 794static void sway_keyboard_group_remove(struct sway_keyboard *keyboard) {
768 struct sway_input_device *device = keyboard->seat_device->input_device; 795 struct sway_input_device *device = keyboard->seat_device->input_device;
769 struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard; 796 struct wlr_keyboard_group *wlr_group = keyboard->wlr->group;
770 struct wlr_keyboard_group *wlr_group = wlr_keyboard->group;
771 797
772 sway_log(SWAY_DEBUG, "Removing keyboard %s from group %p", 798 sway_log(SWAY_DEBUG, "Removing keyboard %s from group %p",
773 device->identifier, wlr_group); 799 device->identifier, wlr_group);
774 800
775 wlr_keyboard_group_remove_keyboard(wlr_keyboard->group, wlr_keyboard); 801 wlr_keyboard_group_remove_keyboard(keyboard->wlr->group, keyboard->wlr);
776 802
777 if (wl_list_empty(&wlr_group->devices)) { 803 if (wl_list_empty(&wlr_group->devices)) {
778 sway_log(SWAY_DEBUG, "Destroying empty keyboard group %p", 804 sway_log(SWAY_DEBUG, "Destroying empty keyboard group %p",
@@ -797,9 +823,7 @@ static void sway_keyboard_group_remove(struct sway_keyboard *keyboard) {
797} 823}
798 824
799static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) { 825static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) {
800 struct sway_input_device *device = keyboard->seat_device->input_device; 826 if (!keyboard->wlr->group) {
801 struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard;
802 if (!wlr_keyboard->group) {
803 return; 827 return;
804 } 828 }
805 829
@@ -815,7 +839,7 @@ static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) {
815 break; 839 break;
816 case KEYBOARD_GROUP_DEFAULT: /* fallthrough */ 840 case KEYBOARD_GROUP_DEFAULT: /* fallthrough */
817 case KEYBOARD_GROUP_SMART:; 841 case KEYBOARD_GROUP_SMART:;
818 struct wlr_keyboard_group *group = wlr_keyboard->group; 842 struct wlr_keyboard_group *group = keyboard->wlr->group;
819 if (!wlr_keyboard_keymaps_match(keyboard->keymap, group->keyboard.keymap) || 843 if (!wlr_keyboard_keymaps_match(keyboard->keymap, group->keyboard.keymap) ||
820 !repeat_info_match(keyboard, &group->keyboard)) { 844 !repeat_info_match(keyboard, &group->keyboard)) {
821 sway_keyboard_group_remove(keyboard); 845 sway_keyboard_group_remove(keyboard);
@@ -826,7 +850,6 @@ static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) {
826 850
827static void sway_keyboard_group_add(struct sway_keyboard *keyboard) { 851static void sway_keyboard_group_add(struct sway_keyboard *keyboard) {
828 struct sway_input_device *device = keyboard->seat_device->input_device; 852 struct sway_input_device *device = keyboard->seat_device->input_device;
829 struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard;
830 struct sway_seat *seat = keyboard->seat_device->sway_seat; 853 struct sway_seat *seat = keyboard->seat_device->sway_seat;
831 struct seat_config *sc = seat_get_config(seat); 854 struct seat_config *sc = seat_get_config(seat);
832 855
@@ -858,7 +881,7 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) {
858 repeat_info_match(keyboard, &wlr_group->keyboard)) { 881 repeat_info_match(keyboard, &wlr_group->keyboard)) {
859 sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p", 882 sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p",
860 device->identifier, wlr_group); 883 device->identifier, wlr_group);
861 wlr_keyboard_group_add_keyboard(wlr_group, wlr_keyboard); 884 wlr_keyboard_group_add_keyboard(wlr_group, keyboard->wlr);
862 return; 885 return;
863 } 886 }
864 break; 887 break;
@@ -897,7 +920,7 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) {
897 goto cleanup; 920 goto cleanup;
898 } 921 }
899 sway_group->seat_device->input_device->wlr_device = 922 sway_group->seat_device->input_device->wlr_device =
900 sway_group->wlr_group->input_device; 923 &sway_group->wlr_group->keyboard.base;
901 924
902 if (!sway_keyboard_create(seat, sway_group->seat_device)) { 925 if (!sway_keyboard_create(seat, sway_group->seat_device)) {
903 sway_log(SWAY_ERROR, "Failed to allocate sway_keyboard for group"); 926 sway_log(SWAY_ERROR, "Failed to allocate sway_keyboard for group");
@@ -906,7 +929,7 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) {
906 929
907 sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p", 930 sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p",
908 device->identifier, sway_group->wlr_group); 931 device->identifier, sway_group->wlr_group);
909 wlr_keyboard_group_add_keyboard(sway_group->wlr_group, wlr_keyboard); 932 wlr_keyboard_group_add_keyboard(sway_group->wlr_group, keyboard->wlr);
910 933
911 wl_list_insert(&seat->keyboard_groups, &sway_group->link); 934 wl_list_insert(&seat->keyboard_groups, &sway_group->link);
912 935
@@ -938,10 +961,8 @@ cleanup:
938void sway_keyboard_configure(struct sway_keyboard *keyboard) { 961void sway_keyboard_configure(struct sway_keyboard *keyboard) {
939 struct input_config *input_config = 962 struct input_config *input_config =
940 input_device_get_config(keyboard->seat_device->input_device); 963 input_device_get_config(keyboard->seat_device->input_device);
941 struct wlr_input_device *wlr_device =
942 keyboard->seat_device->input_device->wlr_device;
943 964
944 if (!sway_assert(!wlr_keyboard_group_from_wlr_keyboard(wlr_device->keyboard), 965 if (!sway_assert(!wlr_keyboard_group_from_wlr_keyboard(keyboard->wlr),
945 "sway_keyboard_configure should not be called with a " 966 "sway_keyboard_configure should not be called with a "
946 "keyboard group's keyboard")) { 967 "keyboard group's keyboard")) {
947 return; 968 return;
@@ -983,11 +1004,11 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
983 1004
984 sway_keyboard_group_remove_invalid(keyboard); 1005 sway_keyboard_group_remove_invalid(keyboard);
985 1006
986 wlr_keyboard_set_keymap(wlr_device->keyboard, keyboard->keymap); 1007 wlr_keyboard_set_keymap(keyboard->wlr, keyboard->keymap);
987 wlr_keyboard_set_repeat_info(wlr_device->keyboard, 1008 wlr_keyboard_set_repeat_info(keyboard->wlr,
988 keyboard->repeat_rate, keyboard->repeat_delay); 1009 keyboard->repeat_rate, keyboard->repeat_delay);
989 1010
990 if (!wlr_device->keyboard->group) { 1011 if (!keyboard->wlr->group) {
991 sway_keyboard_group_add(keyboard); 1012 sway_keyboard_group_add(keyboard);
992 } 1013 }
993 1014
@@ -1007,40 +1028,42 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
1007 } 1028 }
1008 } 1029 }
1009 if (locked_mods) { 1030 if (locked_mods) {
1010 wlr_keyboard_notify_modifiers(wlr_device->keyboard, 0, 0, 1031 wlr_keyboard_notify_modifiers(keyboard->wlr, 0, 0,
1011 locked_mods, 0); 1032 locked_mods, 0);
1012 uint32_t leds = 0; 1033 uint32_t leds = 0;
1013 for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) { 1034 for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) {
1014 if (xkb_state_led_index_is_active( 1035 if (xkb_state_led_index_is_active(keyboard->wlr->xkb_state,
1015 wlr_device->keyboard->xkb_state, 1036 keyboard->wlr->led_indexes[i])) {
1016 wlr_device->keyboard->led_indexes[i])) {
1017 leds |= (1 << i); 1037 leds |= (1 << i);
1018 } 1038 }
1019 } 1039 }
1020 if (wlr_device->keyboard->group) { 1040 if (keyboard->wlr->group) {
1021 wlr_keyboard_led_update( 1041 wlr_keyboard_led_update(&keyboard->wlr->group->keyboard, leds);
1022 &wlr_device->keyboard->group->keyboard, leds);
1023 } else { 1042 } else {
1024 wlr_keyboard_led_update(wlr_device->keyboard, leds); 1043 wlr_keyboard_led_update(keyboard->wlr, leds);
1025 } 1044 }
1026 } 1045 }
1027 } else { 1046 } else {
1028 xkb_keymap_unref(keymap); 1047 xkb_keymap_unref(keymap);
1029 sway_keyboard_group_remove_invalid(keyboard); 1048 sway_keyboard_group_remove_invalid(keyboard);
1030 if (!wlr_device->keyboard->group) { 1049 if (!keyboard->wlr->group) {
1031 sway_keyboard_group_add(keyboard); 1050 sway_keyboard_group_add(keyboard);
1032 } 1051 }
1033 } 1052 }
1034 1053
1054 // If the seat has no active keyboard, set this one
1035 struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat; 1055 struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat;
1036 wlr_seat_set_keyboard(seat, wlr_device); 1056 struct wlr_keyboard *current_keyboard = seat->keyboard_state.keyboard;
1057 if (current_keyboard == NULL) {
1058 wlr_seat_set_keyboard(seat, keyboard->wlr);
1059 }
1037 1060
1038 wl_list_remove(&keyboard->keyboard_key.link); 1061 wl_list_remove(&keyboard->keyboard_key.link);
1039 wl_signal_add(&wlr_device->keyboard->events.key, &keyboard->keyboard_key); 1062 wl_signal_add(&keyboard->wlr->events.key, &keyboard->keyboard_key);
1040 keyboard->keyboard_key.notify = handle_keyboard_key; 1063 keyboard->keyboard_key.notify = handle_keyboard_key;
1041 1064
1042 wl_list_remove(&keyboard->keyboard_modifiers.link); 1065 wl_list_remove(&keyboard->keyboard_modifiers.link);
1043 wl_signal_add(&wlr_device->keyboard->events.modifiers, 1066 wl_signal_add(&keyboard->wlr->events.modifiers,
1044 &keyboard->keyboard_modifiers); 1067 &keyboard->keyboard_modifiers);
1045 keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers; 1068 keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers;
1046 1069
@@ -1057,12 +1080,11 @@ void sway_keyboard_destroy(struct sway_keyboard *keyboard) {
1057 if (!keyboard) { 1080 if (!keyboard) {
1058 return; 1081 return;
1059 } 1082 }
1060 if (keyboard->seat_device->input_device->wlr_device->keyboard->group) { 1083 if (keyboard->wlr->group) {
1061 sway_keyboard_group_remove(keyboard); 1084 sway_keyboard_group_remove(keyboard);
1062 } 1085 }
1063 struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat; 1086 struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat;
1064 struct sway_input_device *device = keyboard->seat_device->input_device; 1087 if (wlr_seat_get_keyboard(wlr_seat) == keyboard->wlr) {
1065 if (wlr_seat_get_keyboard(wlr_seat) == device->wlr_device->keyboard) {
1066 wlr_seat_set_keyboard(wlr_seat, NULL); 1088 wlr_seat_set_keyboard(wlr_seat, NULL);
1067 } 1089 }
1068 if (keyboard->keymap) { 1090 if (keyboard->keymap) {