diff --git a/include/labwc.h b/include/labwc.h index 20fe882b..b343fbba 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -349,6 +349,7 @@ struct view { struct wl_listener map; struct wl_listener unmap; struct wl_listener destroy; + struct wl_listener surface_destroy; struct wl_listener commit; struct wl_listener request_move; struct wl_listener request_resize; diff --git a/src/xwayland.c b/src/xwayland.c index f700b8ff..1b51cd37 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -95,6 +95,18 @@ handle_unmap(struct wl_listener *listener, void *data) } } +static void +handle_surface_destroy(struct wl_listener *listener, void *data) +{ + struct view *view = wl_container_of(listener, view, surface_destroy); + assert(view->type == LAB_XWAYLAND_VIEW); + struct wlr_surface *surface = data; + assert(surface == view->surface); + + view->surface = NULL; + wl_list_remove(&view->surface_destroy.link); +} + static void handle_destroy(struct wl_listener *listener, void *data) { @@ -102,6 +114,15 @@ handle_destroy(struct wl_listener *listener, void *data) assert(view->type == LAB_XWAYLAND_VIEW); /* Reset XWayland specific surface for good measure */ + if (view->surface) { + /* + * We got the destroy signal from + * wlr_xwayland_surface before the + * destroy signal from wlr_surface. + */ + wl_list_remove(&view->surface_destroy.link); + } + view->surface = NULL; view->xwayland_surface = NULL; /* Remove XWayland specific handlers */ @@ -337,7 +358,16 @@ map(struct view *view) } if (view->surface != view->xwayland_surface->surface) { + if (view->surface) { + wl_list_remove(&view->surface_destroy.link); + } view->surface = view->xwayland_surface->surface; + + /* Required to set the surface to NULL when destroyed by the client */ + view->surface_destroy.notify = handle_surface_destroy; + wl_signal_add(&view->surface->events.destroy, &view->surface_destroy); + + /* Will be free'd automatically once the surface is being destroyed */ struct wlr_scene_tree *tree = wlr_scene_subsurface_tree_create( view->scene_tree, view->surface); if (!tree) {