References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3871 Adds option to allow tearing per output, as well as an option to force enable or disable tearing for a specific application using a window rule. Only works with fullscreen applications.master
							parent
							
								
									b881c2e84c
								
							
						
					
					
						commit
						9a1c411abd
					
				| @ -0,0 +1,24 @@ | ||||
| #include <sway/commands.h> | ||||
| #include "sway/config.h" | ||||
| #include "sway/tree/view.h" | ||||
| #include "util.h" | ||||
| 
 | ||||
| struct cmd_results *cmd_allow_tearing(int argc, char **argv) { | ||||
| 	struct cmd_results *error = NULL; | ||||
| 	if ((error = checkarg(argc, "allow_tearing", EXPECTED_AT_LEAST, 1))) { | ||||
| 		return error; | ||||
| 	} | ||||
| 
 | ||||
| 	struct sway_container *container = config->handler_context.container; | ||||
| 	if (!container || !container->view) { | ||||
| 		return cmd_results_new(CMD_INVALID, "Tearing can only be allowed on views"); | ||||
| 	} | ||||
| 
 | ||||
| 	bool wants_tearing = parse_boolean(argv[0], true); | ||||
| 
 | ||||
| 	struct sway_view *view = container->view; | ||||
| 	view->tearing_mode = wants_tearing ? TEARING_OVERRIDE_TRUE : | ||||
| 		TEARING_OVERRIDE_FALSE; | ||||
| 
 | ||||
| 	return cmd_results_new(CMD_SUCCESS, NULL); | ||||
| } | ||||
| @ -0,0 +1,23 @@ | ||||
| #include "sway/commands.h" | ||||
| #include "sway/config.h" | ||||
| #include "util.h" | ||||
| 
 | ||||
| struct cmd_results *output_cmd_allow_tearing(int argc, char **argv) { | ||||
| 	if (!config->handler_context.output_config) { | ||||
| 		return cmd_results_new(CMD_FAILURE, "Missing output config"); | ||||
| 	} | ||||
| 	if (argc == 0) { | ||||
| 		return cmd_results_new(CMD_INVALID, "Missing allow_tearing argument"); | ||||
| 	} | ||||
| 
 | ||||
| 	if (parse_boolean(argv[0], | ||||
| 			(config->handler_context.output_config->allow_tearing == 1))) { | ||||
| 		config->handler_context.output_config->allow_tearing = 1; | ||||
| 	} else { | ||||
| 		config->handler_context.output_config->allow_tearing = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	config->handler_context.leftovers.argc = argc - 1; | ||||
| 	config->handler_context.leftovers.argv = argv + 1; | ||||
| 	return NULL; | ||||
| } | ||||
| @ -0,0 +1,62 @@ | ||||
| #include <wayland-server-core.h> | ||||
| #include <wlr/types/wlr_tearing_control_v1.h> | ||||
| #include "sway/server.h" | ||||
| #include "sway/tree/view.h" | ||||
| #include "sway/output.h" | ||||
| #include "log.h" | ||||
| 
 | ||||
| struct sway_tearing_controller { | ||||
| 	struct wlr_tearing_control_v1 *tearing_control; | ||||
| 	struct wl_listener set_hint; | ||||
| 	struct wl_listener destroy; | ||||
| 
 | ||||
| 	struct wl_list link; // sway_server::tearing_controllers
 | ||||
| }; | ||||
| 
 | ||||
| static void handle_tearing_controller_set_hint(struct wl_listener *listener, | ||||
| 		void *data) { | ||||
| 	struct sway_tearing_controller *controller = | ||||
| 		wl_container_of(listener, controller, set_hint); | ||||
| 	 | ||||
| 	struct sway_view *view = view_from_wlr_surface( | ||||
| 		controller->tearing_control->surface); | ||||
| 	if (view) { | ||||
| 		view->tearing_hint = controller->tearing_control->current; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void handle_tearing_controller_destroy(struct wl_listener *listener,  | ||||
| 		void *data) { | ||||
| 	struct sway_tearing_controller *controller =  | ||||
| 		wl_container_of(listener, controller, destroy); | ||||
| 	wl_list_remove(&controller->link); | ||||
| 	free(controller); | ||||
| } | ||||
| 
 | ||||
| void handle_new_tearing_hint(struct wl_listener *listener,  | ||||
| 		void *data) { | ||||
| 	struct sway_server *server =  | ||||
| 		wl_container_of(listener, server, tearing_control_new_object); | ||||
| 	struct wlr_tearing_control_v1 *tearing_control = data; | ||||
| 	 | ||||
| 	enum wp_tearing_control_v1_presentation_hint hint =  | ||||
| 		wlr_tearing_control_manager_v1_surface_hint_from_surface( | ||||
| 			server->tearing_control_v1, tearing_control->surface); | ||||
| 	sway_log(SWAY_DEBUG, "New presentation hint %d received for surface %p", | ||||
| 		hint, tearing_control->surface); | ||||
| 
 | ||||
| 	struct sway_tearing_controller *controller =  | ||||
| 		calloc(1, sizeof(struct sway_tearing_controller)); | ||||
| 	if (!controller) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	controller->tearing_control = tearing_control; | ||||
| 	controller->set_hint.notify = handle_tearing_controller_set_hint; | ||||
| 	wl_signal_add(&tearing_control->events.set_hint, &controller->set_hint); | ||||
| 	controller->destroy.notify = handle_tearing_controller_destroy; | ||||
| 	wl_signal_add(&tearing_control->events.destroy, &controller->destroy); | ||||
| 	wl_list_init(&controller->link); | ||||
| 
 | ||||
| 	wl_list_insert(&server->tearing_controllers, &controller->link); | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue