From 2d169624247feffc20d02f0cb89a198b290ed7fd Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Tue, 27 Oct 2026 23:07:24 +0100 Subject: [PATCH] pass the object to LISTEN_STATIC handlers wlroots 482d6e53 stopped passing the surface to the idle inhibitor destroy and surface commit signals, which made destroyidleinhibitor() and commitpopup() dereference NULL. Store the object in the listener instead. --- dwl.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/dwl.c b/dwl.c index a813938..4589b8f 100644 --- a/dwl.c +++ b/dwl.c @@ -83,7 +83,7 @@ #define VISIBLEON(C, M) ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags])) #define TAGMASK ((1u << TAGCOUNT) - 1) #define LISTEN(E, L, H) wl_signal_add((E), ((L)->notify = (H), (L))) -#define LISTEN_STATIC(E, H) do { struct wl_listener *_l = ecalloc(1, sizeof(*_l)); _l->notify = (H); wl_signal_add((E), _l); } while (0) +#define LISTEN_STATIC(E, H, D) do { StaticListener *_l = ecalloc(1, sizeof(*_l)); _l->listener.notify = (H); _l->data = (D); wl_signal_add((E), &_l->listener); } while (0) /* enums */ enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ @@ -263,6 +263,12 @@ typedef struct { struct wl_listener destroy; } SessionLock; +typedef struct { + /* Must keep this field first */ + struct wl_listener listener; + void *data; +} StaticListener; + /* function declarations */ static void applybounds(Client *c, struct wlr_box *bbox); static void applygeom(Client *c); @@ -1048,8 +1054,8 @@ commitnotify(struct wl_listener *listener, void *data) void commitpopup(struct wl_listener *listener, void *data) { - struct wlr_surface *surface = data; - struct wlr_xdg_popup *popup = wlr_xdg_popup_try_from_wlr_surface(surface); + StaticListener *sl = wl_container_of(listener, sl, listener); + struct wlr_xdg_popup *popup = sl->data; LayerSurface *l = NULL; Client *c = NULL; struct wlr_box box; @@ -1092,7 +1098,7 @@ void createidleinhibitor(struct wl_listener *listener, void *data) { struct wlr_idle_inhibitor_v1 *idle_inhibitor = data; - LISTEN_STATIC(&idle_inhibitor->events.destroy, destroyidleinhibitor); + LISTEN_STATIC(&idle_inhibitor->events.destroy, destroyidleinhibitor, idle_inhibitor); checkidleinhibitor(NULL); } @@ -1366,7 +1372,7 @@ createpopup(struct wl_listener *listener, void *data) /* This event is raised when a client (either xdg-shell or layer-shell) * creates a new popup. */ struct wlr_xdg_popup *popup = data; - LISTEN_STATIC(&popup->base->surface->events.commit, commitpopup); + LISTEN_STATIC(&popup->base->surface->events.commit, commitpopup, popup); } void @@ -1429,9 +1435,10 @@ destroydragicon(struct wl_listener *listener, void *data) void destroyidleinhibitor(struct wl_listener *listener, void *data) { - /* `data` is the wlr_surface of the idle inhibitor being destroyed, - * at this point the idle inhibitor is still in the list of the manager */ - checkidleinhibitor(wlr_surface_get_root_surface(data)); + StaticListener *sl = wl_container_of(listener, sl, listener); + struct wlr_idle_inhibitor_v1 *idle_inhibitor = sl->data; + /* At this point the idle inhibitor is still in the list of the manager */ + checkidleinhibitor(wlr_surface_get_root_surface(idle_inhibitor->surface)); wl_list_remove(&listener->link); free(listener); }