diff --git a/include/meta-keymap-utils.h b/include/meta-keymap-utils.h
new file mode 100644
index 000000000..b7ebc69e5
--- /dev/null
+++ b/include/meta-keymap-utils.h
@@ -0,0 +1,28 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * Utilities for use with libxkbcommon
+ *
+ * Copyright 2020 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#ifndef META_KEYMAP_UTILS_H
+#define META_KEYMAP_UTILS_H
+
+#include
+
+struct xkb_context * meta_create_xkb_context(void);
+
+#endif /* META_KEYMAP_UTILS_H */
diff --git a/sway/config.c b/sway/config.c
index bcf8d56fc..5df3a7dff 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -31,13 +31,14 @@
#include "stringop.h"
#include "list.h"
#include "log.h"
+#include "meta-keymap-utils.h"
#include "util.h"
struct sway_config *config = NULL;
static struct xkb_state *keysym_translation_state_create(
struct xkb_rule_names rules) {
- struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
+ struct xkb_context *context = meta_create_xkb_context();
struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_names(
context,
&rules,
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c
index 541fc90d7..015d29632 100644
--- a/sway/input/keyboard.c
+++ b/sway/input/keyboard.c
@@ -15,6 +15,7 @@
#include "sway/input/seat.h"
#include "sway/ipc-server.h"
#include "log.h"
+#include "meta-keymap-utils.h"
static struct modifier_key {
char *name;
@@ -701,7 +702,7 @@ static void handle_xkb_context_log(struct xkb_context *context,
struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic,
char **error) {
- struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
+ struct xkb_context *context = meta_create_xkb_context();
if (!sway_assert(context, "cannot create XKB context")) {
return NULL;
}
diff --git a/sway/meson.build b/sway/meson.build
index 0db458362..87079f965 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -6,6 +6,7 @@ sway_sources = files(
'ipc-json.c',
'ipc-server.c',
'main.c',
+ 'meta-keymap-utils.c',
'server.c',
'swaynag.c',
'xdg_decoration.c',
diff --git a/sway/meta-keymap-utils.c b/sway/meta-keymap-utils.c
new file mode 100644
index 000000000..473b79bba
--- /dev/null
+++ b/sway/meta-keymap-utils.c
@@ -0,0 +1,53 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * Utilities for use with libxkbcommon
+ *
+ * Copyright 2019 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include "meta-keymap-utils.h"
+
+#include
+#include
+
+struct xkb_context *
+meta_create_xkb_context (void)
+{
+ struct xkb_context *ctx;
+ char xdg[PATH_MAX] = {0};
+ const char *env;
+
+ /*
+ * We can only append search paths in libxkbcommon, so we start with an
+ * emtpy set, then add the XDG dir, then add the default search paths.
+ */
+ ctx = xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES);
+
+ env = g_getenv("XDG_CONFIG_HOME");
+ if (env) {
+ g_snprintf(xdg, sizeof xdg, "%s/xkb", env);
+ }
+ else if ((env = g_getenv("HOME"))) {
+ g_snprintf(xdg, sizeof xdg, "%s/.config/xkb", env);
+ }
+
+ if (env) {
+ xkb_context_include_path_append(ctx, xdg);
+ }
+ xkb_context_include_path_append_default(ctx);
+
+ return ctx;
+}