diff options
-rw-r--r-- | include/rootston/view.h | 3 | ||||
-rw-r--r-- | rootston/desktop.c | 29 | ||||
-rw-r--r-- | rootston/xwayland.c | 11 |
3 files changed, 32 insertions, 11 deletions
diff --git a/include/rootston/view.h b/include/rootston/view.h index 6c5e0573..d07f9ca2 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -123,6 +123,8 @@ struct roots_view_child { struct wl_listener commit; struct wl_listener new_subsurface; + + void (*destroy)(struct roots_view_child *child); }; struct roots_subsurface { @@ -151,6 +153,5 @@ void view_child_finish(struct roots_view_child *child); struct roots_subsurface *subsurface_create(struct roots_view *view, struct wlr_subsurface *wlr_subsurface); -void subsurface_destroy(struct roots_subsurface *subsurface); #endif diff --git a/rootston/desktop.c b/rootston/desktop.c index 191338a8..4bb1de5f 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -280,6 +280,7 @@ static void view_child_handle_new_subsurface(struct wl_listener *listener, void view_child_init(struct roots_view_child *child, struct roots_view *view, struct wlr_surface *wlr_surface) { + assert(child->destroy); child->view = view; child->wlr_surface = wlr_surface; child->commit.notify = view_child_handle_commit; @@ -289,11 +290,22 @@ void view_child_init(struct roots_view_child *child, struct roots_view *view, wl_list_insert(&view->children, &child->link); } +static void subsurface_destroy(struct roots_view_child *child) { + assert(child->destroy == subsurface_destroy); + struct roots_subsurface *subsurface = (struct roots_subsurface *)child; + if (subsurface == NULL) { + return; + } + wl_list_remove(&subsurface->destroy.link); + view_child_finish(&subsurface->view_child); + free(subsurface); +} + static void subsurface_handle_destroy(struct wl_listener *listener, void *data) { struct roots_subsurface *subsurface = wl_container_of(listener, subsurface, destroy); - subsurface_destroy(subsurface); + subsurface_destroy((struct roots_view_child *)subsurface); } struct roots_subsurface *subsurface_create(struct roots_view *view, @@ -304,27 +316,24 @@ struct roots_subsurface *subsurface_create(struct roots_view *view, return NULL; } subsurface->wlr_subsurface = wlr_subsurface; + subsurface->view_child.destroy = subsurface_destroy; view_child_init(&subsurface->view_child, view, wlr_subsurface->surface); subsurface->destroy.notify = subsurface_handle_destroy; wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy); return subsurface; } -void subsurface_destroy(struct roots_subsurface *subsurface) { - if (subsurface == NULL) { - return; - } - wl_list_remove(&subsurface->destroy.link); - view_child_finish(&subsurface->view_child); - free(subsurface); -} - void view_finish(struct roots_view *view) { view_damage_whole(view); wl_signal_emit(&view->events.destroy, view); wl_list_remove(&view->new_subsurface.link); + struct roots_view_child *child, *tmp; + wl_list_for_each_safe(child, tmp, &view->children, link) { + child->destroy(child); + } + if (view->fullscreen_output) { view->fullscreen_output->fullscreen_view = NULL; } diff --git a/rootston/xwayland.c b/rootston/xwayland.c index 6f9912e6..24315e1a 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -236,6 +236,12 @@ static void handle_map_notify(struct wl_listener *listener, void *data) { view->y = xsurface->y; wl_list_insert(&desktop->views, &view->link); + struct wlr_subsurface *subsurface; + wl_list_for_each(subsurface, &view->wlr_surface->subsurface_list, + parent_link) { + subsurface_create(view, subsurface); + } + view_damage_whole(view); roots_surface->surface_commit.notify = handle_surface_commit; @@ -252,6 +258,11 @@ static void handle_unmap_notify(struct wl_listener *listener, void *data) { view_damage_whole(view); + struct roots_view_child *child, *tmp; + wl_list_for_each_safe(child, tmp, &view->children, link) { + child->destroy(child); + } + view->wlr_surface = NULL; wl_list_remove(&view->link); } |