aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/keyboard.c
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2019-05-23 03:06:28 -0400
committerLibravatar Simon Ser <contact@emersion.fr>2019-06-09 20:13:22 +0300
commitbe2d2a299a6f854f0494f84169ef82ad5b31a917 (patch)
tree1afefdc25efda19c13f137a49a88346b763ac8d9 /sway/input/keyboard.c
parentUnhide cursor on cursor activity after touch (diff)
downloadsway-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.c47
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
498struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic) { 498static 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
535struct 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");