From 17d2814b4d7e491a8717475d0214c5726b98dfd0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 21 Aug 2026 20:38:38 +0530 Subject: [PATCH] Fix #10383 --- glfw/wl_init.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/glfw/wl_init.c b/glfw/wl_init.c index 4f7abbdad..d3bb66b6a 100644 --- a/glfw/wl_init.c +++ b/glfw/wl_init.c @@ -879,12 +879,6 @@ _glfwPlatformTerminate(void) { } free(_glfw.wl.activation_requests.array); } - _glfwTerminateEGL(); - if (_glfw.wl.egl.handle) { - _glfw_dlclose(_glfw.wl.egl.handle); - _glfw.wl.egl.handle = NULL; - } - glfw_xkb_release(&_glfw.wl.xkb); glfw_dbus_terminate(&_glfw.wl.dbus); @@ -941,11 +935,29 @@ _glfwPlatformTerminate(void) { if (_glfw.wl.pointer_gestures) zwp_pointer_gestures_v1_release(_glfw.wl.pointer_gestures); if (_glfw.wl.registry) wl_registry_destroy(_glfw.wl.registry); + // Call eglTerminate before disconnecting from the display: eglTerminate + // sends Wayland protocol requests which must be flushed and their closures + // drained before we unload the EGL library. The dlclose calls move to + // after wl_display_disconnect so the message format tables remain mapped + // while the queue is drained, preventing a segfault in + // destroy_queued_closure(). + if (_glfw.egl.display) { + eglTerminate(_glfw.egl.display); + _glfw.egl.display = EGL_NO_DISPLAY; + } if (_glfw.wl.display) { wl_display_flush(_glfw.wl.display); wl_display_disconnect(_glfw.wl.display); _glfw.wl.display = NULL; } + if (_glfw.egl.handle) { + _glfw_dlclose(_glfw.egl.handle); + _glfw.egl.handle = NULL; + } + if (_glfw.wl.egl.handle) { + _glfw_dlclose(_glfw.wl.egl.handle); + _glfw.wl.egl.handle = NULL; + } finalizePollData(&_glfw.wl.eventLoopData); if (_glfw.wl.compositor_name) { free(_glfw.wl.compositor_name);