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); }