diff --git a/include/sway/config.h b/include/sway/config.h index db507296b..a0a98fb6f 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -577,6 +577,8 @@ void merge_input_config(struct input_config *dst, struct input_config *src); struct input_config *store_input_config(struct input_config *ic); +struct xkb_rule_names input_config_get_rule_names(struct input_config *ic); + void free_input_config(struct input_config *ic); int seat_name_cmp(const void *item, const void *data); @@ -655,7 +657,7 @@ void config_update_font_height(bool recalculate); */ bool translate_binding(struct sway_binding *binding); -void translate_keysyms(const char *layout); +void translate_keysyms(struct input_config *input_config); void binding_add_translated(struct sway_binding *binding, list_t *bindings); diff --git a/sway/commands/input.c b/sway/commands/input.c index 2de07de6e..0195082c3 100644 --- a/sway/commands/input.c +++ b/sway/commands/input.c @@ -48,7 +48,7 @@ static void retranslate_keysyms(struct input_config *input_config) { if (ic->xkb_layout) { // this is the first config with xkb_layout if (ic->identifier == input_config->identifier) { - translate_keysyms(ic->xkb_layout); + translate_keysyms(ic); } return; diff --git a/sway/config.c b/sway/config.c index 8579e8653..fed01eb43 100644 --- a/sway/config.c +++ b/sway/config.c @@ -34,16 +34,14 @@ struct sway_config *config = NULL; static struct xkb_state *keysym_translation_state_create( - const char *layout) { - struct xkb_rule_names rules = { - .layout = layout, - }; - + struct xkb_rule_names rules) { + struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_names( - xkb_context_new(XKB_CONTEXT_NO_FLAGS), + context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); + xkb_context_unref(context); return xkb_state_new(xkb_keymap); } @@ -339,8 +337,9 @@ static void config_defaults(struct sway_config *config) { if (!(config->ipc_policies = create_list())) goto cleanup; // The keysym to keycode translation + struct xkb_rule_names rules = {}; config->keysym_translation_state = - keysym_translation_state_create(NULL); + keysym_translation_state_create(rules); return; cleanup: @@ -987,9 +986,12 @@ static void translate_binding_list(list_t *bindings, list_t *bindsyms, } } -void translate_keysyms(const char *layout) { +void translate_keysyms(struct input_config *input_config) { keysym_translation_state_destroy(config->keysym_translation_state); - config->keysym_translation_state = keysym_translation_state_create(layout); + + struct xkb_rule_names rules = input_config_get_rule_names(input_config); + config->keysym_translation_state = + keysym_translation_state_create(rules); for (int i = 0; i < config->modes->length; ++i) { struct sway_mode *mode = config->modes->items[i]; @@ -1007,5 +1009,6 @@ void translate_keysyms(const char *layout) { mode->keycode_bindings = bindcodes; } - sway_log(SWAY_DEBUG, "Translated keysyms for layout %s", layout); + sway_log(SWAY_DEBUG, "Translated keysyms using config for device '%s'", + input_config->identifier); } diff --git a/sway/config/input.c b/sway/config/input.c index aa5814313..595aa029a 100644 --- a/sway/config/input.c +++ b/sway/config/input.c @@ -212,6 +212,18 @@ struct input_config *store_input_config(struct input_config *ic) { return ic; } +struct xkb_rule_names input_config_get_rule_names(struct input_config *ic) { + struct xkb_rule_names rules = { + .layout = ic->xkb_layout, + .model = ic->xkb_model, + .options = ic->xkb_options, + .rules = ic->xkb_rules, + .variant = ic->xkb_variant, + }; + + return rules; +} + void free_input_config(struct input_config *ic) { if (!ic) { return; diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 5a9651852..04b8b0ce8 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c @@ -477,39 +477,31 @@ 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)); struct input_config *input_config = input_device_get_config(keyboard->seat_device->input_device); struct wlr_input_device *wlr_device = keyboard->seat_device->input_device->wlr_device; - if (input_config && input_config->xkb_layout) { - rules.layout = input_config->xkb_layout; + struct xkb_rule_names rules; + if (input_config) { + rules = input_config_get_rule_names(input_config); } else { + memset(&rules, 0, sizeof(rules)); + } + + if (!rules.layout) { rules.layout = getenv("XKB_DEFAULT_LAYOUT"); } - if (input_config && input_config->xkb_model) { - rules.model = input_config->xkb_model; - } else { + if (!rules.model) { rules.model = getenv("XKB_DEFAULT_MODEL"); } - - if (input_config && input_config->xkb_options) { - rules.options = input_config->xkb_options; - } else { + if (!rules.options) { rules.options = getenv("XKB_DEFAULT_OPTIONS"); } - - if (input_config && input_config->xkb_rules) { - rules.rules = input_config->xkb_rules; - } else { + if (!rules.rules) { rules.rules = getenv("XKB_DEFAULT_RULES"); } - - if (input_config && input_config->xkb_variant) { - rules.variant = input_config->xkb_variant; - } else { + if (!rules.variant) { rules.variant = getenv("XKB_DEFAULT_VARIANT"); }