diff options
Diffstat (limited to 'sway/input/keyboard.c')
-rw-r--r-- | sway/input/keyboard.c | 190 |
1 files changed, 80 insertions, 110 deletions
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index f258ac7d..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, |
@@ -401,15 +398,15 @@ static struct wlr_input_method_keyboard_grab_v2 *keyboard_get_im_grab( | |||
401 | } | 398 | } |
402 | 399 | ||
403 | static void handle_key_event(struct sway_keyboard *keyboard, | 400 | static void handle_key_event(struct sway_keyboard *keyboard, |
404 | struct wlr_event_keyboard_key *event) { | 401 | struct wlr_keyboard_key_event *event) { |
405 | struct sway_seat *seat = keyboard->seat_device->sway_seat; | 402 | struct sway_seat *seat = keyboard->seat_device->sway_seat; |
406 | struct wlr_seat *wlr_seat = seat->wlr_seat; | 403 | struct wlr_seat *wlr_seat = seat->wlr_seat; |
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 | struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor = | 410 | struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor = |
414 | keyboard_shortcuts_inhibitor_get_for_focused_surface(seat); | 411 | keyboard_shortcuts_inhibitor_get_for_focused_surface(seat); |
415 | bool shortcuts_inhibited = sway_inhibitor && sway_inhibitor->inhibitor->active; | 412 | bool shortcuts_inhibited = sway_inhibitor && sway_inhibitor->inhibitor->active; |
@@ -427,17 +424,17 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
427 | struct sway_binding *binding_released = NULL; | 424 | struct sway_binding *binding_released = NULL; |
428 | get_active_binding(&keyboard->state_keycodes, | 425 | get_active_binding(&keyboard->state_keycodes, |
429 | config->current_mode->keycode_bindings, &binding_released, | 426 | config->current_mode->keycode_bindings, &binding_released, |
430 | keyinfo.code_modifiers, true, input_inhibited, | 427 | keyinfo.code_modifiers, true, locked, |
431 | shortcuts_inhibited, device_identifier, | 428 | shortcuts_inhibited, device_identifier, |
432 | exact_identifier, keyboard->effective_layout); | 429 | exact_identifier, keyboard->effective_layout); |
433 | get_active_binding(&keyboard->state_keysyms_raw, | 430 | get_active_binding(&keyboard->state_keysyms_raw, |
434 | config->current_mode->keysym_bindings, &binding_released, | 431 | config->current_mode->keysym_bindings, &binding_released, |
435 | keyinfo.raw_modifiers, true, input_inhibited, | 432 | keyinfo.raw_modifiers, true, locked, |
436 | shortcuts_inhibited, device_identifier, | 433 | shortcuts_inhibited, device_identifier, |
437 | exact_identifier, keyboard->effective_layout); | 434 | exact_identifier, keyboard->effective_layout); |
438 | get_active_binding(&keyboard->state_keysyms_translated, | 435 | get_active_binding(&keyboard->state_keysyms_translated, |
439 | config->current_mode->keysym_bindings, &binding_released, | 436 | config->current_mode->keysym_bindings, &binding_released, |
440 | keyinfo.translated_modifiers, true, input_inhibited, | 437 | keyinfo.translated_modifiers, true, locked, |
441 | shortcuts_inhibited, device_identifier, | 438 | shortcuts_inhibited, device_identifier, |
442 | exact_identifier, keyboard->effective_layout); | 439 | exact_identifier, keyboard->effective_layout); |
443 | 440 | ||
@@ -459,17 +456,17 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
459 | if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { | 456 | if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { |
460 | get_active_binding(&keyboard->state_keycodes, | 457 | get_active_binding(&keyboard->state_keycodes, |
461 | config->current_mode->keycode_bindings, &binding, | 458 | config->current_mode->keycode_bindings, &binding, |
462 | keyinfo.code_modifiers, false, input_inhibited, | 459 | keyinfo.code_modifiers, false, locked, |
463 | shortcuts_inhibited, device_identifier, | 460 | shortcuts_inhibited, device_identifier, |
464 | exact_identifier, keyboard->effective_layout); | 461 | exact_identifier, keyboard->effective_layout); |
465 | get_active_binding(&keyboard->state_keysyms_raw, | 462 | get_active_binding(&keyboard->state_keysyms_raw, |
466 | config->current_mode->keysym_bindings, &binding, | 463 | config->current_mode->keysym_bindings, &binding, |
467 | keyinfo.raw_modifiers, false, input_inhibited, | 464 | keyinfo.raw_modifiers, false, locked, |
468 | shortcuts_inhibited, device_identifier, | 465 | shortcuts_inhibited, device_identifier, |
469 | exact_identifier, keyboard->effective_layout); | 466 | exact_identifier, keyboard->effective_layout); |
470 | get_active_binding(&keyboard->state_keysyms_translated, | 467 | get_active_binding(&keyboard->state_keysyms_translated, |
471 | config->current_mode->keysym_bindings, &binding, | 468 | config->current_mode->keysym_bindings, &binding, |
472 | keyinfo.translated_modifiers, false, input_inhibited, | 469 | keyinfo.translated_modifiers, false, locked, |
473 | shortcuts_inhibited, device_identifier, | 470 | shortcuts_inhibited, device_identifier, |
474 | exact_identifier, keyboard->effective_layout); | 471 | exact_identifier, keyboard->effective_layout); |
475 | } | 472 | } |
@@ -477,10 +474,10 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
477 | // 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 |
478 | // 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 |
479 | if (binding && !(binding->flags & BINDING_NOREPEAT) && | 476 | if (binding && !(binding->flags & BINDING_NOREPEAT) && |
480 | wlr_device->keyboard->repeat_info.delay > 0) { | 477 | keyboard->wlr->repeat_info.delay > 0) { |
481 | keyboard->repeat_binding = binding; | 478 | keyboard->repeat_binding = binding; |
482 | if (wl_event_source_timer_update(keyboard->key_repeat_source, | 479 | if (wl_event_source_timer_update(keyboard->key_repeat_source, |
483 | wlr_device->keyboard->repeat_info.delay) < 0) { | 480 | keyboard->wlr->repeat_info.delay) < 0) { |
484 | sway_log(SWAY_DEBUG, "failed to set key repeat timer"); | 481 | sway_log(SWAY_DEBUG, "failed to set key repeat timer"); |
485 | } | 482 | } |
486 | } else if (keyboard->repeat_binding) { | 483 | } else if (keyboard->repeat_binding) { |
@@ -492,7 +489,7 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
492 | handled = true; | 489 | handled = true; |
493 | } | 490 | } |
494 | 491 | ||
495 | if (!handled && wlr_device->keyboard->group) { | 492 | if (!handled && keyboard->wlr->group) { |
496 | // Only handle device specific bindings for keyboards in a group | 493 | // Only handle device specific bindings for keyboards in a group |
497 | free(device_identifier); | 494 | free(device_identifier); |
498 | return; | 495 | return; |
@@ -517,7 +514,7 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
517 | &keyboard->state_pressed_sent, event->keycode, | 514 | &keyboard->state_pressed_sent, event->keycode, |
518 | event->state, keyinfo.keycode, 0); | 515 | event->state, keyinfo.keycode, 0); |
519 | if (pressed_sent) { | 516 | if (pressed_sent) { |
520 | wlr_seat_set_keyboard(wlr_seat, wlr_device); | 517 | wlr_seat_set_keyboard(wlr_seat, keyboard->wlr); |
521 | wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec, | 518 | wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec, |
522 | event->keycode, event->state); | 519 | event->keycode, event->state); |
523 | handled = true; | 520 | handled = true; |
@@ -528,8 +525,7 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
528 | 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); |
529 | 526 | ||
530 | if (kb_grab) { | 527 | if (kb_grab) { |
531 | wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab, | 528 | wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab, keyboard->wlr); |
532 | wlr_device->keyboard); | ||
533 | wlr_input_method_keyboard_grab_v2_send_key(kb_grab, | 529 | wlr_input_method_keyboard_grab_v2_send_key(kb_grab, |
534 | event->time_msec, event->keycode, event->state); | 530 | event->time_msec, event->keycode, event->state); |
535 | handled = true; | 531 | handled = true; |
@@ -542,7 +538,7 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
542 | update_shortcut_state( | 538 | update_shortcut_state( |
543 | &keyboard->state_pressed_sent, event->keycode, event->state, | 539 | &keyboard->state_pressed_sent, event->keycode, event->state, |
544 | keyinfo.keycode, 0); | 540 | keyinfo.keycode, 0); |
545 | wlr_seat_set_keyboard(wlr_seat, wlr_device); | 541 | wlr_seat_set_keyboard(wlr_seat, keyboard->wlr); |
546 | wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec, | 542 | wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec, |
547 | event->keycode, event->state); | 543 | event->keycode, event->state); |
548 | } | 544 | } |
@@ -618,14 +614,12 @@ static void handle_keyboard_group_leave(struct wl_listener *listener, | |||
618 | } | 614 | } |
619 | 615 | ||
620 | static int handle_keyboard_repeat(void *data) { | 616 | static int handle_keyboard_repeat(void *data) { |
621 | struct sway_keyboard *keyboard = (struct sway_keyboard *)data; | 617 | struct sway_keyboard *keyboard = data; |
622 | struct wlr_keyboard *wlr_device = | ||
623 | keyboard->seat_device->input_device->wlr_device->keyboard; | ||
624 | if (keyboard->repeat_binding) { | 618 | if (keyboard->repeat_binding) { |
625 | if (wlr_device->repeat_info.rate > 0) { | 619 | if (keyboard->wlr->repeat_info.rate > 0) { |
626 | // 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 |
627 | if (wl_event_source_timer_update(keyboard->key_repeat_source, | 621 | if (wl_event_source_timer_update(keyboard->key_repeat_source, |
628 | 1000 / wlr_device->repeat_info.rate) < 0) { | 622 | 1000 / keyboard->wlr->repeat_info.rate) < 0) { |
629 | sway_log(SWAY_DEBUG, "failed to update key repeat timer"); | 623 | sway_log(SWAY_DEBUG, "failed to update key repeat timer"); |
630 | } | 624 | } |
631 | } | 625 | } |
@@ -658,31 +652,28 @@ static void determine_bar_visibility(uint32_t modifiers) { | |||
658 | } | 652 | } |
659 | 653 | ||
660 | static void handle_modifier_event(struct sway_keyboard *keyboard) { | 654 | static void handle_modifier_event(struct sway_keyboard *keyboard) { |
661 | struct wlr_input_device *wlr_device = | 655 | if (!keyboard->wlr->group) { |
662 | keyboard->seat_device->input_device->wlr_device; | ||
663 | if (!wlr_device->keyboard->group) { | ||
664 | 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); |
665 | 657 | ||
666 | if (kb_grab) { | 658 | if (kb_grab) { |
667 | wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab, | 659 | wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab, keyboard->wlr); |
668 | wlr_device->keyboard); | ||
669 | wlr_input_method_keyboard_grab_v2_send_modifiers(kb_grab, | 660 | wlr_input_method_keyboard_grab_v2_send_modifiers(kb_grab, |
670 | &wlr_device->keyboard->modifiers); | 661 | &keyboard->wlr->modifiers); |
671 | } else { | 662 | } else { |
672 | 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; |
673 | wlr_seat_set_keyboard(wlr_seat, wlr_device); | 664 | wlr_seat_set_keyboard(wlr_seat, keyboard->wlr); |
674 | wlr_seat_keyboard_notify_modifiers(wlr_seat, | 665 | wlr_seat_keyboard_notify_modifiers(wlr_seat, |
675 | &wlr_device->keyboard->modifiers); | 666 | &keyboard->wlr->modifiers); |
676 | } | 667 | } |
677 | 668 | ||
678 | uint32_t modifiers = wlr_keyboard_get_modifiers(wlr_device->keyboard); | 669 | uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->wlr); |
679 | determine_bar_visibility(modifiers); | 670 | determine_bar_visibility(modifiers); |
680 | } | 671 | } |
681 | 672 | ||
682 | if (wlr_device->keyboard->modifiers.group != keyboard->effective_layout) { | 673 | if (keyboard->wlr->modifiers.group != keyboard->effective_layout) { |
683 | keyboard->effective_layout = wlr_device->keyboard->modifiers.group; | 674 | keyboard->effective_layout = keyboard->wlr->modifiers.group; |
684 | 675 | ||
685 | if (!wlr_keyboard_group_from_wlr_keyboard(wlr_device->keyboard)) { | 676 | if (!wlr_keyboard_group_from_wlr_keyboard(keyboard->wlr)) { |
686 | ipc_event_input("xkb_layout", keyboard->seat_device->input_device); | 677 | ipc_event_input("xkb_layout", keyboard->seat_device->input_device); |
687 | } | 678 | } |
688 | } | 679 | } |
@@ -711,6 +702,7 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, | |||
711 | } | 702 | } |
712 | 703 | ||
713 | keyboard->seat_device = device; | 704 | keyboard->seat_device = device; |
705 | keyboard->wlr = wlr_keyboard_from_input_device(device->input_device->wlr_device); | ||
714 | device->keyboard = keyboard; | 706 | device->keyboard = keyboard; |
715 | 707 | ||
716 | wl_list_init(&keyboard->keyboard_key.link); | 708 | wl_list_init(&keyboard->keyboard_key.link); |
@@ -724,23 +716,11 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, | |||
724 | 716 | ||
725 | static void handle_xkb_context_log(struct xkb_context *context, | 717 | static void handle_xkb_context_log(struct xkb_context *context, |
726 | enum xkb_log_level level, const char *format, va_list args) { | 718 | enum xkb_log_level level, const char *format, va_list args) { |
727 | va_list args_copy; | 719 | char *error = vformat_str(format, args); |
728 | va_copy(args_copy, args); | ||
729 | size_t length = vsnprintf(NULL, 0, format, args_copy) + 1; | ||
730 | va_end(args_copy); | ||
731 | |||
732 | char *error = malloc(length); | ||
733 | if (!error) { | ||
734 | sway_log(SWAY_ERROR, "Failed to allocate libxkbcommon log message"); | ||
735 | return; | ||
736 | } | ||
737 | |||
738 | va_copy(args_copy, args); | ||
739 | vsnprintf(error, length, format, args_copy); | ||
740 | va_end(args_copy); | ||
741 | 720 | ||
742 | if (error[length - 2] == '\n') { | 721 | size_t len = strlen(error); |
743 | error[length - 2] = '\0'; | 722 | if (error[len - 1] == '\n') { |
723 | error[len - 1] = '\0'; | ||
744 | } | 724 | } |
745 | 725 | ||
746 | sway_log_importance_t importance = SWAY_DEBUG; | 726 | sway_log_importance_t importance = SWAY_DEBUG; |
@@ -761,7 +741,7 @@ static void handle_xkb_context_log(struct xkb_context *context, | |||
761 | 741 | ||
762 | struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic, | 742 | struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic, |
763 | char **error) { | 743 | char **error) { |
764 | struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); | 744 | struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_SECURE_GETENV); |
765 | if (!sway_assert(context, "cannot create XKB context")) { | 745 | if (!sway_assert(context, "cannot create XKB context")) { |
766 | return NULL; | 746 | return NULL; |
767 | } | 747 | } |
@@ -775,13 +755,8 @@ struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic, | |||
775 | if (!keymap_file) { | 755 | if (!keymap_file) { |
776 | 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); |
777 | if (error) { | 757 | if (error) { |
778 | size_t len = snprintf(NULL, 0, "cannot read xkb file %s: %s", | 758 | *error = format_str("cannot read xkb file %s: %s", |
779 | ic->xkb_file, strerror(errno)) + 1; | 759 | ic->xkb_file, strerror(errno)); |
780 | *error = malloc(len); | ||
781 | if (*error) { | ||
782 | snprintf(*error, len, "cannot read xkb_file %s: %s", | ||
783 | ic->xkb_file, strerror(errno)); | ||
784 | } | ||
785 | } | 760 | } |
786 | goto cleanup; | 761 | goto cleanup; |
787 | } | 762 | } |
@@ -819,13 +794,12 @@ static void destroy_empty_wlr_keyboard_group(void *data) { | |||
819 | 794 | ||
820 | static void sway_keyboard_group_remove(struct sway_keyboard *keyboard) { | 795 | static void sway_keyboard_group_remove(struct sway_keyboard *keyboard) { |
821 | struct sway_input_device *device = keyboard->seat_device->input_device; | 796 | struct sway_input_device *device = keyboard->seat_device->input_device; |
822 | struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard; | 797 | struct wlr_keyboard_group *wlr_group = keyboard->wlr->group; |
823 | struct wlr_keyboard_group *wlr_group = wlr_keyboard->group; | ||
824 | 798 | ||
825 | sway_log(SWAY_DEBUG, "Removing keyboard %s from group %p", | 799 | sway_log(SWAY_DEBUG, "Removing keyboard %s from group %p", |
826 | device->identifier, wlr_group); | 800 | device->identifier, wlr_group); |
827 | 801 | ||
828 | wlr_keyboard_group_remove_keyboard(wlr_keyboard->group, wlr_keyboard); | 802 | wlr_keyboard_group_remove_keyboard(keyboard->wlr->group, keyboard->wlr); |
829 | 803 | ||
830 | if (wl_list_empty(&wlr_group->devices)) { | 804 | if (wl_list_empty(&wlr_group->devices)) { |
831 | sway_log(SWAY_DEBUG, "Destroying empty keyboard group %p", | 805 | sway_log(SWAY_DEBUG, "Destroying empty keyboard group %p", |
@@ -850,9 +824,7 @@ static void sway_keyboard_group_remove(struct sway_keyboard *keyboard) { | |||
850 | } | 824 | } |
851 | 825 | ||
852 | static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) { | 826 | static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) { |
853 | struct sway_input_device *device = keyboard->seat_device->input_device; | 827 | if (!keyboard->wlr->group) { |
854 | struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard; | ||
855 | if (!wlr_keyboard->group) { | ||
856 | return; | 828 | return; |
857 | } | 829 | } |
858 | 830 | ||
@@ -868,7 +840,7 @@ static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) { | |||
868 | break; | 840 | break; |
869 | case KEYBOARD_GROUP_DEFAULT: /* fallthrough */ | 841 | case KEYBOARD_GROUP_DEFAULT: /* fallthrough */ |
870 | case KEYBOARD_GROUP_SMART:; | 842 | case KEYBOARD_GROUP_SMART:; |
871 | struct wlr_keyboard_group *group = wlr_keyboard->group; | 843 | struct wlr_keyboard_group *group = keyboard->wlr->group; |
872 | if (!wlr_keyboard_keymaps_match(keyboard->keymap, group->keyboard.keymap) || | 844 | if (!wlr_keyboard_keymaps_match(keyboard->keymap, group->keyboard.keymap) || |
873 | !repeat_info_match(keyboard, &group->keyboard)) { | 845 | !repeat_info_match(keyboard, &group->keyboard)) { |
874 | sway_keyboard_group_remove(keyboard); | 846 | sway_keyboard_group_remove(keyboard); |
@@ -879,7 +851,6 @@ static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) { | |||
879 | 851 | ||
880 | static void sway_keyboard_group_add(struct sway_keyboard *keyboard) { | 852 | static void sway_keyboard_group_add(struct sway_keyboard *keyboard) { |
881 | struct sway_input_device *device = keyboard->seat_device->input_device; | 853 | struct sway_input_device *device = keyboard->seat_device->input_device; |
882 | struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard; | ||
883 | struct sway_seat *seat = keyboard->seat_device->sway_seat; | 854 | struct sway_seat *seat = keyboard->seat_device->sway_seat; |
884 | struct seat_config *sc = seat_get_config(seat); | 855 | struct seat_config *sc = seat_get_config(seat); |
885 | 856 | ||
@@ -911,7 +882,7 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) { | |||
911 | repeat_info_match(keyboard, &wlr_group->keyboard)) { | 882 | repeat_info_match(keyboard, &wlr_group->keyboard)) { |
912 | sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p", | 883 | sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p", |
913 | device->identifier, wlr_group); | 884 | device->identifier, wlr_group); |
914 | wlr_keyboard_group_add_keyboard(wlr_group, wlr_keyboard); | 885 | wlr_keyboard_group_add_keyboard(wlr_group, keyboard->wlr); |
915 | return; | 886 | return; |
916 | } | 887 | } |
917 | break; | 888 | break; |
@@ -950,7 +921,7 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) { | |||
950 | goto cleanup; | 921 | goto cleanup; |
951 | } | 922 | } |
952 | sway_group->seat_device->input_device->wlr_device = | 923 | sway_group->seat_device->input_device->wlr_device = |
953 | sway_group->wlr_group->input_device; | 924 | &sway_group->wlr_group->keyboard.base; |
954 | 925 | ||
955 | if (!sway_keyboard_create(seat, sway_group->seat_device)) { | 926 | if (!sway_keyboard_create(seat, sway_group->seat_device)) { |
956 | sway_log(SWAY_ERROR, "Failed to allocate sway_keyboard for group"); | 927 | sway_log(SWAY_ERROR, "Failed to allocate sway_keyboard for group"); |
@@ -959,7 +930,7 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) { | |||
959 | 930 | ||
960 | sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p", | 931 | sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p", |
961 | device->identifier, sway_group->wlr_group); | 932 | device->identifier, sway_group->wlr_group); |
962 | wlr_keyboard_group_add_keyboard(sway_group->wlr_group, wlr_keyboard); | 933 | wlr_keyboard_group_add_keyboard(sway_group->wlr_group, keyboard->wlr); |
963 | 934 | ||
964 | wl_list_insert(&seat->keyboard_groups, &sway_group->link); | 935 | wl_list_insert(&seat->keyboard_groups, &sway_group->link); |
965 | 936 | ||
@@ -991,10 +962,8 @@ cleanup: | |||
991 | void sway_keyboard_configure(struct sway_keyboard *keyboard) { | 962 | void sway_keyboard_configure(struct sway_keyboard *keyboard) { |
992 | struct input_config *input_config = | 963 | struct input_config *input_config = |
993 | input_device_get_config(keyboard->seat_device->input_device); | 964 | input_device_get_config(keyboard->seat_device->input_device); |
994 | struct wlr_input_device *wlr_device = | ||
995 | keyboard->seat_device->input_device->wlr_device; | ||
996 | 965 | ||
997 | if (!sway_assert(!wlr_keyboard_group_from_wlr_keyboard(wlr_device->keyboard), | 966 | if (!sway_assert(!wlr_keyboard_group_from_wlr_keyboard(keyboard->wlr), |
998 | "sway_keyboard_configure should not be called with a " | 967 | "sway_keyboard_configure should not be called with a " |
999 | "keyboard group's keyboard")) { | 968 | "keyboard group's keyboard")) { |
1000 | return; | 969 | return; |
@@ -1036,11 +1005,11 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) { | |||
1036 | 1005 | ||
1037 | sway_keyboard_group_remove_invalid(keyboard); | 1006 | sway_keyboard_group_remove_invalid(keyboard); |
1038 | 1007 | ||
1039 | wlr_keyboard_set_keymap(wlr_device->keyboard, keyboard->keymap); | 1008 | wlr_keyboard_set_keymap(keyboard->wlr, keyboard->keymap); |
1040 | wlr_keyboard_set_repeat_info(wlr_device->keyboard, | 1009 | wlr_keyboard_set_repeat_info(keyboard->wlr, |
1041 | keyboard->repeat_rate, keyboard->repeat_delay); | 1010 | keyboard->repeat_rate, keyboard->repeat_delay); |
1042 | 1011 | ||
1043 | if (!wlr_device->keyboard->group) { | 1012 | if (!keyboard->wlr->group) { |
1044 | sway_keyboard_group_add(keyboard); | 1013 | sway_keyboard_group_add(keyboard); |
1045 | } | 1014 | } |
1046 | 1015 | ||
@@ -1060,40 +1029,42 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) { | |||
1060 | } | 1029 | } |
1061 | } | 1030 | } |
1062 | if (locked_mods) { | 1031 | if (locked_mods) { |
1063 | wlr_keyboard_notify_modifiers(wlr_device->keyboard, 0, 0, | 1032 | wlr_keyboard_notify_modifiers(keyboard->wlr, 0, 0, |
1064 | locked_mods, 0); | 1033 | locked_mods, 0); |
1065 | uint32_t leds = 0; | 1034 | uint32_t leds = 0; |
1066 | for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) { | 1035 | for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) { |
1067 | if (xkb_state_led_index_is_active( | 1036 | if (xkb_state_led_index_is_active(keyboard->wlr->xkb_state, |
1068 | wlr_device->keyboard->xkb_state, | 1037 | keyboard->wlr->led_indexes[i])) { |
1069 | wlr_device->keyboard->led_indexes[i])) { | ||
1070 | leds |= (1 << i); | 1038 | leds |= (1 << i); |
1071 | } | 1039 | } |
1072 | } | 1040 | } |
1073 | if (wlr_device->keyboard->group) { | 1041 | if (keyboard->wlr->group) { |
1074 | wlr_keyboard_led_update( | 1042 | wlr_keyboard_led_update(&keyboard->wlr->group->keyboard, leds); |
1075 | &wlr_device->keyboard->group->keyboard, leds); | ||
1076 | } else { | 1043 | } else { |
1077 | wlr_keyboard_led_update(wlr_device->keyboard, leds); | 1044 | wlr_keyboard_led_update(keyboard->wlr, leds); |
1078 | } | 1045 | } |
1079 | } | 1046 | } |
1080 | } else { | 1047 | } else { |
1081 | xkb_keymap_unref(keymap); | 1048 | xkb_keymap_unref(keymap); |
1082 | sway_keyboard_group_remove_invalid(keyboard); | 1049 | sway_keyboard_group_remove_invalid(keyboard); |
1083 | if (!wlr_device->keyboard->group) { | 1050 | if (!keyboard->wlr->group) { |
1084 | sway_keyboard_group_add(keyboard); | 1051 | sway_keyboard_group_add(keyboard); |
1085 | } | 1052 | } |
1086 | } | 1053 | } |
1087 | 1054 | ||
1055 | // If the seat has no active keyboard, set this one | ||
1088 | struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat; | 1056 | struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat; |
1089 | wlr_seat_set_keyboard(seat, wlr_device); | 1057 | struct wlr_keyboard *current_keyboard = seat->keyboard_state.keyboard; |
1058 | if (current_keyboard == NULL) { | ||
1059 | wlr_seat_set_keyboard(seat, keyboard->wlr); | ||
1060 | } | ||
1090 | 1061 | ||
1091 | wl_list_remove(&keyboard->keyboard_key.link); | 1062 | wl_list_remove(&keyboard->keyboard_key.link); |
1092 | wl_signal_add(&wlr_device->keyboard->events.key, &keyboard->keyboard_key); | 1063 | wl_signal_add(&keyboard->wlr->events.key, &keyboard->keyboard_key); |
1093 | keyboard->keyboard_key.notify = handle_keyboard_key; | 1064 | keyboard->keyboard_key.notify = handle_keyboard_key; |
1094 | 1065 | ||
1095 | wl_list_remove(&keyboard->keyboard_modifiers.link); | 1066 | wl_list_remove(&keyboard->keyboard_modifiers.link); |
1096 | wl_signal_add(&wlr_device->keyboard->events.modifiers, | 1067 | wl_signal_add(&keyboard->wlr->events.modifiers, |
1097 | &keyboard->keyboard_modifiers); | 1068 | &keyboard->keyboard_modifiers); |
1098 | keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers; | 1069 | keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers; |
1099 | 1070 | ||
@@ -1110,12 +1081,11 @@ void sway_keyboard_destroy(struct sway_keyboard *keyboard) { | |||
1110 | if (!keyboard) { | 1081 | if (!keyboard) { |
1111 | return; | 1082 | return; |
1112 | } | 1083 | } |
1113 | if (keyboard->seat_device->input_device->wlr_device->keyboard->group) { | 1084 | if (keyboard->wlr->group) { |
1114 | sway_keyboard_group_remove(keyboard); | 1085 | sway_keyboard_group_remove(keyboard); |
1115 | } | 1086 | } |
1116 | 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; |
1117 | struct sway_input_device *device = keyboard->seat_device->input_device; | 1088 | if (wlr_seat_get_keyboard(wlr_seat) == keyboard->wlr) { |
1118 | if (wlr_seat_get_keyboard(wlr_seat) == device->wlr_device->keyboard) { | ||
1119 | wlr_seat_set_keyboard(wlr_seat, NULL); | 1089 | wlr_seat_set_keyboard(wlr_seat, NULL); |
1120 | } | 1090 | } |
1121 | if (keyboard->keymap) { | 1091 | if (keyboard->keymap) { |