From 57a8973bc20f4441394e7955e00d233690d9c8fb Mon Sep 17 00:00:00 2001 From: lkn Date: Sat, 6 Jun 2026 16:53:13 +0200 Subject: [PATCH] fix: wlclient_dispatch stops spinning when compositor closes the socket (NULLs ctx->display, making subsequent calls a no-op) --- WINGs/wclient_wl.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/WINGs/wclient_wl.c b/WINGs/wclient_wl.c index 8001b66..6eccec9 100644 --- a/WINGs/wclient_wl.c +++ b/WINGs/wclient_wl.c @@ -1159,18 +1159,14 @@ wlclient_dispatch(int timeout_ms, void *userdata) * 2. Flush outgoing requests. * 3. Poll the fd. * 4. read_events / cancel_read. - * 5. Dispatch any queued events. - * - * We don't need the prepare/read split when we're only blocking - * here, but doing it correctly keeps us safe if multiple threads - * ever want to share the wl_display. - */ + * 5. Dispatch any queued events. */ while (wl_display_prepare_read(ctx->display) != 0) { - if (wl_display_dispatch_pending(ctx->display) < 0) return; + if (wl_display_dispatch_pending(ctx->display) < 0) + goto dead; } if (wl_display_flush(ctx->display) < 0 && errno != EAGAIN) { wl_display_cancel_read(ctx->display); - return; + goto dead; } struct pollfd pfd = { @@ -1182,8 +1178,14 @@ wlclient_dispatch(int timeout_ms, void *userdata) wl_display_cancel_read(ctx->display); return; } - if (wl_display_read_events(ctx->display) < 0) return; - wl_display_dispatch_pending(ctx->display); + if (wl_display_read_events(ctx->display) < 0) goto dead; + if (wl_display_dispatch_pending(ctx->display) < 0) goto dead; + return; + +dead: + /* Compositor closed the socket — stop spinning. */ + wl_display_disconnect(ctx->display); + ctx->display = NULL; } /* Pump the client-side Wayland display so pending events (like