diff options
Diffstat (limited to 'sway/input/keyboard.c')
-rw-r--r-- | sway/input/keyboard.c | 187 |
1 files changed, 78 insertions, 109 deletions
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 8f18b8ba..f74d0658 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c | |||
@@ -1,10 +1,9 @@ | |||
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> |
@@ -16,6 +15,10 @@ | |||
16 | #include "sway/ipc-server.h" | 15 | #include "sway/ipc-server.h" |
17 | #include "log.h" | 16 | #include "log.h" |
18 | 17 | ||
18 | #if WLR_HAS_SESSION | ||
19 | #include <wlr/backend/session.h> | ||
20 | #endif | ||
21 | |||
19 | static struct modifier_key { | 22 | static struct modifier_key { |
20 | char *name; | 23 | char *name; |
21 | uint32_t mod; | 24 | uint32_t mod; |
@@ -29,6 +32,7 @@ static struct modifier_key { | |||
29 | { XKB_MOD_NAME_NUM, WLR_MODIFIER_MOD2 }, | 32 | { XKB_MOD_NAME_NUM, WLR_MODIFIER_MOD2 }, |
30 | { "Mod3", WLR_MODIFIER_MOD3 }, | 33 | { "Mod3", WLR_MODIFIER_MOD3 }, |
31 | { XKB_MOD_NAME_LOGO, WLR_MODIFIER_LOGO }, | 34 | { XKB_MOD_NAME_LOGO, WLR_MODIFIER_LOGO }, |
35 | { "Super", WLR_MODIFIER_LOGO }, | ||
32 | { "Mod5", WLR_MODIFIER_MOD5 }, | 36 | { "Mod5", WLR_MODIFIER_MOD5 }, |
33 | }; | 37 | }; |
34 | 38 | ||
@@ -264,14 +268,12 @@ static bool keyboard_execute_compositor_binding(struct sway_keyboard *keyboard, | |||
264 | xkb_keysym_t keysym = pressed_keysyms[i]; | 268 | xkb_keysym_t keysym = pressed_keysyms[i]; |
265 | if (keysym >= XKB_KEY_XF86Switch_VT_1 && | 269 | if (keysym >= XKB_KEY_XF86Switch_VT_1 && |
266 | keysym <= XKB_KEY_XF86Switch_VT_12) { | 270 | keysym <= XKB_KEY_XF86Switch_VT_12) { |
267 | if (wlr_backend_is_multi(server.backend)) { | 271 | #if WLR_HAS_SESSION |
268 | struct wlr_session *session = | 272 | if (server.session) { |
269 | wlr_backend_get_session(server.backend); | 273 | unsigned vt = keysym - XKB_KEY_XF86Switch_VT_1 + 1; |
270 | if (session) { | 274 | wlr_session_change_vt(server.session, vt); |
271 | unsigned vt = keysym - XKB_KEY_XF86Switch_VT_1 + 1; | ||
272 | wlr_session_change_vt(session, vt); | ||
273 | } | ||
274 | } | 275 | } |
276 | #endif | ||
275 | return true; | 277 | return true; |
276 | } | 278 | } |
277 | } | 279 | } |
@@ -291,14 +293,12 @@ static bool keyboard_execute_compositor_binding(struct sway_keyboard *keyboard, | |||
291 | static size_t keyboard_keysyms_translated(struct sway_keyboard *keyboard, | 293 | static size_t keyboard_keysyms_translated(struct sway_keyboard *keyboard, |
292 | xkb_keycode_t keycode, const xkb_keysym_t **keysyms, | 294 | xkb_keycode_t keycode, const xkb_keysym_t **keysyms, |
293 | uint32_t *modifiers) { | 295 | uint32_t *modifiers) { |
294 | struct wlr_input_device *device = | 296 | *modifiers = wlr_keyboard_get_modifiers(keyboard->wlr); |
295 | keyboard->seat_device->input_device->wlr_device; | ||
296 | *modifiers = wlr_keyboard_get_modifiers(device->keyboard); | ||
297 | xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods2( | 297 | xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods2( |
298 | device->keyboard->xkb_state, keycode, XKB_CONSUMED_MODE_XKB); | 298 | keyboard->wlr->xkb_state, keycode, XKB_CONSUMED_MODE_XKB); |
299 | *modifiers = *modifiers & ~consumed; | 299 | *modifiers = *modifiers & ~consumed; |
300 | 300 | ||
301 | return xkb_state_key_get_syms(device->keyboard->xkb_state, | 301 | return xkb_state_key_get_syms(keyboard->wlr->xkb_state, |
302 | keycode, keysyms); | 302 | keycode, keysyms); |
303 | } | 303 | } |
304 | 304 | ||
@@ -314,13 +314,11 @@ static size_t keyboard_keysyms_translated(struct sway_keyboard *keyboard, | |||
314 | static size_t keyboard_keysyms_raw(struct sway_keyboard *keyboard, | 314 | static size_t keyboard_keysyms_raw(struct sway_keyboard *keyboard, |
315 | xkb_keycode_t keycode, const xkb_keysym_t **keysyms, | 315 | xkb_keycode_t keycode, const xkb_keysym_t **keysyms, |
316 | uint32_t *modifiers) { | 316 | uint32_t *modifiers) { |
317 | struct wlr_input_device *device = | 317 | *modifiers = wlr_keyboard_get_modifiers(keyboard->wlr); |
318 | keyboard->seat_device->input_device->wlr_device; | ||
319 | *modifiers = wlr_keyboard_get_modifiers(device->keyboard); | ||
320 | 318 | ||
321 | xkb_layout_index_t layout_index = xkb_state_key_get_layout( | 319 | xkb_layout_index_t layout_index = xkb_state_key_get_layout( |
322 | device->keyboard->xkb_state, keycode); | 320 | keyboard->wlr->xkb_state, keycode); |
323 | return xkb_keymap_key_get_syms_by_level(device->keyboard->keymap, | 321 | return xkb_keymap_key_get_syms_by_level(keyboard->wlr->keymap, |
324 | keycode, layout_index, 0, keysyms); | 322 | keycode, layout_index, 0, keysyms); |
325 | } | 323 | } |
326 | 324 | ||
@@ -360,8 +358,7 @@ static void update_keyboard_state(struct sway_keyboard *keyboard, | |||
360 | keyinfo->keycode, &keyinfo->translated_keysyms, | 358 | keyinfo->keycode, &keyinfo->translated_keysyms, |
361 | &keyinfo->translated_modifiers); | 359 | &keyinfo->translated_modifiers); |
362 | 360 | ||
363 | keyinfo->code_modifiers = wlr_keyboard_get_modifiers( | 361 | keyinfo->code_modifiers = wlr_keyboard_get_modifiers(keyboard->wlr); |
364 | keyboard->seat_device->input_device->wlr_device->keyboard); | ||
365 | 362 | ||
366 | // Update shortcut model keyinfo | 363 | // Update shortcut model keyinfo |
367 | update_shortcut_state(&keyboard->state_keycodes, raw_keycode, keystate, | 364 | update_shortcut_state(&keyboard->state_keycodes, raw_keycode, keystate, |
@@ -407,10 +404,9 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
407 | struct wlr_input_device *wlr_device = | 404 | struct wlr_input_device *wlr_device = |
408 | keyboard->seat_device->input_device->wlr_device; | 405 | keyboard->seat_device->input_device->wlr_device; |
409 | char *device_identifier = input_device_get_identifier(wlr_device); | 406 | char *device_identifier = input_device_get_identifier(wlr_device); |
410 | bool exact_identifier = wlr_device->keyboard->group != NULL; | 407 | bool exact_identifier = keyboard->wlr->group != NULL; |
411 | seat_idle_notify_activity(seat, IDLE_SOURCE_KEYBOARD); | 408 | seat_idle_notify_activity(seat, IDLE_SOURCE_KEYBOARD); |
412 | bool input_inhibited = seat->exclusive_client != NULL || | 409 | bool locked = server.session_lock.lock; |
413 | server.session_lock.locked; | ||
414 | struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor = | 410 | struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor = |
415 | keyboard_shortcuts_inhibitor_get_for_focused_surface(seat); | 411 | keyboard_shortcuts_inhibitor_get_for_focused_surface(seat); |
416 | bool shortcuts_inhibited = sway_inhibitor && sway_inhibitor->inhibitor->active; | 412 | bool shortcuts_inhibited = sway_inhibitor && sway_inhibitor->inhibitor->active; |
@@ -428,17 +424,17 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
428 | struct sway_binding *binding_released = NULL; | 424 | struct sway_binding *binding_released = NULL; |
429 | get_active_binding(&keyboard->state_keycodes, | 425 | get_active_binding(&keyboard->state_keycodes, |
430 | config->current_mode->keycode_bindings, &binding_released, | 426 | config->current_mode->keycode_bindings, &binding_released, |
431 | keyinfo.code_modifiers, true, input_inhibited, | 427 | keyinfo.code_modifiers, true, locked, |
432 | shortcuts_inhibited, device_identifier, | 428 | shortcuts_inhibited, device_identifier, |
433 | exact_identifier, keyboard->effective_layout); | 429 | exact_identifier, keyboard->effective_layout); |
434 | get_active_binding(&keyboard->state_keysyms_raw, | 430 | get_active_binding(&keyboard->state_keysyms_raw, |
435 | config->current_mode->keysym_bindings, &binding_released, | 431 | config->current_mode->keysym_bindings, &binding_released, |
436 | keyinfo.raw_modifiers, true, input_inhibited, | 432 | keyinfo.raw_modifiers, true, locked, |
437 | shortcuts_inhibited, device_identifier, | 433 | shortcuts_inhibited, device_identifier, |
438 | exact_identifier, keyboard->effective_layout); | 434 | exact_identifier, keyboard->effective_layout); |
439 | get_active_binding(&keyboard->state_keysyms_translated, | 435 | get_active_binding(&keyboard->state_keysyms_translated, |
440 | config->current_mode->keysym_bindings, &binding_released, | 436 | config->current_mode->keysym_bindings, &binding_released, |
441 | keyinfo.translated_modifiers, true, input_inhibited, | 437 | keyinfo.translated_modifiers, true, locked, |
442 | shortcuts_inhibited, device_identifier, | 438 | shortcuts_inhibited, device_identifier, |
443 | exact_identifier, keyboard->effective_layout); | 439 | exact_identifier, keyboard->effective_layout); |
444 | 440 | ||
@@ -460,17 +456,17 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
460 | if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { | 456 | if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { |
461 | get_active_binding(&keyboard->state_keycodes, | 457 | get_active_binding(&keyboard->state_keycodes, |
462 | config->current_mode->keycode_bindings, &binding, | 458 | config->current_mode->keycode_bindings, &binding, |
463 | keyinfo.code_modifiers, false, input_inhibited, | 459 | keyinfo.code_modifiers, false, locked, |
464 | shortcuts_inhibited, device_identifier, | 460 | shortcuts_inhibited, device_identifier, |
465 | exact_identifier, keyboard->effective_layout); | 461 | exact_identifier, keyboard->effective_layout); |
466 | get_active_binding(&keyboard->state_keysyms_raw, | 462 | get_active_binding(&keyboard->state_keysyms_raw, |
467 | config->current_mode->keysym_bindings, &binding, | 463 | config->current_mode->keysym_bindings, &binding, |
468 | keyinfo.raw_modifiers, false, input_inhibited, | 464 | keyinfo.raw_modifiers, false, locked, |
469 | shortcuts_inhibited, device_identifier, | 465 | shortcuts_inhibited, device_identifier, |
470 | exact_identifier, keyboard->effective_layout); | 466 | exact_identifier, keyboard->effective_layout); |
471 | get_active_binding(&keyboard->state_keysyms_translated, | 467 | get_active_binding(&keyboard->state_keysyms_translated, |
472 | config->current_mode->keysym_bindings, &binding, | 468 | config->current_mode->keysym_bindings, &binding, |
473 | keyinfo.translated_modifiers, false, input_inhibited, | 469 | keyinfo.translated_modifiers, false, locked, |
474 | shortcuts_inhibited, device_identifier, | 470 | shortcuts_inhibited, device_identifier, |
475 | exact_identifier, keyboard->effective_layout); | 471 | exact_identifier, keyboard->effective_layout); |
476 | } | 472 | } |
@@ -478,10 +474,10 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
478 | // Set up (or clear) keyboard repeat for a pressed binding. Since the | 474 | // Set up (or clear) keyboard repeat for a pressed binding. Since the |
479 | // binding may remove the keyboard, the timer needs to be updated first | 475 | // binding may remove the keyboard, the timer needs to be updated first |
480 | if (binding && !(binding->flags & BINDING_NOREPEAT) && | 476 | if (binding && !(binding->flags & BINDING_NOREPEAT) && |
481 | wlr_device->keyboard->repeat_info.delay > 0) { | 477 | keyboard->wlr->repeat_info.delay > 0) { |
482 | keyboard->repeat_binding = binding; | 478 | keyboard->repeat_binding = binding; |
483 | if (wl_event_source_timer_update(keyboard->key_repeat_source, | 479 | if (wl_event_source_timer_update(keyboard->key_repeat_source, |
484 | wlr_device->keyboard->repeat_info.delay) < 0) { | 480 | keyboard->wlr->repeat_info.delay) < 0) { |
485 | sway_log(SWAY_DEBUG, "failed to set key repeat timer"); | 481 | sway_log(SWAY_DEBUG, "failed to set key repeat timer"); |
486 | } | 482 | } |
487 | } else if (keyboard->repeat_binding) { | 483 | } else if (keyboard->repeat_binding) { |
@@ -493,7 +489,7 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
493 | handled = true; | 489 | handled = true; |
494 | } | 490 | } |
495 | 491 | ||
496 | if (!handled && wlr_device->keyboard->group) { | 492 | if (!handled && keyboard->wlr->group) { |
497 | // Only handle device specific bindings for keyboards in a group | 493 | // Only handle device specific bindings for keyboards in a group |
498 | free(device_identifier); | 494 | free(device_identifier); |
499 | return; | 495 | return; |
@@ -518,7 +514,7 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
518 | &keyboard->state_pressed_sent, event->keycode, | 514 | &keyboard->state_pressed_sent, event->keycode, |
519 | event->state, keyinfo.keycode, 0); | 515 | event->state, keyinfo.keycode, 0); |
520 | if (pressed_sent) { | 516 | if (pressed_sent) { |
521 | wlr_seat_set_keyboard(wlr_seat, wlr_device->keyboard); | 517 | wlr_seat_set_keyboard(wlr_seat, keyboard->wlr); |
522 | wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec, | 518 | wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec, |
523 | event->keycode, event->state); | 519 | event->keycode, event->state); |
524 | handled = true; | 520 | handled = true; |
@@ -529,8 +525,7 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
529 | struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(keyboard); | 525 | struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(keyboard); |
530 | 526 | ||
531 | if (kb_grab) { | 527 | if (kb_grab) { |
532 | wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab, | 528 | wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab, keyboard->wlr); |
533 | wlr_device->keyboard); | ||
534 | wlr_input_method_keyboard_grab_v2_send_key(kb_grab, | 529 | wlr_input_method_keyboard_grab_v2_send_key(kb_grab, |
535 | event->time_msec, event->keycode, event->state); | 530 | event->time_msec, event->keycode, event->state); |
536 | handled = true; | 531 | handled = true; |
@@ -543,7 +538,7 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
543 | update_shortcut_state( | 538 | update_shortcut_state( |
544 | &keyboard->state_pressed_sent, event->keycode, event->state, | 539 | &keyboard->state_pressed_sent, event->keycode, event->state, |
545 | keyinfo.keycode, 0); | 540 | keyinfo.keycode, 0); |
546 | wlr_seat_set_keyboard(wlr_seat, wlr_device->keyboard); | 541 | wlr_seat_set_keyboard(wlr_seat, keyboard->wlr); |
547 | wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec, | 542 | wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec, |
548 | event->keycode, event->state); | 543 | event->keycode, event->state); |
549 | } | 544 | } |
@@ -619,14 +614,12 @@ static void handle_keyboard_group_leave(struct wl_listener *listener, | |||
619 | } | 614 | } |
620 | 615 | ||
621 | static int handle_keyboard_repeat(void *data) { | 616 | static int handle_keyboard_repeat(void *data) { |
622 | struct sway_keyboard *keyboard = (struct sway_keyboard *)data; | 617 | struct sway_keyboard *keyboard = data; |
623 | struct wlr_keyboard *wlr_device = | ||
624 | keyboard->seat_device->input_device->wlr_device->keyboard; | ||
625 | if (keyboard->repeat_binding) { | 618 | if (keyboard->repeat_binding) { |
626 | if (wlr_device->repeat_info.rate > 0) { | 619 | if (keyboard->wlr->repeat_info.rate > 0) { |
627 | // We queue the next event first, as the command might cancel it | 620 | // We queue the next event first, as the command might cancel it |
628 | if (wl_event_source_timer_update(keyboard->key_repeat_source, | 621 | if (wl_event_source_timer_update(keyboard->key_repeat_source, |
629 | 1000 / wlr_device->repeat_info.rate) < 0) { | 622 | 1000 / keyboard->wlr->repeat_info.rate) < 0) { |
630 | sway_log(SWAY_DEBUG, "failed to update key repeat timer"); | 623 | sway_log(SWAY_DEBUG, "failed to update key repeat timer"); |
631 | } | 624 | } |
632 | } | 625 | } |
@@ -659,31 +652,28 @@ static void determine_bar_visibility(uint32_t modifiers) { | |||
659 | } | 652 | } |
660 | 653 | ||
661 | static void handle_modifier_event(struct sway_keyboard *keyboard) { | 654 | static void handle_modifier_event(struct sway_keyboard *keyboard) { |
662 | struct wlr_input_device *wlr_device = | 655 | if (!keyboard->wlr->group) { |
663 | keyboard->seat_device->input_device->wlr_device; | ||
664 | if (!wlr_device->keyboard->group) { | ||
665 | struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(keyboard); | 656 | struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(keyboard); |
666 | 657 | ||
667 | if (kb_grab) { | 658 | if (kb_grab) { |
668 | wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab, | 659 | wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab, keyboard->wlr); |
669 | wlr_device->keyboard); | ||
670 | wlr_input_method_keyboard_grab_v2_send_modifiers(kb_grab, | 660 | wlr_input_method_keyboard_grab_v2_send_modifiers(kb_grab, |
671 | &wlr_device->keyboard->modifiers); | 661 | &keyboard->wlr->modifiers); |
672 | } else { | 662 | } else { |
673 | struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat; | 663 | struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat; |
674 | wlr_seat_set_keyboard(wlr_seat, wlr_device->keyboard); | 664 | wlr_seat_set_keyboard(wlr_seat, keyboard->wlr); |
675 | wlr_seat_keyboard_notify_modifiers(wlr_seat, | 665 | wlr_seat_keyboard_notify_modifiers(wlr_seat, |
676 | &wlr_device->keyboard->modifiers); | 666 | &keyboard->wlr->modifiers); |
677 | } | 667 | } |
678 | 668 | ||
679 | uint32_t modifiers = wlr_keyboard_get_modifiers(wlr_device->keyboard); | 669 | uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->wlr); |
680 | determine_bar_visibility(modifiers); | 670 | determine_bar_visibility(modifiers); |
681 | } | 671 | } |
682 | 672 | ||
683 | if (wlr_device->keyboard->modifiers.group != keyboard->effective_layout) { | 673 | if (keyboard->wlr->modifiers.group != keyboard->effective_layout) { |
684 | keyboard->effective_layout = wlr_device->keyboard->modifiers.group; | 674 | keyboard->effective_layout = keyboard->wlr->modifiers.group; |
685 | 675 | ||
686 | if (!wlr_keyboard_group_from_wlr_keyboard(wlr_device->keyboard)) { | 676 | if (!wlr_keyboard_group_from_wlr_keyboard(keyboard->wlr)) { |
687 | ipc_event_input("xkb_layout", keyboard->seat_device->input_device); | 677 | ipc_event_input("xkb_layout", keyboard->seat_device->input_device); |
688 | } | 678 | } |
689 | } | 679 | } |
@@ -712,6 +702,7 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, | |||
712 | } | 702 | } |
713 | 703 | ||
714 | keyboard->seat_device = device; | 704 | keyboard->seat_device = device; |
705 | keyboard->wlr = wlr_keyboard_from_input_device(device->input_device->wlr_device); | ||
715 | device->keyboard = keyboard; | 706 | device->keyboard = keyboard; |
716 | 707 | ||
717 | wl_list_init(&keyboard->keyboard_key.link); | 708 | wl_list_init(&keyboard->keyboard_key.link); |
@@ -725,23 +716,11 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, | |||
725 | 716 | ||
726 | static void handle_xkb_context_log(struct xkb_context *context, | 717 | static void handle_xkb_context_log(struct xkb_context *context, |
727 | enum xkb_log_level level, const char *format, va_list args) { | 718 | enum xkb_log_level level, const char *format, va_list args) { |
728 | va_list args_copy; | 719 | char *error = vformat_str(format, args); |
729 | va_copy(args_copy, args); | ||
730 | size_t length = vsnprintf(NULL, 0, format, args_copy) + 1; | ||
731 | va_end(args_copy); | ||
732 | |||
733 | char *error = malloc(length); | ||
734 | if (!error) { | ||
735 | sway_log(SWAY_ERROR, "Failed to allocate libxkbcommon log message"); | ||
736 | return; | ||
737 | } | ||
738 | |||
739 | va_copy(args_copy, args); | ||
740 | vsnprintf(error, length, format, args_copy); | ||
741 | va_end(args_copy); | ||
742 | 720 | ||
743 | if (error[length - 2] == '\n') { | 721 | size_t len = strlen(error); |
744 | error[length - 2] = '\0'; | 722 | if (error[len - 1] == '\n') { |
723 | error[len - 1] = '\0'; | ||
745 | } | 724 | } |
746 | 725 | ||
747 | sway_log_importance_t importance = SWAY_DEBUG; | 726 | sway_log_importance_t importance = SWAY_DEBUG; |
@@ -762,7 +741,7 @@ static void handle_xkb_context_log(struct xkb_context *context, | |||
762 | 741 | ||
763 | struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic, | 742 | struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic, |
764 | char **error) { | 743 | char **error) { |
765 | struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); | 744 | struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_SECURE_GETENV); |
766 | if (!sway_assert(context, "cannot create XKB context")) { | 745 | if (!sway_assert(context, "cannot create XKB context")) { |
767 | return NULL; | 746 | return NULL; |
768 | } | 747 | } |
@@ -776,13 +755,8 @@ struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic, | |||
776 | if (!keymap_file) { | 755 | if (!keymap_file) { |
777 | sway_log_errno(SWAY_ERROR, "cannot read xkb file %s", ic->xkb_file); | 756 | sway_log_errno(SWAY_ERROR, "cannot read xkb file %s", ic->xkb_file); |
778 | if (error) { | 757 | if (error) { |
779 | size_t len = snprintf(NULL, 0, "cannot read xkb file %s: %s", | 758 | *error = format_str("cannot read xkb file %s: %s", |
780 | ic->xkb_file, strerror(errno)) + 1; | 759 | ic->xkb_file, strerror(errno)); |
781 | *error = malloc(len); | ||
782 | if (*error) { | ||
783 | snprintf(*error, len, "cannot read xkb_file %s: %s", | ||
784 | ic->xkb_file, strerror(errno)); | ||
785 | } | ||
786 | } | 760 | } |
787 | goto cleanup; | 761 | goto cleanup; |
788 | } | 762 | } |
@@ -820,13 +794,12 @@ static void destroy_empty_wlr_keyboard_group(void *data) { | |||
820 | 794 | ||
821 | static void sway_keyboard_group_remove(struct sway_keyboard *keyboard) { | 795 | static void sway_keyboard_group_remove(struct sway_keyboard *keyboard) { |
822 | struct sway_input_device *device = keyboard->seat_device->input_device; | 796 | struct sway_input_device *device = keyboard->seat_device->input_device; |
823 | struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard; | 797 | struct wlr_keyboard_group *wlr_group = keyboard->wlr->group; |
824 | struct wlr_keyboard_group *wlr_group = wlr_keyboard->group; | ||
825 | 798 | ||
826 | sway_log(SWAY_DEBUG, "Removing keyboard %s from group %p", | 799 | sway_log(SWAY_DEBUG, "Removing keyboard %s from group %p", |
827 | device->identifier, wlr_group); | 800 | device->identifier, wlr_group); |
828 | 801 | ||
829 | wlr_keyboard_group_remove_keyboard(wlr_keyboard->group, wlr_keyboard); | 802 | wlr_keyboard_group_remove_keyboard(keyboard->wlr->group, keyboard->wlr); |
830 | 803 | ||
831 | if (wl_list_empty(&wlr_group->devices)) { | 804 | if (wl_list_empty(&wlr_group->devices)) { |
832 | sway_log(SWAY_DEBUG, "Destroying empty keyboard group %p", | 805 | sway_log(SWAY_DEBUG, "Destroying empty keyboard group %p", |
@@ -851,9 +824,7 @@ static void sway_keyboard_group_remove(struct sway_keyboard *keyboard) { | |||
851 | } | 824 | } |
852 | 825 | ||
853 | static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) { | 826 | static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) { |
854 | struct sway_input_device *device = keyboard->seat_device->input_device; | 827 | if (!keyboard->wlr->group) { |
855 | struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard; | ||
856 | if (!wlr_keyboard->group) { | ||
857 | return; | 828 | return; |
858 | } | 829 | } |
859 | 830 | ||
@@ -869,7 +840,7 @@ static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) { | |||
869 | break; | 840 | break; |
870 | case KEYBOARD_GROUP_DEFAULT: /* fallthrough */ | 841 | case KEYBOARD_GROUP_DEFAULT: /* fallthrough */ |
871 | case KEYBOARD_GROUP_SMART:; | 842 | case KEYBOARD_GROUP_SMART:; |
872 | struct wlr_keyboard_group *group = wlr_keyboard->group; | 843 | struct wlr_keyboard_group *group = keyboard->wlr->group; |
873 | if (!wlr_keyboard_keymaps_match(keyboard->keymap, group->keyboard.keymap) || | 844 | if (!wlr_keyboard_keymaps_match(keyboard->keymap, group->keyboard.keymap) || |
874 | !repeat_info_match(keyboard, &group->keyboard)) { | 845 | !repeat_info_match(keyboard, &group->keyboard)) { |
875 | sway_keyboard_group_remove(keyboard); | 846 | sway_keyboard_group_remove(keyboard); |
@@ -880,7 +851,6 @@ static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) { | |||
880 | 851 | ||
881 | static void sway_keyboard_group_add(struct sway_keyboard *keyboard) { | 852 | static void sway_keyboard_group_add(struct sway_keyboard *keyboard) { |
882 | struct sway_input_device *device = keyboard->seat_device->input_device; | 853 | struct sway_input_device *device = keyboard->seat_device->input_device; |
883 | struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard; | ||
884 | struct sway_seat *seat = keyboard->seat_device->sway_seat; | 854 | struct sway_seat *seat = keyboard->seat_device->sway_seat; |
885 | struct seat_config *sc = seat_get_config(seat); | 855 | struct seat_config *sc = seat_get_config(seat); |
886 | 856 | ||
@@ -912,7 +882,7 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) { | |||
912 | repeat_info_match(keyboard, &wlr_group->keyboard)) { | 882 | repeat_info_match(keyboard, &wlr_group->keyboard)) { |
913 | sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p", | 883 | sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p", |
914 | device->identifier, wlr_group); | 884 | device->identifier, wlr_group); |
915 | wlr_keyboard_group_add_keyboard(wlr_group, wlr_keyboard); | 885 | wlr_keyboard_group_add_keyboard(wlr_group, keyboard->wlr); |
916 | return; | 886 | return; |
917 | } | 887 | } |
918 | break; | 888 | break; |
@@ -960,7 +930,7 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) { | |||
960 | 930 | ||
961 | sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p", | 931 | sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p", |
962 | device->identifier, sway_group->wlr_group); | 932 | device->identifier, sway_group->wlr_group); |
963 | wlr_keyboard_group_add_keyboard(sway_group->wlr_group, wlr_keyboard); | 933 | wlr_keyboard_group_add_keyboard(sway_group->wlr_group, keyboard->wlr); |
964 | 934 | ||
965 | wl_list_insert(&seat->keyboard_groups, &sway_group->link); | 935 | wl_list_insert(&seat->keyboard_groups, &sway_group->link); |
966 | 936 | ||
@@ -992,10 +962,8 @@ cleanup: | |||
992 | void sway_keyboard_configure(struct sway_keyboard *keyboard) { | 962 | void sway_keyboard_configure(struct sway_keyboard *keyboard) { |
993 | struct input_config *input_config = | 963 | struct input_config *input_config = |
994 | input_device_get_config(keyboard->seat_device->input_device); | 964 | input_device_get_config(keyboard->seat_device->input_device); |
995 | struct wlr_input_device *wlr_device = | ||
996 | keyboard->seat_device->input_device->wlr_device; | ||
997 | 965 | ||
998 | if (!sway_assert(!wlr_keyboard_group_from_wlr_keyboard(wlr_device->keyboard), | 966 | if (!sway_assert(!wlr_keyboard_group_from_wlr_keyboard(keyboard->wlr), |
999 | "sway_keyboard_configure should not be called with a " | 967 | "sway_keyboard_configure should not be called with a " |
1000 | "keyboard group's keyboard")) { | 968 | "keyboard group's keyboard")) { |
1001 | return; | 969 | return; |
@@ -1037,11 +1005,11 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) { | |||
1037 | 1005 | ||
1038 | sway_keyboard_group_remove_invalid(keyboard); | 1006 | sway_keyboard_group_remove_invalid(keyboard); |
1039 | 1007 | ||
1040 | wlr_keyboard_set_keymap(wlr_device->keyboard, keyboard->keymap); | 1008 | wlr_keyboard_set_keymap(keyboard->wlr, keyboard->keymap); |
1041 | wlr_keyboard_set_repeat_info(wlr_device->keyboard, | 1009 | wlr_keyboard_set_repeat_info(keyboard->wlr, |
1042 | keyboard->repeat_rate, keyboard->repeat_delay); | 1010 | keyboard->repeat_rate, keyboard->repeat_delay); |
1043 | 1011 | ||
1044 | if (!wlr_device->keyboard->group) { | 1012 | if (!keyboard->wlr->group) { |
1045 | sway_keyboard_group_add(keyboard); | 1013 | sway_keyboard_group_add(keyboard); |
1046 | } | 1014 | } |
1047 | 1015 | ||
@@ -1061,40 +1029,42 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) { | |||
1061 | } | 1029 | } |
1062 | } | 1030 | } |
1063 | if (locked_mods) { | 1031 | if (locked_mods) { |
1064 | wlr_keyboard_notify_modifiers(wlr_device->keyboard, 0, 0, | 1032 | wlr_keyboard_notify_modifiers(keyboard->wlr, 0, 0, |
1065 | locked_mods, 0); | 1033 | locked_mods, 0); |
1066 | uint32_t leds = 0; | 1034 | uint32_t leds = 0; |
1067 | for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) { | 1035 | for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) { |
1068 | if (xkb_state_led_index_is_active( | 1036 | if (xkb_state_led_index_is_active(keyboard->wlr->xkb_state, |
1069 | wlr_device->keyboard->xkb_state, | 1037 | keyboard->wlr->led_indexes[i])) { |
1070 | wlr_device->keyboard->led_indexes[i])) { | ||
1071 | leds |= (1 << i); | 1038 | leds |= (1 << i); |
1072 | } | 1039 | } |
1073 | } | 1040 | } |
1074 | if (wlr_device->keyboard->group) { | 1041 | if (keyboard->wlr->group) { |
1075 | wlr_keyboard_led_update( | 1042 | wlr_keyboard_led_update(&keyboard->wlr->group->keyboard, leds); |
1076 | &wlr_device->keyboard->group->keyboard, leds); | ||
1077 | } else { | 1043 | } else { |
1078 | wlr_keyboard_led_update(wlr_device->keyboard, leds); | 1044 | wlr_keyboard_led_update(keyboard->wlr, leds); |
1079 | } | 1045 | } |
1080 | } | 1046 | } |
1081 | } else { | 1047 | } else { |
1082 | xkb_keymap_unref(keymap); | 1048 | xkb_keymap_unref(keymap); |
1083 | sway_keyboard_group_remove_invalid(keyboard); | 1049 | sway_keyboard_group_remove_invalid(keyboard); |
1084 | if (!wlr_device->keyboard->group) { | 1050 | if (!keyboard->wlr->group) { |
1085 | sway_keyboard_group_add(keyboard); | 1051 | sway_keyboard_group_add(keyboard); |
1086 | } | 1052 | } |
1087 | } | 1053 | } |
1088 | 1054 | ||
1055 | // If the seat has no active keyboard, set this one | ||
1089 | struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat; | 1056 | struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat; |
1090 | wlr_seat_set_keyboard(seat, wlr_device->keyboard); | 1057 | struct wlr_keyboard *current_keyboard = seat->keyboard_state.keyboard; |
1058 | if (current_keyboard == NULL) { | ||
1059 | wlr_seat_set_keyboard(seat, keyboard->wlr); | ||
1060 | } | ||
1091 | 1061 | ||
1092 | wl_list_remove(&keyboard->keyboard_key.link); | 1062 | wl_list_remove(&keyboard->keyboard_key.link); |
1093 | wl_signal_add(&wlr_device->keyboard->events.key, &keyboard->keyboard_key); | 1063 | wl_signal_add(&keyboard->wlr->events.key, &keyboard->keyboard_key); |
1094 | keyboard->keyboard_key.notify = handle_keyboard_key; | 1064 | keyboard->keyboard_key.notify = handle_keyboard_key; |
1095 | 1065 | ||
1096 | wl_list_remove(&keyboard->keyboard_modifiers.link); | 1066 | wl_list_remove(&keyboard->keyboard_modifiers.link); |
1097 | wl_signal_add(&wlr_device->keyboard->events.modifiers, | 1067 | wl_signal_add(&keyboard->wlr->events.modifiers, |
1098 | &keyboard->keyboard_modifiers); | 1068 | &keyboard->keyboard_modifiers); |
1099 | keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers; | 1069 | keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers; |
1100 | 1070 | ||
@@ -1111,12 +1081,11 @@ void sway_keyboard_destroy(struct sway_keyboard *keyboard) { | |||
1111 | if (!keyboard) { | 1081 | if (!keyboard) { |
1112 | return; | 1082 | return; |
1113 | } | 1083 | } |
1114 | if (keyboard->seat_device->input_device->wlr_device->keyboard->group) { | 1084 | if (keyboard->wlr->group) { |
1115 | sway_keyboard_group_remove(keyboard); | 1085 | sway_keyboard_group_remove(keyboard); |
1116 | } | 1086 | } |
1117 | struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat; | 1087 | struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat; |
1118 | struct sway_input_device *device = keyboard->seat_device->input_device; | 1088 | if (wlr_seat_get_keyboard(wlr_seat) == keyboard->wlr) { |
1119 | if (wlr_seat_get_keyboard(wlr_seat) == device->wlr_device->keyboard) { | ||
1120 | wlr_seat_set_keyboard(wlr_seat, NULL); | 1089 | wlr_seat_set_keyboard(wlr_seat, NULL); |
1121 | } | 1090 | } |
1122 | if (keyboard->keymap) { | 1091 | if (keyboard->keymap) { |