]> git.mdlowis.com Git - proto/labwc.git/commitdiff
src/xdg.c: prevent interacting with un-initialized xdg toplevels after unmap
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Sun, 27 Jul 2025 13:55:43 +0000 (15:55 +0200)
committerHiroaki Yamamoto <hrak1529@gmail.com>
Sun, 27 Jul 2025 14:51:28 +0000 (23:51 +0900)
Fixes: #2937
Fixes: #2944
Originally-Reported-By: tranzystorekk via IRC
src/xdg.c

index 8b041361c0b7784d765ef555f15f0dca318f5bd6..5621e07eb68845699a2519fac2e3ca6b40ecaca1 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -488,6 +488,8 @@ xdg_toplevel_view_configure(struct view *view, struct wlr_box geo)
 {
        uint32_t serial = 0;
 
+       struct wlr_xdg_toplevel *toplevel = xdg_toplevel_from_view(view);
+
        /*
         * We do not need to send a configure request unless the size
         * changed (wayland has no notion of a global position). If the
@@ -496,8 +498,20 @@ xdg_toplevel_view_configure(struct view *view, struct wlr_box geo)
         */
        if (geo.width != view->pending.width
                        || geo.height != view->pending.height) {
-               serial = wlr_xdg_toplevel_set_size(xdg_toplevel_from_view(view),
-                       geo.width, geo.height);
+               if (toplevel->base->initialized) {
+                       serial = wlr_xdg_toplevel_set_size(toplevel, geo.width, geo.height);
+               } else {
+                       /*
+                        * This may happen, for example, when a panel resizes because a
+                        * foreign-toplevel has been destroyed. This would then trigger
+                        * a call to desktop_arrange_all_views() which in turn explicitly
+                        * also tries to configure unmapped surfaces. This is fine when
+                        * trying to resize surfaces before they are mapped but it will
+                        * also try to resize surfaces which have been unmapped but their
+                        * associated struct view has not been destroyed yet.
+                        */
+                       wlr_log(WLR_DEBUG, "Preventing configure of uninitialized surface");
+               }
        }
 
        view->pending = geo;
@@ -519,6 +533,10 @@ xdg_toplevel_view_close(struct view *view)
 static void
 xdg_toplevel_view_maximize(struct view *view, enum view_axis maximized)
 {
+       if (!xdg_toplevel_from_view(view)->base->initialized) {
+               wlr_log(WLR_DEBUG, "Prevented maximize notification for a non-intialized view");
+               return;
+       }
        uint32_t serial = wlr_xdg_toplevel_set_maximized(
                xdg_toplevel_from_view(view), maximized == VIEW_AXIS_BOTH);
        if (serial > 0) {
@@ -578,6 +596,10 @@ xdg_toplevel_view_append_children(struct view *self, struct wl_array *children)
 static void
 xdg_toplevel_view_set_activated(struct view *view, bool activated)
 {
+       if (!xdg_toplevel_from_view(view)->base->initialized) {
+               wlr_log(WLR_DEBUG, "Prevented activating a non-intialized view");
+               return;
+       }
        uint32_t serial = wlr_xdg_toplevel_set_activated(
                xdg_toplevel_from_view(view), activated);
        if (serial > 0) {
@@ -588,6 +610,10 @@ xdg_toplevel_view_set_activated(struct view *view, bool activated)
 static void
 xdg_toplevel_view_set_fullscreen(struct view *view, bool fullscreen)
 {
+       if (!xdg_toplevel_from_view(view)->base->initialized) {
+               wlr_log(WLR_DEBUG, "Prevented fullscreening a non-intialized view");
+               return;
+       }
        uint32_t serial = wlr_xdg_toplevel_set_fullscreen(
                xdg_toplevel_from_view(view), fullscreen);
        if (serial > 0) {
@@ -603,6 +629,11 @@ xdg_toplevel_view_notify_tiled(struct view *view)
                return;
        }
 
+       if (!xdg_toplevel_from_view(view)->base->initialized) {
+               wlr_log(WLR_DEBUG, "Prevented tiling notification for a non-intialized view");
+               return;
+       }
+
        enum wlr_edges edge = WLR_EDGE_NONE;
 
        bool want_edge = rc.snap_tiling_events_mode & LAB_TILING_EVENTS_EDGE;