diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2019-05-23 03:06:28 -0400 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2019-06-09 20:13:22 +0300 |
commit | be2d2a299a6f854f0494f84169ef82ad5b31a917 (patch) | |
tree | 1afefdc25efda19c13f137a49a88346b763ac8d9 /sway/input/keyboard.c | |
parent | Unhide cursor on cursor activity after touch (diff) | |
download | sway-be2d2a299a6f854f0494f84169ef82ad5b31a917.tar.gz sway-be2d2a299a6f854f0494f84169ef82ad5b31a917.tar.zst sway-be2d2a299a6f854f0494f84169ef82ad5b31a917.zip |
commands/input: perform basic keymap validation
Before the delta input config is stored, this attempts to compile a
keymap with it. If the keymap fails to compile, then the first line of
the xkbcommon log entry will be included with a `CMD_FAILURE`, the
entire xkbcommon log entry will be included in the sway error log, and
the delta will not be stored.
This only handles basic issues such as a layouts not existing. This
will NOT catch more complex issues such as when a variant does
exist, but not for the given layout (ex: `azerty` is a valid variant,
but the `us` layout does not have a `azerty` variant).
Diffstat (limited to 'sway/input/keyboard.c')
-rw-r--r-- | sway/input/keyboard.c | 47 |
1 files changed, 44 insertions, 3 deletions
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"); |