From dc86d02ff1943bbceda72d4e89f9cf711bbd6ad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 15 Jun 2026 18:06:36 +0200 Subject: [PATCH] Wayland: Fix some event types not being processed If there was already an event available in the Wayland queue, that event would be processed but other kinds of events (libdecor, key repeat, joystick connection, etc.) would not be. This commit restores the processing of all available events on every call to glfw*Events. It is partially based on #2842 by jadahl. Because some libdecor plugins also process non-Wayland events, without providing an fd for them, libdecor_dispatch is now called unconditionally. Fixes #2793 Closes #2795 Related to #2842 --- README.md | 2 ++ src/wl_window.c | 28 +++++++++++++++------------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ed18b950..90cf45e7 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,8 @@ information on what to include when reporting a bug. was suspended (#1350,#2582,#2640,#2719,#2723,#2800,#2827) - [Wayland] Bugfix: `glfwPostEmptyEvent` would leak a callback proxy (#2836) - [Wayland] Bugfix: `glfwHideWindow` did not always send its request immediately + - [Wayland] Bugfix: Some event types were not always processed by `glfwPollEvents` or + `glfwWait*Events` (#2793,#2795) - [X11] Bugfix: Running without a WM could trigger an assert (#2593,#2601,#2631) - [X11] Bugfix: Occasional crash when an idle display awakes (#2766) - [X11] Bugfix: Prevent BadWindow when creating small windows with a content scale diff --git a/src/wl_window.c b/src/wl_window.c index 7d0a8309..221b3ccd 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1375,24 +1375,27 @@ static void handleEvents(double* timeout) #endif GLFWbool event = GLFW_FALSE; - enum { DISPLAY_FD, KEYREPEAT_FD, CURSOR_FD, LIBDECOR_FD }; + enum { DISPLAY_FD, KEYREPEAT_FD, CURSOR_FD }; struct pollfd fds[] = { [DISPLAY_FD] = { wl_display_get_fd(_glfw.wl.display), POLLIN }, [KEYREPEAT_FD] = { _glfw.wl.keyRepeatTimerfd, POLLIN }, - [CURSOR_FD] = { _glfw.wl.cursorTimerfd, POLLIN }, - [LIBDECOR_FD] = { -1, POLLIN } + [CURSOR_FD] = { _glfw.wl.cursorTimerfd, POLLIN } }; - if (_glfw.wl.libdecor.context) - fds[LIBDECOR_FD].fd = libdecor_get_fd(_glfw.wl.libdecor.context); - while (!event) { + if (_glfw.wl.libdecor.context) + { + // Dispatch unconditionally because it also processes non-Wayland events + if (libdecor_dispatch(_glfw.wl.libdecor.context, 0) > 0) + event = GLFW_TRUE; + } + while (wl_display_prepare_read(_glfw.wl.display) != 0) { if (wl_display_dispatch_pending(_glfw.wl.display) > 0) - return; + event = GLFW_TRUE; } // If an error other than EAGAIN happens, we have likely been disconnected @@ -1411,6 +1414,11 @@ static void handleEvents(double* timeout) return; } + double immediate = 0.0; + + if (event) + timeout = &immediate; + if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout)) { wl_display_cancel_read(_glfw.wl.display); @@ -1457,12 +1465,6 @@ static void handleEvents(double* timeout) if (read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)) == 8) incrementCursorImage(); } - - if (fds[LIBDECOR_FD].revents & POLLIN) - { - if (libdecor_dispatch(_glfw.wl.libdecor.context, 0) > 0) - event = GLFW_TRUE; - } } }