]> git.mdlowis.com Git - proto/labwc.git/commitdiff
src/xwayland.c: Keep view->surface in sync
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Sat, 3 Sep 2022 23:32:12 +0000 (01:32 +0200)
committerConsolatis <35009135+Consolatis@users.noreply.github.com>
Tue, 6 Sep 2022 20:03:17 +0000 (22:03 +0200)
include/labwc.h
src/xwayland.c

index 20fe882bd792bfbd6bce29df74d860fa7dae2c09..b343fbba1719913739b6a608c33908b79208cfdf 100644 (file)
@@ -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;
index f700b8ffa0e2602170754437bc27e15a1ae23c16..1b51cd37b964bfd258d999bdf337362a7ef53177 100644 (file)
@@ -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) {