diff options
Diffstat (limited to 'sway/input/keyboard.c')
-rw-r--r-- | sway/input/keyboard.c | 72 |
1 files changed, 30 insertions, 42 deletions
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 5e5692f1..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 | } |
@@ -404,8 +406,7 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
404 | char *device_identifier = input_device_get_identifier(wlr_device); | 406 | char *device_identifier = input_device_get_identifier(wlr_device); |
405 | bool exact_identifier = keyboard->wlr->group != NULL; | 407 | bool exact_identifier = keyboard->wlr->group != NULL; |
406 | seat_idle_notify_activity(seat, IDLE_SOURCE_KEYBOARD); | 408 | seat_idle_notify_activity(seat, IDLE_SOURCE_KEYBOARD); |
407 | bool input_inhibited = seat->exclusive_client != NULL || | 409 | bool locked = server.session_lock.lock; |
408 | server.session_lock.locked; | ||
409 | struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor = | 410 | struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor = |
410 | keyboard_shortcuts_inhibitor_get_for_focused_surface(seat); | 411 | keyboard_shortcuts_inhibitor_get_for_focused_surface(seat); |
411 | bool shortcuts_inhibited = sway_inhibitor && sway_inhibitor->inhibitor->active; | 412 | bool shortcuts_inhibited = sway_inhibitor && sway_inhibitor->inhibitor->active; |
@@ -423,17 +424,17 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
423 | struct sway_binding *binding_released = NULL; | 424 | struct sway_binding *binding_released = NULL; |
424 | get_active_binding(&keyboard->state_keycodes, | 425 | get_active_binding(&keyboard->state_keycodes, |
425 | config->current_mode->keycode_bindings, &binding_released, | 426 | config->current_mode->keycode_bindings, &binding_released, |
426 | keyinfo.code_modifiers, true, input_inhibited, | 427 | keyinfo.code_modifiers, true, locked, |
427 | shortcuts_inhibited, device_identifier, | 428 | shortcuts_inhibited, device_identifier, |
428 | exact_identifier, keyboard->effective_layout); | 429 | exact_identifier, keyboard->effective_layout); |
429 | get_active_binding(&keyboard->state_keysyms_raw, | 430 | get_active_binding(&keyboard->state_keysyms_raw, |
430 | config->current_mode->keysym_bindings, &binding_released, | 431 | config->current_mode->keysym_bindings, &binding_released, |
431 | keyinfo.raw_modifiers, true, input_inhibited, | 432 | keyinfo.raw_modifiers, true, locked, |
432 | shortcuts_inhibited, device_identifier, | 433 | shortcuts_inhibited, device_identifier, |
433 | exact_identifier, keyboard->effective_layout); | 434 | exact_identifier, keyboard->effective_layout); |
434 | get_active_binding(&keyboard->state_keysyms_translated, | 435 | get_active_binding(&keyboard->state_keysyms_translated, |
435 | config->current_mode->keysym_bindings, &binding_released, | 436 | config->current_mode->keysym_bindings, &binding_released, |
436 | keyinfo.translated_modifiers, true, input_inhibited, | 437 | keyinfo.translated_modifiers, true, locked, |
437 | shortcuts_inhibited, device_identifier, | 438 | shortcuts_inhibited, device_identifier, |
438 | exact_identifier, keyboard->effective_layout); | 439 | exact_identifier, keyboard->effective_layout); |
439 | 440 | ||
@@ -455,17 +456,17 @@ static void handle_key_event(struct sway_keyboard *keyboard, | |||
455 | if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { | 456 | if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { |
456 | get_active_binding(&keyboard->state_keycodes, | 457 | get_active_binding(&keyboard->state_keycodes, |
457 | config->current_mode->keycode_bindings, &binding, | 458 | config->current_mode->keycode_bindings, &binding, |
458 | keyinfo.code_modifiers, false, input_inhibited, | 459 | keyinfo.code_modifiers, false, locked, |
459 | shortcuts_inhibited, device_identifier, | 460 | shortcuts_inhibited, device_identifier, |
460 | exact_identifier, keyboard->effective_layout); | 461 | exact_identifier, keyboard->effective_layout); |
461 | get_active_binding(&keyboard->state_keysyms_raw, | 462 | get_active_binding(&keyboard->state_keysyms_raw, |
462 | config->current_mode->keysym_bindings, &binding, | 463 | config->current_mode->keysym_bindings, &binding, |
463 | keyinfo.raw_modifiers, false, input_inhibited, | 464 | keyinfo.raw_modifiers, false, locked, |
464 | shortcuts_inhibited, device_identifier, | 465 | shortcuts_inhibited, device_identifier, |
465 | exact_identifier, keyboard->effective_layout); | 466 | exact_identifier, keyboard->effective_layout); |
466 | get_active_binding(&keyboard->state_keysyms_translated, | 467 | get_active_binding(&keyboard->state_keysyms_translated, |
467 | config->current_mode->keysym_bindings, &binding, | 468 | config->current_mode->keysym_bindings, &binding, |
468 | keyinfo.translated_modifiers, false, input_inhibited, | 469 | keyinfo.translated_modifiers, false, locked, |
469 | shortcuts_inhibited, device_identifier, | 470 | shortcuts_inhibited, device_identifier, |
470 | exact_identifier, keyboard->effective_layout); | 471 | exact_identifier, keyboard->effective_layout); |
471 | } | 472 | } |
@@ -715,23 +716,11 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, | |||
715 | 716 | ||
716 | static void handle_xkb_context_log(struct xkb_context *context, | 717 | static void handle_xkb_context_log(struct xkb_context *context, |
717 | enum xkb_log_level level, const char *format, va_list args) { | 718 | enum xkb_log_level level, const char *format, va_list args) { |
718 | va_list args_copy; | 719 | char *error = vformat_str(format, args); |
719 | va_copy(args_copy, args); | ||
720 | size_t length = vsnprintf(NULL, 0, format, args_copy) + 1; | ||
721 | va_end(args_copy); | ||
722 | |||
723 | char *error = malloc(length); | ||
724 | if (!error) { | ||
725 | sway_log(SWAY_ERROR, "Failed to allocate libxkbcommon log message"); | ||
726 | return; | ||
727 | } | ||
728 | |||
729 | va_copy(args_copy, args); | ||
730 | vsnprintf(error, length, format, args_copy); | ||
731 | va_end(args_copy); | ||
732 | 720 | ||
733 | if (error[length - 2] == '\n') { | 721 | size_t len = strlen(error); |
734 | error[length - 2] = '\0'; | 722 | if (error[len - 1] == '\n') { |
723 | error[len - 1] = '\0'; | ||
735 | } | 724 | } |
736 | 725 | ||
737 | sway_log_importance_t importance = SWAY_DEBUG; | 726 | sway_log_importance_t importance = SWAY_DEBUG; |
@@ -752,7 +741,7 @@ static void handle_xkb_context_log(struct xkb_context *context, | |||
752 | 741 | ||
753 | struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic, | 742 | struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic, |
754 | char **error) { | 743 | char **error) { |
755 | struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); | 744 | struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_SECURE_GETENV); |
756 | if (!sway_assert(context, "cannot create XKB context")) { | 745 | if (!sway_assert(context, "cannot create XKB context")) { |
757 | return NULL; | 746 | return NULL; |
758 | } | 747 | } |
@@ -766,13 +755,8 @@ struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic, | |||
766 | if (!keymap_file) { | 755 | if (!keymap_file) { |
767 | 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); |
768 | if (error) { | 757 | if (error) { |
769 | size_t len = snprintf(NULL, 0, "cannot read xkb file %s: %s", | 758 | *error = format_str("cannot read xkb file %s: %s", |
770 | ic->xkb_file, strerror(errno)) + 1; | 759 | ic->xkb_file, strerror(errno)); |
771 | *error = malloc(len); | ||
772 | if (*error) { | ||
773 | snprintf(*error, len, "cannot read xkb_file %s: %s", | ||
774 | ic->xkb_file, strerror(errno)); | ||
775 | } | ||
776 | } | 760 | } |
777 | goto cleanup; | 761 | goto cleanup; |
778 | } | 762 | } |
@@ -1068,8 +1052,12 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) { | |||
1068 | } | 1052 | } |
1069 | } | 1053 | } |
1070 | 1054 | ||
1055 | // If the seat has no active keyboard, set this one | ||
1071 | struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat; | 1056 | struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat; |
1072 | wlr_seat_set_keyboard(seat, keyboard->wlr); | 1057 | struct wlr_keyboard *current_keyboard = seat->keyboard_state.keyboard; |
1058 | if (current_keyboard == NULL) { | ||
1059 | wlr_seat_set_keyboard(seat, keyboard->wlr); | ||
1060 | } | ||
1073 | 1061 | ||
1074 | wl_list_remove(&keyboard->keyboard_key.link); | 1062 | wl_list_remove(&keyboard->keyboard_key.link); |
1075 | wl_signal_add(&keyboard->wlr->events.key, &keyboard->keyboard_key); | 1063 | wl_signal_add(&keyboard->wlr->events.key, &keyboard->keyboard_key); |