]> git.mdlowis.com Git - proto/labwc.git/commitdiff
Destroy xdg_popups when its parent is destroyed
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Wed, 18 Jun 2025 15:40:04 +0000 (17:40 +0200)
committerJohan Malm <johanmalm@users.noreply.github.com>
Wed, 18 Jun 2025 19:19:48 +0000 (20:19 +0100)
Fixes: #2845
include/layers.h
src/layers.c
src/xdg-popup.c
src/xdg.c

index 6f98d41dc339aafaf02106ea96f03ffe703fe144..21705fc39c64a12931ec57e4045ed4c5d2ca02a4 100644 (file)
@@ -9,6 +9,7 @@ struct output;
 struct seat;
 
 struct lab_layer_surface {
+       struct wlr_layer_surface_v1 *layer_surface;
        struct wlr_scene_layer_surface_v1 *scene_layer_surface;
        struct server *server;
        struct output *output;
index e52ea3c404eccda67e14f6662c72309c17cdf95a..c702b4dfbfc7472f68607e1d5787923c4966de1a 100644 (file)
@@ -314,6 +314,22 @@ handle_node_destroy(struct wl_listener *listener, void *data)
 {
        struct lab_layer_surface *layer =
                wl_container_of(listener, layer, node_destroy);
+
+       /*
+        * Important:
+        *
+        * We can no longer access layer->scene_layer_surface anymore
+        * because it has already been free'd by wlroots.
+        * Set it to NULL to run into a proper crash rather than accessing
+        * random free'd memory.
+        */
+       layer->scene_layer_surface = NULL;
+
+       struct wlr_xdg_popup *popup, *tmp;
+       wl_list_for_each_safe(popup, tmp, &layer->layer_surface->popups, link) {
+               wlr_xdg_popup_destroy(popup);
+       }
+
        /*
         * TODO: Determine if this layer is being used by an exclusive client.
         * If it is, try and find another layer owned by this client to pass
@@ -377,6 +393,12 @@ handle_popup_destroy(struct wl_listener *listener, void *data)
 {
        struct lab_layer_popup *popup =
                wl_container_of(listener, popup, destroy);
+
+       struct wlr_xdg_popup *_popup, *tmp;
+       wl_list_for_each_safe(_popup, tmp, &popup->wlr_popup->base->popups, link) {
+               wlr_xdg_popup_destroy(_popup);
+       }
+
        wl_list_remove(&popup->destroy.link);
        wl_list_remove(&popup->new_popup.link);
        wl_list_remove(&popup->reposition.link);
@@ -565,6 +587,7 @@ handle_new_layer_surface(struct wl_listener *listener, void *data)
        }
 
        struct lab_layer_surface *surface = znew(*surface);
+       surface->layer_surface = layer_surface;
 
        struct output *output = layer_surface->output->data;
        surface->output = output;
index f7e174ace1dba0e8fcc7975952f5caf17defdec1..d4daadd6f280e7b9e518dbcc6f6edbdf0df15011 100644 (file)
@@ -73,6 +73,12 @@ static void
 handle_destroy(struct wl_listener *listener, void *data)
 {
        struct xdg_popup *popup = wl_container_of(listener, popup, destroy);
+
+       struct wlr_xdg_popup *_popup, *tmp;
+       wl_list_for_each_safe(_popup, tmp, &popup->wlr_popup->base->popups, link) {
+               wlr_xdg_popup_destroy(_popup);
+       }
+
        wl_list_remove(&popup->destroy.link);
        wl_list_remove(&popup->new_popup.link);
        wl_list_remove(&popup->reposition.link);
index 5ff5ccb0142a2256770258427f72b228f52a7ab9..db64c92c688adaca223c8ee70580bebaa23d19e1 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -345,6 +345,11 @@ handle_destroy(struct wl_listener *listener, void *data)
        struct xdg_toplevel_view *xdg_toplevel_view =
                xdg_toplevel_view_from_view(view);
 
+       struct wlr_xdg_popup *popup, *tmp;
+       wl_list_for_each_safe(popup, tmp, &xdg_toplevel_view->xdg_surface->popups, link) {
+               wlr_xdg_popup_destroy(popup);
+       }
+
        xdg_toplevel_view->xdg_surface->data = NULL;
        xdg_toplevel_view->xdg_surface = NULL;