diff --git a/include/sway/commands.h b/include/sway/commands.h index ce74e1ed..61950d0d 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -195,6 +195,11 @@ sway_cmd input_cmd_natural_scroll; sway_cmd input_cmd_pointer_accel; sway_cmd input_cmd_scroll_method; sway_cmd input_cmd_tap; +sway_cmd input_cmd_xkb_layout; +sway_cmd input_cmd_xkb_model; +sway_cmd input_cmd_xkb_options; +sway_cmd input_cmd_xkb_rules; +sway_cmd input_cmd_xkb_variant; sway_cmd seat_cmd_attach; diff --git a/include/sway/config.h b/include/sway/config.h index 5df5d61e..9bfda259 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -67,6 +67,12 @@ struct input_config { int send_events; int tap; + char *xkb_layout; + char *xkb_model; + char *xkb_options; + char *xkb_rules; + char *xkb_variant; + bool capturable; struct wlr_box region; }; diff --git a/sway/commands.c b/sway/commands.c index e003e06d..b8948fb7 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -154,6 +154,11 @@ static struct cmd_handler input_handlers[] = { { "pointer_accel", input_cmd_pointer_accel }, { "scroll_method", input_cmd_scroll_method }, { "tap", input_cmd_tap }, + { "xkb_layout", input_cmd_xkb_layout }, + { "xkb_model", input_cmd_xkb_model }, + { "xkb_options", input_cmd_xkb_options }, + { "xkb_rules", input_cmd_xkb_rules }, + { "xkb_variant", input_cmd_xkb_variant }, }; // must be in order for the bsearch diff --git a/sway/commands/input/xkb_layout.c b/sway/commands/input/xkb_layout.c new file mode 100644 index 00000000..9a9ce044 --- /dev/null +++ b/sway/commands/input/xkb_layout.c @@ -0,0 +1,24 @@ +#define _XOPEN_SOURCE 700 +#include "sway/commands.h" +#include "sway/input/input-manager.h" +#include "log.h" + +struct cmd_results *input_cmd_xkb_layout(int argc, char **argv) { + sway_log(L_DEBUG, "xkb layout for device: %s", current_input_config->identifier); + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "xkb_layout", EXPECTED_AT_LEAST, 1))) { + return error; + } + if (!current_input_config) { + return cmd_results_new(CMD_FAILURE, "xkb_layout", "No input device defined."); + } + struct input_config *new_config = + new_input_config(current_input_config->identifier); + + new_config->xkb_layout = strdup(argv[0]); + + sway_log(L_DEBUG, "apply-xkb_layout for device: %s", + current_input_config->identifier); + input_cmd_apply(new_config); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} diff --git a/sway/commands/input/xkb_model.c b/sway/commands/input/xkb_model.c new file mode 100644 index 00000000..14a50ffb --- /dev/null +++ b/sway/commands/input/xkb_model.c @@ -0,0 +1,24 @@ +#define _XOPEN_SOURCE 700 +#include "sway/commands.h" +#include "sway/input/input-manager.h" +#include "log.h" + +struct cmd_results *input_cmd_xkb_model(int argc, char **argv) { + sway_log(L_DEBUG, "xkb model for device: %s", current_input_config->identifier); + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "xkb_model", EXPECTED_AT_LEAST, 1))) { + return error; + } + if (!current_input_config) { + return cmd_results_new(CMD_FAILURE, "xkb_model", "No input device defined."); + } + struct input_config *new_config = + new_input_config(current_input_config->identifier); + + new_config->xkb_model = strdup(argv[0]); + + sway_log(L_DEBUG, "apply-xkb_model for device: %s", + current_input_config->identifier); + input_cmd_apply(new_config); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} diff --git a/sway/commands/input/xkb_options.c b/sway/commands/input/xkb_options.c new file mode 100644 index 00000000..67eb5342 --- /dev/null +++ b/sway/commands/input/xkb_options.c @@ -0,0 +1,24 @@ +#define _XOPEN_SOURCE 700 +#include "sway/commands.h" +#include "sway/input/input-manager.h" +#include "log.h" + +struct cmd_results *input_cmd_xkb_options(int argc, char **argv) { + sway_log(L_DEBUG, "xkb options for device: %s", current_input_config->identifier); + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "xkb_options", EXPECTED_AT_LEAST, 1))) { + return error; + } + if (!current_input_config) { + return cmd_results_new(CMD_FAILURE, "xkb_options", "No input device defined."); + } + struct input_config *new_config = + new_input_config(current_input_config->identifier); + + new_config->xkb_options = strdup(argv[0]); + + sway_log(L_DEBUG, "apply-xkb_options for device: %s", + current_input_config->identifier); + input_cmd_apply(new_config); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} diff --git a/sway/commands/input/xkb_rules.c b/sway/commands/input/xkb_rules.c new file mode 100644 index 00000000..3eda0bdd --- /dev/null +++ b/sway/commands/input/xkb_rules.c @@ -0,0 +1,24 @@ +#define _XOPEN_SOURCE 700 +#include "sway/commands.h" +#include "sway/input/input-manager.h" +#include "log.h" + +struct cmd_results *input_cmd_xkb_rules(int argc, char **argv) { + sway_log(L_DEBUG, "xkb rules for device: %s", current_input_config->identifier); + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "xkb_rules", EXPECTED_AT_LEAST, 1))) { + return error; + } + if (!current_input_config) { + return cmd_results_new(CMD_FAILURE, "xkb_rules", "No input device defined."); + } + struct input_config *new_config = + new_input_config(current_input_config->identifier); + + new_config->xkb_rules = strdup(argv[0]); + + sway_log(L_DEBUG, "apply-xkb_rules for device: %s", + current_input_config->identifier); + input_cmd_apply(new_config); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} diff --git a/sway/commands/input/xkb_variant.c b/sway/commands/input/xkb_variant.c new file mode 100644 index 00000000..c7f93ad4 --- /dev/null +++ b/sway/commands/input/xkb_variant.c @@ -0,0 +1,24 @@ +#define _XOPEN_SOURCE 700 +#include "sway/commands.h" +#include "sway/input/input-manager.h" +#include "log.h" + +struct cmd_results *input_cmd_xkb_variant(int argc, char **argv) { + sway_log(L_DEBUG, "xkb variant for device: %s", current_input_config->identifier); + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "xkb_variant", EXPECTED_AT_LEAST, 1))) { + return error; + } + if (!current_input_config) { + return cmd_results_new(CMD_FAILURE, "xkb_variant", "No input device defined."); + } + struct input_config *new_config = + new_input_config(current_input_config->identifier); + + new_config->xkb_variant = strdup(argv[0]); + + sway_log(L_DEBUG, "apply-xkb_variant for device: %s", + current_input_config->identifier); + input_cmd_apply(new_config); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} diff --git a/sway/config.c b/sway/config.c index 52633ad8..4e34aa8c 100644 --- a/sway/config.c +++ b/sway/config.c @@ -292,6 +292,26 @@ void merge_input_config(struct input_config *dst, struct input_config *src) { if (src->tap != INT_MIN) { dst->tap = src->tap; } + if (src->xkb_layout) { + free(dst->xkb_layout); + dst->xkb_layout = strdup(src->xkb_layout); + } + if (src->xkb_model) { + free(dst->xkb_model); + dst->xkb_model = strdup(src->xkb_model); + } + if (src->xkb_options) { + free(dst->xkb_options); + dst->xkb_options = strdup(src->xkb_options); + } + if (src->xkb_rules) { + free(dst->xkb_rules); + dst->xkb_rules = strdup(src->xkb_rules); + } + if (src->xkb_variant) { + free(dst->xkb_variant); + dst->xkb_variant = strdup(src->xkb_variant); + } } void free_input_config(struct input_config *ic) { diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 53db3270..2ab0206a 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c @@ -1,5 +1,6 @@ #include "sway/input/seat.h" #include "sway/input/keyboard.h" +#include "sway/input/input-manager.h" #include "log.h" static void handle_keyboard_key(struct wl_listener *listener, void *data) { @@ -47,17 +48,44 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, void sway_keyboard_configure(struct sway_keyboard *keyboard) { struct xkb_rule_names rules; memset(&rules, 0, sizeof(rules)); - rules.rules = getenv("XKB_DEFAULT_RULES"); - rules.model = getenv("XKB_DEFAULT_MODEL"); - rules.layout = getenv("XKB_DEFAULT_LAYOUT"); - rules.variant = getenv("XKB_DEFAULT_VARIANT"); - rules.options = getenv("XKB_DEFAULT_OPTIONS"); + struct input_config *input_config = + keyboard->seat_device->input_device->config; + + if (input_config && input_config->xkb_layout) { + rules.layout = input_config->xkb_layout; + } else { + rules.layout = getenv("XKB_DEFAULT_LAYOUT"); + } + if (input_config && input_config->xkb_model) { + rules.model = input_config->xkb_model; + } else { + rules.model = getenv("XKB_DEFAULT_MODEL"); + } + + if (input_config && input_config->xkb_options) { + rules.options = input_config->xkb_options; + } else { + rules.options = getenv("XKB_DEFAULT_OPTIONS"); + } + + if (input_config && input_config->xkb_rules) { + rules.rules = input_config->xkb_rules; + } else { + rules.rules = getenv("XKB_DEFAULT_RULES"); + } + + if (input_config && input_config->xkb_variant) { + rules.variant = input_config->xkb_variant; + } else { + rules.variant = getenv("XKB_DEFAULT_VARIANT"); + } struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (!sway_assert(context, "cannot create XKB context")) { return; } + xkb_keymap_unref(keyboard->keymap); keyboard->keymap = xkb_keymap_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); wlr_keyboard_set_keymap(keyboard->seat_device->input_device->wlr_device->keyboard, keyboard->keymap); diff --git a/sway/main.c b/sway/main.c index 363f4d96..25032aa0 100644 --- a/sway/main.c +++ b/sway/main.c @@ -158,6 +158,7 @@ static void log_distro() { } static void log_kernel() { + return; FILE *f = popen("uname -a", "r"); if (!f) { sway_log(L_INFO, "Unable to determine kernel version"); diff --git a/sway/meson.build b/sway/meson.build index ad8160eb..c81e1c2c 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -24,6 +24,11 @@ sway_sources = files( 'commands/input/pointer_accel.c', 'commands/input/scroll_method.c', 'commands/input/tap.c', + 'commands/input/xkb_layout.c', + 'commands/input/xkb_model.c', + 'commands/input/xkb_options.c', + 'commands/input/xkb_rules.c', + 'commands/input/xkb_variant.c', 'config.c', 'ipc-json.c', 'ipc-server.c',