|  |  |  | @ -578,6 +578,30 @@ static void update_textures(struct sway_container *con, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	container_update_marks_textures(con); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void update_output_manager_config(struct sway_server *server) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_output_configuration_v1 *config = | 
			
		
	
		
			
				
					|  |  |  |  | 		wlr_output_configuration_v1_create(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_output *output; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(output, &root->all_outputs, link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		if (output == root->noop_output) { | 
			
		
	
		
			
				
					|  |  |  |  | 			continue; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_output_configuration_head_v1 *config_head = | 
			
		
	
		
			
				
					|  |  |  |  | 			wlr_output_configuration_head_v1_create(config, output->wlr_output); | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_box *output_box = wlr_output_layout_get_box( | 
			
		
	
		
			
				
					|  |  |  |  | 			root->output_layout, output->wlr_output); | 
			
		
	
		
			
				
					|  |  |  |  | 		// We mark the output enabled even if it is switched off by DPMS
 | 
			
		
	
		
			
				
					|  |  |  |  | 		config_head->state.enabled = output->enabled; | 
			
		
	
		
			
				
					|  |  |  |  | 		if (output_box) { | 
			
		
	
		
			
				
					|  |  |  |  | 			config_head->state.x = output_box->x; | 
			
		
	
		
			
				
					|  |  |  |  | 			config_head->state.y = output_box->y; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wlr_output_manager_v1_set_configuration(server->output_manager_v1, config); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void handle_scale(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_output *output = wl_container_of(listener, output, scale); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!output->enabled || !output->configured) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -651,4 +675,73 @@ void handle_new_output(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	transaction_commit_dirty(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	update_output_manager_config(server); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void handle_output_manager_apply(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_server *server = | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_container_of(listener, server, output_manager_apply); | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_output_configuration_v1 *config = data; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_output_configuration_head_v1 *config_head; | 
			
		
	
		
			
				
					|  |  |  |  | 	// First disable outputs we need to disable
 | 
			
		
	
		
			
				
					|  |  |  |  | 	bool ok = true; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(config_head, &config->heads, link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_output *wlr_output = config_head->state.output; | 
			
		
	
		
			
				
					|  |  |  |  | 		struct sway_output *output = wlr_output->data; | 
			
		
	
		
			
				
					|  |  |  |  | 		if (!output->enabled || config_head->state.enabled) { | 
			
		
	
		
			
				
					|  |  |  |  | 			continue; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		struct output_config *oc = new_output_config(output->wlr_output->name); | 
			
		
	
		
			
				
					|  |  |  |  | 		oc->enabled = false; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		oc = store_output_config(oc); | 
			
		
	
		
			
				
					|  |  |  |  | 		ok &= apply_output_config(oc, output); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// Then enable outputs that need to
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(config_head, &config->heads, link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_output *wlr_output = config_head->state.output; | 
			
		
	
		
			
				
					|  |  |  |  | 		struct sway_output *output = wlr_output->data; | 
			
		
	
		
			
				
					|  |  |  |  | 		if (!config_head->state.enabled) { | 
			
		
	
		
			
				
					|  |  |  |  | 			continue; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		struct output_config *oc = new_output_config(output->wlr_output->name); | 
			
		
	
		
			
				
					|  |  |  |  | 		oc->enabled = true; | 
			
		
	
		
			
				
					|  |  |  |  | 		if (config_head->state.mode != NULL) { | 
			
		
	
		
			
				
					|  |  |  |  | 			struct wlr_output_mode *mode = config_head->state.mode; | 
			
		
	
		
			
				
					|  |  |  |  | 			oc->width = mode->width; | 
			
		
	
		
			
				
					|  |  |  |  | 			oc->height = mode->height; | 
			
		
	
		
			
				
					|  |  |  |  | 			oc->refresh_rate = mode->refresh; | 
			
		
	
		
			
				
					|  |  |  |  | 		} else { | 
			
		
	
		
			
				
					|  |  |  |  | 			oc->width = config_head->state.custom_mode.width; | 
			
		
	
		
			
				
					|  |  |  |  | 			oc->height = config_head->state.custom_mode.height; | 
			
		
	
		
			
				
					|  |  |  |  | 			oc->refresh_rate = config_head->state.custom_mode.refresh; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		oc->x = config_head->state.x; | 
			
		
	
		
			
				
					|  |  |  |  | 		oc->y = config_head->state.y; | 
			
		
	
		
			
				
					|  |  |  |  | 		oc->transform = config_head->state.transform; | 
			
		
	
		
			
				
					|  |  |  |  | 		oc->scale = config_head->state.scale; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		oc = store_output_config(oc); | 
			
		
	
		
			
				
					|  |  |  |  | 		ok &= apply_output_config(oc, output); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (ok) { | 
			
		
	
		
			
				
					|  |  |  |  | 		wlr_output_configuration_v1_send_succeeded(config); | 
			
		
	
		
			
				
					|  |  |  |  | 	} else { | 
			
		
	
		
			
				
					|  |  |  |  | 		wlr_output_configuration_v1_send_failed(config); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	wlr_output_configuration_v1_destroy(config); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	update_output_manager_config(server); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void handle_output_manager_test(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_output_configuration_v1 *config = data; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// TODO: implement test-only mode
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wlr_output_configuration_v1_send_succeeded(config); | 
			
		
	
		
			
				
					|  |  |  |  | 	wlr_output_configuration_v1_destroy(config); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
	
		
			
				
					|  |  |  | 
 |