aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sway/input/keyboard.h3
-rw-r--r--sway/commands/input.c15
-rw-r--r--sway/input/keyboard.c47
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 {
struct sway_binding *repeat_binding;
};
-struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic);
+struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic,
+ char **error);
struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
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 @@
#include <strings.h>
#include "sway/commands.h"
#include "sway/input/input-manager.h"
+#include "sway/input/keyboard.h"
#include "log.h"
#include "stringop.h"
@@ -86,6 +87,20 @@ struct cmd_results *cmd_input(int argc, char **argv) {
}
if (!res || res->status == CMD_SUCCESS) {
+ char *error = NULL;
+ struct xkb_keymap *keymap = sway_keyboard_compile_keymap(
+ config->handler_context.input_config, &error);
+ if (!keymap) {
+ if (res) {
+ free_cmd_results(res);
+ }
+ res = cmd_results_new(CMD_FAILURE, "Failed to compile keymap: %s",
+ error ? error : "(details unavailable)");
+ free(error);
+ return res;
+ }
+ xkb_keymap_unref(keymap);
+
struct input_config *ic =
store_input_config(config->handler_context.input_config);
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,
return keyboard;
}
-struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic) {
+static void handle_xkb_context_log(struct xkb_context *context,
+ enum xkb_log_level level, const char *format, va_list args) {
+ va_list args_copy;
+ va_copy(args_copy, args);
+ size_t length = vsnprintf(NULL, 0, format, args_copy) + 1;
+ va_end(args_copy);
+
+ char *error = malloc(length);
+ if (!error) {
+ sway_log(SWAY_ERROR, "Failed to allocate libxkbcommon log message");
+ return;
+ }
+
+ va_copy(args_copy, args);
+ vsnprintf(error, length, format, args_copy);
+ va_end(args_copy);
+
+ if (error[length - 2] == '\n') {
+ error[length - 2] = '\0';
+ }
+
+ sway_log_importance_t importance = SWAY_DEBUG;
+ if (level <= XKB_LOG_LEVEL_ERROR) { // Critical and Error
+ importance = SWAY_ERROR;
+ } else if (level <= XKB_LOG_LEVEL_INFO) { // Warning and Info
+ importance = SWAY_INFO;
+ }
+ sway_log(importance, "[xkbcommon] %s", error);
+
+ char **data = xkb_context_get_user_data(context);
+ if (importance == SWAY_ERROR && data && !*data) {
+ *data = error;
+ } else {
+ free(error);
+ }
+}
+
+struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic,
+ char **error) {
struct xkb_rule_names rules = {0};
if (ic) {
input_config_fill_rule_names(ic, &rules);
@@ -505,9 +543,12 @@ struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic) {
if (!sway_assert(context, "cannot create XKB context")) {
return NULL;
}
+ xkb_context_set_user_data(context, error);
+ xkb_context_set_log_fn(context, handle_xkb_context_log);
struct xkb_keymap *keymap =
xkb_keymap_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
+ xkb_context_set_user_data(context, NULL);
xkb_context_unref(context);
return keymap;
}
@@ -518,10 +559,10 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
struct wlr_input_device *wlr_device =
keyboard->seat_device->input_device->wlr_device;
- struct xkb_keymap *keymap = sway_keyboard_compile_keymap(input_config);
+ struct xkb_keymap *keymap = sway_keyboard_compile_keymap(input_config, NULL);
if (!keymap) {
sway_log(SWAY_ERROR, "Failed to compile keymap. Attempting defaults");
- keymap = sway_keyboard_compile_keymap(NULL);
+ keymap = sway_keyboard_compile_keymap(NULL, NULL);
if (!keymap) {
sway_log(SWAY_ERROR,
"Failed to compile default keymap. Aborting configure");