mirror of
				https://github.com/swaywm/sway.git
				synced 2025-10-29 05:40:18 -04:00 
			
		
		
		
	Merge pull request #2772 from RyanDwyer/improve-popup-damage
Only damage popups when popups have damage
This commit is contained in:
		
						commit
						4bebee620f
					
				
					 4 changed files with 80 additions and 9 deletions
				
			
		|  | @ -208,6 +208,7 @@ struct sway_xwayland_unmanaged { | |||
| struct sway_view_child; | ||||
| 
 | ||||
| struct sway_view_child_impl { | ||||
| 	void (*get_root_coords)(struct sway_view_child *child, int *sx, int *sy); | ||||
| 	void (*destroy)(struct sway_view_child *child); | ||||
| }; | ||||
| 
 | ||||
|  | @ -222,6 +223,8 @@ struct sway_view_child { | |||
| 
 | ||||
| 	struct wl_listener surface_commit; | ||||
| 	struct wl_listener surface_new_subsurface; | ||||
| 	struct wl_listener surface_map; | ||||
| 	struct wl_listener surface_unmap; | ||||
| 	struct wl_listener surface_destroy; | ||||
| 	struct wl_listener view_unmap; | ||||
| }; | ||||
|  |  | |||
|  | @ -20,6 +20,17 @@ | |||
| 
 | ||||
| static const struct sway_view_child_impl popup_impl; | ||||
| 
 | ||||
| static void popup_get_root_coords(struct sway_view_child *child, | ||||
| 		int *root_sx, int *root_sy) { | ||||
| 	struct sway_xdg_popup *popup = (struct sway_xdg_popup *)child; | ||||
| 	struct wlr_xdg_surface *surface = popup->wlr_xdg_surface; | ||||
| 
 | ||||
| 	wlr_xdg_popup_get_toplevel_coords(surface->popup, | ||||
| 		-surface->geometry.x + surface->popup->geometry.x, | ||||
| 		-surface->geometry.y + surface->popup->geometry.y, | ||||
| 		root_sx, root_sy); | ||||
| } | ||||
| 
 | ||||
| static void popup_destroy(struct sway_view_child *child) { | ||||
| 	if (!sway_assert(child->impl == &popup_impl, | ||||
| 			"Expected an xdg_shell popup")) { | ||||
|  | @ -32,6 +43,7 @@ static void popup_destroy(struct sway_view_child *child) { | |||
| } | ||||
| 
 | ||||
| static const struct sway_view_child_impl popup_impl = { | ||||
| 	.get_root_coords = popup_get_root_coords, | ||||
| 	.destroy = popup_destroy, | ||||
| }; | ||||
| 
 | ||||
|  | @ -85,6 +97,9 @@ static struct sway_xdg_popup *popup_create( | |||
| 	wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); | ||||
| 	popup->destroy.notify = popup_handle_destroy; | ||||
| 
 | ||||
| 	wl_signal_add(&xdg_surface->events.map, &popup->child.surface_map); | ||||
| 	wl_signal_add(&xdg_surface->events.unmap, &popup->child.surface_unmap); | ||||
| 
 | ||||
| 	popup_unconstrain(popup); | ||||
| 
 | ||||
| 	return popup; | ||||
|  |  | |||
|  | @ -19,6 +19,17 @@ | |||
| 
 | ||||
| static const struct sway_view_child_impl popup_impl; | ||||
| 
 | ||||
| static void popup_get_root_coords(struct sway_view_child *child, | ||||
| 		int *root_sx, int *root_sy) { | ||||
| 	struct sway_xdg_popup_v6 *popup = (struct sway_xdg_popup_v6 *)child; | ||||
| 	struct wlr_xdg_surface_v6 *surface = popup->wlr_xdg_surface_v6; | ||||
| 
 | ||||
| 	wlr_xdg_popup_v6_get_toplevel_coords(surface->popup, | ||||
| 		-surface->geometry.x + surface->popup->geometry.x, | ||||
| 		-surface->geometry.y + surface->popup->geometry.y, | ||||
| 		root_sx, root_sy); | ||||
| } | ||||
| 
 | ||||
| static void popup_destroy(struct sway_view_child *child) { | ||||
| 	if (!sway_assert(child->impl == &popup_impl, | ||||
| 			"Expected an xdg_shell_v6 popup")) { | ||||
|  | @ -31,6 +42,7 @@ static void popup_destroy(struct sway_view_child *child) { | |||
| } | ||||
| 
 | ||||
| static const struct sway_view_child_impl popup_impl = { | ||||
| 	.get_root_coords = popup_get_root_coords, | ||||
| 	.destroy = popup_destroy, | ||||
| }; | ||||
| 
 | ||||
|  | @ -84,6 +96,9 @@ static struct sway_xdg_popup_v6 *popup_create( | |||
| 	wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); | ||||
| 	popup->destroy.notify = popup_handle_destroy; | ||||
| 
 | ||||
| 	wl_signal_add(&xdg_surface->events.map, &popup->child.surface_map); | ||||
| 	wl_signal_add(&xdg_surface->events.unmap, &popup->child.surface_unmap); | ||||
| 
 | ||||
| 	popup_unconstrain(popup); | ||||
| 
 | ||||
| 	return popup; | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ | |||
| #include "log.h" | ||||
| #include "sway/criteria.h" | ||||
| #include "sway/commands.h" | ||||
| #include "sway/desktop.h" | ||||
| #include "sway/desktop/transaction.h" | ||||
| #include "sway/input/cursor.h" | ||||
| #include "sway/ipc-server.h" | ||||
|  | @ -639,6 +640,25 @@ void view_update_size(struct sway_view *view, int width, int height) { | |||
| 	container_set_geometry_from_floating_view(view->container); | ||||
| } | ||||
| 
 | ||||
| static void subsurface_get_root_coords(struct sway_view_child *child, | ||||
| 		int *root_sx, int *root_sy) { | ||||
| 	struct wlr_surface *surface = child->surface; | ||||
| 	*root_sx = -child->view->geometry.x; | ||||
| 	*root_sy = -child->view->geometry.y; | ||||
| 
 | ||||
| 	while (surface && wlr_surface_is_subsurface(surface)) { | ||||
| 		struct wlr_subsurface *subsurface = | ||||
| 			wlr_subsurface_from_wlr_surface(surface); | ||||
| 		*root_sx += subsurface->current.x; | ||||
| 		*root_sy += subsurface->current.y; | ||||
| 		surface = subsurface->parent; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static const struct sway_view_child_impl subsurface_impl = { | ||||
| 	.get_root_coords = subsurface_get_root_coords, | ||||
| }; | ||||
| 
 | ||||
| static void view_subsurface_create(struct sway_view *view, | ||||
| 		struct wlr_subsurface *subsurface) { | ||||
| 	struct sway_view_child *child = calloc(1, sizeof(struct sway_view_child)); | ||||
|  | @ -646,15 +666,21 @@ static void view_subsurface_create(struct sway_view *view, | |||
| 		wlr_log(WLR_ERROR, "Allocation failed"); | ||||
| 		return; | ||||
| 	} | ||||
| 	view_child_init(child, NULL, view, subsurface->surface); | ||||
| 	view_child_init(child, &subsurface_impl, view, subsurface->surface); | ||||
| } | ||||
| 
 | ||||
| static void view_child_damage(struct sway_view_child *child, bool whole) { | ||||
| 	int sx, sy; | ||||
| 	child->impl->get_root_coords(child, &sx, &sy); | ||||
| 	desktop_damage_surface(child->surface, | ||||
| 			child->view->x + sx, child->view->y + sy, whole); | ||||
| } | ||||
| 
 | ||||
| static void view_child_handle_surface_commit(struct wl_listener *listener, | ||||
| 		void *data) { | ||||
| 	struct sway_view_child *child = | ||||
| 		wl_container_of(listener, child, surface_commit); | ||||
| 	// TODO: only accumulate damage from the child
 | ||||
| 	view_damage_from(child->view); | ||||
| 	view_child_damage(child, false); | ||||
| } | ||||
| 
 | ||||
| static void view_child_handle_surface_new_subsurface( | ||||
|  | @ -687,6 +713,20 @@ static void view_init_subsurfaces(struct sway_view *view, | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void view_child_handle_surface_map(struct wl_listener *listener, | ||||
| 		void *data) { | ||||
| 	struct sway_view_child *child = | ||||
| 		wl_container_of(listener, child, surface_map); | ||||
| 	view_child_damage(child, true); | ||||
| } | ||||
| 
 | ||||
| static void view_child_handle_surface_unmap(struct wl_listener *listener, | ||||
| 		void *data) { | ||||
| 	struct sway_view_child *child = | ||||
| 		wl_container_of(listener, child, surface_unmap); | ||||
| 	view_child_damage(child, true); | ||||
| } | ||||
| 
 | ||||
| void view_child_init(struct sway_view_child *child, | ||||
| 		const struct sway_view_child_impl *impl, struct sway_view *view, | ||||
| 		struct wlr_surface *surface) { | ||||
|  | @ -702,6 +742,10 @@ void view_child_init(struct sway_view_child *child, | |||
| 		view_child_handle_surface_new_subsurface; | ||||
| 	wl_signal_add(&surface->events.destroy, &child->surface_destroy); | ||||
| 	child->surface_destroy.notify = view_child_handle_surface_destroy; | ||||
| 
 | ||||
| 	child->surface_map.notify = view_child_handle_surface_map; | ||||
| 	child->surface_unmap.notify = view_child_handle_surface_unmap; | ||||
| 
 | ||||
| 	wl_signal_add(&view->events.unmap, &child->view_unmap); | ||||
| 	child->view_unmap.notify = view_child_handle_view_unmap; | ||||
| 
 | ||||
|  | @ -709,15 +753,9 @@ void view_child_init(struct sway_view_child *child, | |||
| 	wlr_surface_send_enter(child->surface, output->wlr_output); | ||||
| 
 | ||||
| 	view_init_subsurfaces(child->view, surface); | ||||
| 
 | ||||
| 	// TODO: only damage the whole child
 | ||||
| 	container_damage_whole(child->view->container); | ||||
| } | ||||
| 
 | ||||
| void view_child_destroy(struct sway_view_child *child) { | ||||
| 	// TODO: only damage the whole child
 | ||||
| 	container_damage_whole(child->view->container); | ||||
| 
 | ||||
| 	wl_list_remove(&child->surface_commit.link); | ||||
| 	wl_list_remove(&child->surface_destroy.link); | ||||
| 	wl_list_remove(&child->view_unmap.link); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Drew DeVault
						Drew DeVault