diff options
-rw-r--r-- | include/sway/input/keyboard.h | 3 | ||||
-rw-r--r-- | sway/commands/input.c | 15 | ||||
-rw-r--r-- | sway/input/keyboard.c | 47 |
3 files changed, 61 insertions, 4 deletions
diff --git a/include/sway/input/keyboard.h b/include/sway/input/keyboard.h index b8622053..90214af9 100644 --- a/include/sway/input/keyboard.h +++ b/include/sway/input/keyboard.h | |||
@@ -65,7 +65,8 @@ struct sway_keyboard { | |||
65 | struct sway_binding *repeat_binding; | 65 | struct sway_binding *repeat_binding; |
66 | }; | 66 | }; |
67 | 67 | ||
68 | struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic); | 68 | struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic, |
69 | char **error); | ||
69 | 70 | ||
70 | struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, | 71 | struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, |
71 | struct sway_seat_device *device); | 72 | struct sway_seat_device *device); |
diff --git a/sway/commands/input.c b/sway/commands/input.c index 0195082c..23a6644f 100644 --- a/sway/commands/input.c +++ b/sway/commands/input.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <strings.h> | 2 | #include <strings.h> |
3 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
4 | #include "sway/input/input-manager.h" | 4 | #include "sway/input/input-manager.h" |
5 | #include "sway/input/keyboard.h" | ||
5 | #include "log.h" | 6 | #include "log.h" |
6 | #include "stringop.h" | 7 | #include "stringop.h" |
7 | 8 | ||
@@ -86,6 +87,20 @@ struct cmd_results *cmd_input(int argc, char **argv) { | |||
86 | } | 87 | } |
87 | 88 | ||
88 | if (!res || res->status == CMD_SUCCESS) { | 89 | if (!res || res->status == CMD_SUCCESS) { |
90 | char *error = NULL; | ||
91 | struct xkb_keymap *keymap = sway_keyboard_compile_keymap( | ||
92 | config->handler_context.input_config, &error); | ||
93 | if (!keymap) { | ||
94 | if (res) { | ||
95 | free_cmd_results(res); | ||
96 | } | ||
97 | res = cmd_results_new(CMD_FAILURE, "Failed to compile keymap: %s", | ||
98 | error ? error : "(details unavailable)"); | ||
99 | free(error); | ||
100 | return res; | ||
101 | } | ||
102 | xkb_keymap_unref(keymap); | ||
103 | |||
89 | struct input_config *ic = | 104 | struct input_config *ic = |
90 | store_input_config(config->handler_context.input_config); | 105 | store_input_config(config->handler_context.input_config); |
91 | 106 | ||
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index dcfaa4fa..ef20a3cf 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c | |||
@@ -495,7 +495,45 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, | |||
495 | return keyboard; | 495 | return keyboard; |
496 | } | 496 | } |
497 | 497 | ||
498 | struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic) { | 498 | static void handle_xkb_context_log(struct xkb_context *context, |
499 | enum xkb_log_level level, const char *format, va_list args) { | ||
500 | va_list args_copy; | ||
501 | va_copy(args_copy, args); | ||
502 | size_t length = vsnprintf(NULL, 0, format, args_copy) + 1; | ||
503 | va_end(args_copy); | ||
504 | |||
505 | char *error = malloc(length); | ||
506 | if (!error) { | ||
507 | sway_log(SWAY_ERROR, "Failed to allocate libxkbcommon log message"); | ||
508 | return; | ||
509 | } | ||
510 | |||
511 | va_copy(args_copy, args); | ||
512 | vsnprintf(error, length, format, args_copy); | ||
513 | va_end(args_copy); | ||
514 | |||
515 | if (error[length - 2] == '\n') { | ||
516 | error[length - 2] = '\0'; | ||
517 | } | ||
518 | |||
519 | sway_log_importance_t importance = SWAY_DEBUG; | ||
520 | if (level <= XKB_LOG_LEVEL_ERROR) { // Critical and Error | ||
521 | importance = SWAY_ERROR; | ||
522 | } else if (level <= XKB_LOG_LEVEL_INFO) { // Warning and Info | ||
523 | importance = SWAY_INFO; | ||
524 | } | ||
525 | sway_log(importance, "[xkbcommon] %s", error); | ||
526 | |||
527 | char **data = xkb_context_get_user_data(context); | ||
528 | if (importance == SWAY_ERROR && data && !*data) { | ||
529 | *data = error; | ||
530 | } else { | ||
531 | free(error); | ||
532 | } | ||
533 | } | ||
534 | |||
535 | struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic, | ||
536 | char **error) { | ||
499 | struct xkb_rule_names rules = {0}; | 537 | struct xkb_rule_names rules = {0}; |
500 | if (ic) { | 538 | if (ic) { |
501 | input_config_fill_rule_names(ic, &rules); | 539 | input_config_fill_rule_names(ic, &rules); |
@@ -505,9 +543,12 @@ struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic) { | |||
505 | if (!sway_assert(context, "cannot create XKB context")) { | 543 | if (!sway_assert(context, "cannot create XKB context")) { |
506 | return NULL; | 544 | return NULL; |
507 | } | 545 | } |
546 | xkb_context_set_user_data(context, error); | ||
547 | xkb_context_set_log_fn(context, handle_xkb_context_log); | ||
508 | 548 | ||
509 | struct xkb_keymap *keymap = | 549 | struct xkb_keymap *keymap = |
510 | xkb_keymap_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); | 550 | xkb_keymap_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); |
551 | xkb_context_set_user_data(context, NULL); | ||
511 | xkb_context_unref(context); | 552 | xkb_context_unref(context); |
512 | return keymap; | 553 | return keymap; |
513 | } | 554 | } |
@@ -518,10 +559,10 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) { | |||
518 | struct wlr_input_device *wlr_device = | 559 | struct wlr_input_device *wlr_device = |
519 | keyboard->seat_device->input_device->wlr_device; | 560 | keyboard->seat_device->input_device->wlr_device; |
520 | 561 | ||
521 | struct xkb_keymap *keymap = sway_keyboard_compile_keymap(input_config); | 562 | struct xkb_keymap *keymap = sway_keyboard_compile_keymap(input_config, NULL); |
522 | if (!keymap) { | 563 | if (!keymap) { |
523 | sway_log(SWAY_ERROR, "Failed to compile keymap. Attempting defaults"); | 564 | sway_log(SWAY_ERROR, "Failed to compile keymap. Attempting defaults"); |
524 | keymap = sway_keyboard_compile_keymap(NULL); | 565 | keymap = sway_keyboard_compile_keymap(NULL, NULL); |
525 | if (!keymap) { | 566 | if (!keymap) { |
526 | sway_log(SWAY_ERROR, | 567 | sway_log(SWAY_ERROR, |
527 | "Failed to compile default keymap. Aborting configure"); | 568 | "Failed to compile default keymap. Aborting configure"); |