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
This commit is contained in:
Camilla Löwy
2026-06-15 18:06:36 +02:00
parent 06406a00a0
commit dc86d02ff1
2 changed files with 17 additions and 13 deletions

View File

@@ -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

View File

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