mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Fix fallback when there are two config blocks for a keyboard
This commit is contained in:
		
							parent
							
								
									4e5d23daa9
								
							
						
					
					
						commit
						c0c4816b13
					
				
					 4 changed files with 49 additions and 33 deletions
				
			
		| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue