Fix fallback when there are two config blocks for a keyboard

This commit is contained in:
emersion 2017-10-26 22:38:03 +02:00
parent 4e5d23daa9
commit c0c4816b13
No known key found for this signature in database
GPG key ID: 0FDE7BE0E88F5E48
4 changed files with 49 additions and 33 deletions

View file

@ -73,7 +73,7 @@ struct device_config *config_get_device(struct roots_config *config,
/** /**
* Get configuration for the keyboard. If the keyboard is not configured, * Get configuration for the keyboard. If the keyboard is not configured,
* returns NULL. * returns NULL. A NULL device returns the default config for keyboards.
*/ */
struct keyboard_config *config_get_keyboard(struct roots_config *config, struct keyboard_config *config_get_keyboard(struct roots_config *config,
struct wlr_input_device *device); struct wlr_input_device *device);

View file

@ -417,14 +417,12 @@ struct device_config *config_get_device(struct roots_config *config,
struct keyboard_config *config_get_keyboard(struct roots_config *config, struct keyboard_config *config_get_keyboard(struct roots_config *config,
struct wlr_input_device *device) { struct wlr_input_device *device) {
struct keyboard_config *kc; struct keyboard_config *kc;
struct keyboard_config *default_kc = NULL;
wl_list_for_each(kc, &config->keyboards, link) { wl_list_for_each(kc, &config->keyboards, link) {
if (strcmp(kc->name, "*") == 0) { if ((device != NULL && strcmp(kc->name, device->name) == 0) ||
default_kc = kc; (device == NULL && strcmp(kc->name, "*") == 0)) {
} else if (strcmp(kc->name, device->name) == 0) {
return kc; return kc;
} }
} }
return default_kc; return NULL;
} }

View file

@ -217,10 +217,12 @@ static void handle_cursor_axis(struct wl_listener *listener, void *data) {
static bool is_meta_pressed(struct roots_input *input, static bool is_meta_pressed(struct roots_input *input,
struct wlr_input_device *device) { struct wlr_input_device *device) {
struct keyboard_config *config = config_get_keyboard(input->server->config,
device);
uint32_t meta_key = 0; uint32_t meta_key = 0;
if (config != NULL) { struct keyboard_config *config;
if ((config = config_get_keyboard(input->server->config, device))) {
meta_key = config->meta_key;
} else if (!meta_key && (config = config_get_keyboard(input->server->config,
NULL))) {
meta_key = config->meta_key; meta_key = config->meta_key;
} }
if (meta_key == 0) { if (meta_key == 0) {

View file

@ -125,6 +125,28 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) {
} }
} }
static void keyboard_config_merge(struct keyboard_config *config,
struct keyboard_config *fallback) {
if (fallback == NULL) {
return;
}
if (config->rules == NULL) {
config->rules = fallback->rules;
}
if (config->model == NULL) {
config->model = fallback->model;
}
if (config->layout == NULL) {
config->layout = fallback->layout;
}
if (config->variant == NULL) {
config->variant = fallback->variant;
}
if (config->options == NULL) {
config->options = fallback->options;
}
}
void keyboard_add(struct wlr_input_device *device, struct roots_input *input) { void keyboard_add(struct wlr_input_device *device, struct roots_input *input) {
struct roots_keyboard *keyboard = calloc(sizeof(struct roots_keyboard), 1); struct roots_keyboard *keyboard = calloc(sizeof(struct roots_keyboard), 1);
if (keyboard == NULL) { if (keyboard == NULL) {
@ -137,33 +159,27 @@ void keyboard_add(struct wlr_input_device *device, struct roots_input *input) {
wl_signal_add(&device->keyboard->events.key, &keyboard->key); wl_signal_add(&device->keyboard->events.key, &keyboard->key);
wl_list_insert(&input->keyboards, &keyboard->link); wl_list_insert(&input->keyboards, &keyboard->link);
struct keyboard_config *config = config_get_keyboard(input->config, struct keyboard_config config;
device); memset(&config, 0, sizeof(config));
keyboard_config_merge(&config, config_get_keyboard(input->config, device));
keyboard_config_merge(&config, config_get_keyboard(input->config, NULL));
struct keyboard_config env_config = {
.rules = getenv("XKB_DEFAULT_RULES"),
.model = getenv("XKB_DEFAULT_MODEL"),
.layout = getenv("XKB_DEFAULT_LAYOUT"),
.variant = getenv("XKB_DEFAULT_VARIANT"),
.options = getenv("XKB_DEFAULT_OPTIONS"),
};
keyboard_config_merge(&config, &env_config);
struct xkb_rule_names rules; struct xkb_rule_names rules;
memset(&rules, 0, sizeof(rules)); memset(&rules, 0, sizeof(rules));
if (config != NULL) { rules.rules = config.rules;
rules.rules = config->rules; rules.model = config.model;
rules.model = config->model; rules.layout = config.layout;
rules.layout = config->layout; rules.variant = config.variant;
rules.variant = config->variant; rules.options = config.options;
rules.options = config->options;
}
if (rules.rules == NULL) {
rules.rules = getenv("XKB_DEFAULT_RULES");
}
if (rules.model == NULL) {
rules.model = getenv("XKB_DEFAULT_MODEL");
}
if (rules.layout == NULL) {
rules.layout = getenv("XKB_DEFAULT_LAYOUT");
}
if (rules.variant == NULL) {
rules.variant = getenv("XKB_DEFAULT_VARIANT");
}
if (rules.options == NULL) {
rules.options = getenv("XKB_DEFAULT_OPTIONS");
}
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (context == NULL) { if (context == NULL) {
wlr_log(L_ERROR, "Cannot create XKB context"); wlr_log(L_ERROR, "Cannot create XKB context");