|  |  | @ -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"); | 
			
		
	
	
		
		
			
				
					|  |  | 
 |