|  |  |  | @ -488,24 +488,6 @@ void view_for_each_popup_surface(struct sway_view *view, | 
			
		
	
		
			
				
					|  |  |  |  | 		view->impl->for_each_popup_surface(view, iterator, user_data); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void view_subsurface_create(struct sway_view *view, | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_subsurface *subsurface); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void view_init_subsurfaces(struct sway_view *view, | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_surface *surface); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void view_child_init_subsurfaces(struct sway_view_child *view_child, | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_surface *surface); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void view_handle_surface_new_subsurface(struct wl_listener *listener, | 
			
		
	
		
			
				
					|  |  |  |  | 		void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_view *view = | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_container_of(listener, view, surface_new_subsurface); | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_subsurface *subsurface = data; | 
			
		
	
		
			
				
					|  |  |  |  | 	view_subsurface_create(view, subsurface); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static bool view_has_executed_criteria(struct sway_view *view, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct criteria *criteria) { | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int i = 0; i < view->executed_criteria->length; ++i) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -826,11 +808,6 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	ipc_event_window(view->container, "new"); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	view_init_subsurfaces(view, wlr_surface); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_signal_add(&wlr_surface->events.new_subsurface, | 
			
		
	
		
			
				
					|  |  |  |  | 			&view->surface_new_subsurface); | 
			
		
	
		
			
				
					|  |  |  |  | 	view->surface_new_subsurface.notify = view_handle_surface_new_subsurface; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (decoration) { | 
			
		
	
		
			
				
					|  |  |  |  | 		view_update_csd_from_client(view, decoration); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
	
		
			
				
					|  |  |  | @ -897,8 +874,6 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, | 
			
		
	
		
			
				
					|  |  |  |  | void view_unmap(struct sway_view *view) { | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_signal_emit_mutable(&view->events.unmap, view); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&view->surface_new_subsurface.link); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	view->executed_criteria->length = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (view->urgent_timer) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -962,253 +937,6 @@ void view_center_surface(struct sway_view *view) { | 
			
		
	
		
			
				
					|  |  |  |  | 			(con->current.content_height - view->geometry.height) / 2); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static const struct sway_view_child_impl subsurface_impl; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void subsurface_get_view_coords(struct sway_view_child *child, | 
			
		
	
		
			
				
					|  |  |  |  | 		int *sx, int *sy) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_surface *surface = child->surface; | 
			
		
	
		
			
				
					|  |  |  |  | 	if (child->parent && child->parent->impl && | 
			
		
	
		
			
				
					|  |  |  |  | 			child->parent->impl->get_view_coords) { | 
			
		
	
		
			
				
					|  |  |  |  | 		child->parent->impl->get_view_coords(child->parent, sx, sy); | 
			
		
	
		
			
				
					|  |  |  |  | 	} else { | 
			
		
	
		
			
				
					|  |  |  |  | 		*sx = *sy = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_subsurface *subsurface = | 
			
		
	
		
			
				
					|  |  |  |  | 		wlr_subsurface_try_from_wlr_surface(surface); | 
			
		
	
		
			
				
					|  |  |  |  | 	*sx += subsurface->current.x; | 
			
		
	
		
			
				
					|  |  |  |  | 	*sy += subsurface->current.y; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void subsurface_destroy(struct sway_view_child *child) { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!sway_assert(child->impl == &subsurface_impl, | 
			
		
	
		
			
				
					|  |  |  |  | 			"Expected a subsurface")) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_subsurface *subsurface = (struct sway_subsurface *)child; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&subsurface->destroy.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	free(subsurface); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static const struct sway_view_child_impl subsurface_impl = { | 
			
		
	
		
			
				
					|  |  |  |  | 	.get_view_coords = subsurface_get_view_coords, | 
			
		
	
		
			
				
					|  |  |  |  | 	.destroy = subsurface_destroy, | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void subsurface_handle_destroy(struct wl_listener *listener, | 
			
		
	
		
			
				
					|  |  |  |  | 		void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_subsurface *subsurface = | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_container_of(listener, subsurface, destroy); | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_view_child *child = &subsurface->child; | 
			
		
	
		
			
				
					|  |  |  |  | 	view_child_destroy(child); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void view_child_damage(struct sway_view_child *child, bool whole); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void view_subsurface_create(struct sway_view *view, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_subsurface *wlr_subsurface) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_subsurface *subsurface = | 
			
		
	
		
			
				
					|  |  |  |  | 		calloc(1, sizeof(struct sway_subsurface)); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (subsurface == NULL) { | 
			
		
	
		
			
				
					|  |  |  |  | 		sway_log(SWAY_ERROR, "Allocation failed"); | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	view_child_init(&subsurface->child, &subsurface_impl, view, | 
			
		
	
		
			
				
					|  |  |  |  | 		wlr_subsurface->surface); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy); | 
			
		
	
		
			
				
					|  |  |  |  | 	subsurface->destroy.notify = subsurface_handle_destroy; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	subsurface->child.mapped = true; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	view_child_damage(&subsurface->child, true); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void view_child_subsurface_create(struct sway_view_child *child, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_subsurface *wlr_subsurface) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_subsurface *subsurface = | 
			
		
	
		
			
				
					|  |  |  |  | 		calloc(1, sizeof(struct sway_subsurface)); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (subsurface == NULL) { | 
			
		
	
		
			
				
					|  |  |  |  | 		sway_log(SWAY_ERROR, "Allocation failed"); | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	subsurface->child.parent = child; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_insert(&child->children, &subsurface->child.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	view_child_init(&subsurface->child, &subsurface_impl, child->view, | 
			
		
	
		
			
				
					|  |  |  |  | 		wlr_subsurface->surface); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy); | 
			
		
	
		
			
				
					|  |  |  |  | 	subsurface->destroy.notify = subsurface_handle_destroy; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	subsurface->child.mapped = true; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	view_child_damage(&subsurface->child, true); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static bool view_child_is_mapped(struct sway_view_child *child) { | 
			
		
	
		
			
				
					|  |  |  |  | 	while (child) { | 
			
		
	
		
			
				
					|  |  |  |  | 		if (!child->mapped) { | 
			
		
	
		
			
				
					|  |  |  |  | 			return false; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		child = child->parent; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return true; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void view_child_damage(struct sway_view_child *child, bool whole) { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!child || !view_child_is_mapped(child) || !child->view || !child->view->container) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	int sx, sy; | 
			
		
	
		
			
				
					|  |  |  |  | 	child->impl->get_view_coords(child, &sx, &sy); | 
			
		
	
		
			
				
					|  |  |  |  | 	desktop_damage_surface(child->surface, | 
			
		
	
		
			
				
					|  |  |  |  | 			child->view->container->pending.content_x - | 
			
		
	
		
			
				
					|  |  |  |  | 				child->view->geometry.x + sx, | 
			
		
	
		
			
				
					|  |  |  |  | 			child->view->container->pending.content_y - | 
			
		
	
		
			
				
					|  |  |  |  | 				child->view->geometry.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); | 
			
		
	
		
			
				
					|  |  |  |  | 	view_child_damage(child, false); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void view_child_handle_surface_new_subsurface( | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_view_child *child = | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_container_of(listener, child, surface_new_subsurface); | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_subsurface *subsurface = data; | 
			
		
	
		
			
				
					|  |  |  |  | 	view_child_subsurface_create(child, subsurface); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void view_child_handle_surface_destroy(struct wl_listener *listener, | 
			
		
	
		
			
				
					|  |  |  |  | 		void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_view_child *child = | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_container_of(listener, child, surface_destroy); | 
			
		
	
		
			
				
					|  |  |  |  | 	view_child_destroy(child); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void view_init_subsurfaces(struct sway_view *view, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_surface *surface) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_subsurface *subsurface; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(subsurface, &surface->current.subsurfaces_below, | 
			
		
	
		
			
				
					|  |  |  |  | 			current.link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		view_subsurface_create(view, subsurface); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(subsurface, &surface->current.subsurfaces_above, | 
			
		
	
		
			
				
					|  |  |  |  | 			current.link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		view_subsurface_create(view, subsurface); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void view_child_init_subsurfaces(struct sway_view_child *view_child, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_surface *surface) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_subsurface *subsurface; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(subsurface, &surface->current.subsurfaces_below, | 
			
		
	
		
			
				
					|  |  |  |  | 			current.link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		view_child_subsurface_create(view_child, subsurface); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(subsurface, &surface->current.subsurfaces_above, | 
			
		
	
		
			
				
					|  |  |  |  | 			current.link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		view_child_subsurface_create(view_child, subsurface); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 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); | 
			
		
	
		
			
				
					|  |  |  |  | 	child->mapped = true; | 
			
		
	
		
			
				
					|  |  |  |  | 	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); | 
			
		
	
		
			
				
					|  |  |  |  | 	child->mapped = false; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void view_child_handle_view_unmap(struct wl_listener *listener, | 
			
		
	
		
			
				
					|  |  |  |  | 		void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_view_child *child = | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_container_of(listener, child, view_unmap); | 
			
		
	
		
			
				
					|  |  |  |  | 	view_child_damage(child, true); | 
			
		
	
		
			
				
					|  |  |  |  | 	child->mapped = false; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void view_child_init(struct sway_view_child *child, | 
			
		
	
		
			
				
					|  |  |  |  | 		const struct sway_view_child_impl *impl, struct sway_view *view, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_surface *surface) { | 
			
		
	
		
			
				
					|  |  |  |  | 	child->impl = impl; | 
			
		
	
		
			
				
					|  |  |  |  | 	child->view = view; | 
			
		
	
		
			
				
					|  |  |  |  | 	child->surface = surface; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_init(&child->children); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_signal_add(&surface->events.commit, &child->surface_commit); | 
			
		
	
		
			
				
					|  |  |  |  | 	child->surface_commit.notify = view_child_handle_surface_commit; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_signal_add(&surface->events.new_subsurface, | 
			
		
	
		
			
				
					|  |  |  |  | 		&child->surface_new_subsurface); | 
			
		
	
		
			
				
					|  |  |  |  | 	child->surface_new_subsurface.notify = | 
			
		
	
		
			
				
					|  |  |  |  | 		view_child_handle_surface_new_subsurface; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_signal_add(&surface->events.destroy, &child->surface_destroy); | 
			
		
	
		
			
				
					|  |  |  |  | 	child->surface_destroy.notify = view_child_handle_surface_destroy; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// Not all child views have a map/unmap event
 | 
			
		
	
		
			
				
					|  |  |  |  | 	child->surface_map.notify = view_child_handle_surface_map; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_init(&child->surface_map.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	child->surface_unmap.notify = view_child_handle_surface_unmap; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_init(&child->surface_unmap.link); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_signal_add(&view->events.unmap, &child->view_unmap); | 
			
		
	
		
			
				
					|  |  |  |  | 	child->view_unmap.notify = view_child_handle_view_unmap; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_container *container = child->view->container; | 
			
		
	
		
			
				
					|  |  |  |  | 	if (container != NULL) { | 
			
		
	
		
			
				
					|  |  |  |  | 		struct sway_workspace *workspace = container->pending.workspace; | 
			
		
	
		
			
				
					|  |  |  |  | 		if (workspace) { | 
			
		
	
		
			
				
					|  |  |  |  | 			surface_enter_output(child->surface, workspace->output); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	view_child_init_subsurfaces(child, surface); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void view_child_destroy(struct sway_view_child *child) { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (view_child_is_mapped(child) && child->view->container != NULL) { | 
			
		
	
		
			
				
					|  |  |  |  | 		view_child_damage(child, true); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (child->parent != NULL) { | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_list_remove(&child->link); | 
			
		
	
		
			
				
					|  |  |  |  | 		child->parent = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_view_child *subchild, *tmpchild; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each_safe(subchild, tmpchild, &child->children, link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_list_remove(&subchild->link); | 
			
		
	
		
			
				
					|  |  |  |  | 		subchild->parent = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 		// The subchild lost its parent link, so it cannot see that the parent
 | 
			
		
	
		
			
				
					|  |  |  |  | 		// is unmapped. Unmap it directly.
 | 
			
		
	
		
			
				
					|  |  |  |  | 		subchild->mapped = false; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&child->surface_commit.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&child->surface_destroy.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&child->surface_map.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&child->surface_unmap.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&child->view_unmap.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&child->surface_new_subsurface.link); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (child->impl && child->impl->destroy) { | 
			
		
	
		
			
				
					|  |  |  |  | 		child->impl->destroy(child); | 
			
		
	
		
			
				
					|  |  |  |  | 	} else { | 
			
		
	
		
			
				
					|  |  |  |  | 		free(child); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | struct sway_view *view_from_wlr_surface(struct wlr_surface *wlr_surface) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_xdg_surface *xdg_surface; | 
			
		
	
		
			
				
					|  |  |  |  | 	if ((xdg_surface = wlr_xdg_surface_try_from_wlr_surface(wlr_surface))) { | 
			
		
	
	
		
			
				
					|  |  |  | 
 |