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.c72
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
19static struct modifier_key { 22static 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
716static void handle_xkb_context_log(struct xkb_context *context, 717static 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
753struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic, 742struct 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);