X11: Fix glfwWaitEvents* ignoring joystick events

The data available on the X11 connection may be a reply or an internal
event for an X11 extension.  Previously the check for whether an event
was available for us was done outside waitForEvent.  This prevented data
available on other file descriptors from breaking the outer wait loop.

This commit moves the check for whether an event is available into the
wait functions, where there is enough knowledge to limit the check to
the X11 connection.

Related to #932

(cherry picked from commit 87970b7f26)
This commit is contained in:
Camilla Löwy 2022-02-18 15:20:10 +01:00
parent 811e6bb01c
commit 7f752c17c6
2 changed files with 24 additions and 11 deletions

View File

@ -128,6 +128,7 @@ information on what to include when reporting a bug.
- [X11] Bugfix: Waiting for events would fail if file descriptor was too large - [X11] Bugfix: Waiting for events would fail if file descriptor was too large
(#2024) (#2024)
- [X11] Bugfix: Joystick events could lead to busy-waiting (#1872) - [X11] Bugfix: Joystick events could lead to busy-waiting (#1872)
- [X11] Bugfix: `glfwWaitEvents*` did not continue for joystick events
- [Wayland] Added support for key names via xkbcommon - [Wayland] Added support for key names via xkbcommon
- [Wayland] Bugfix: Key repeat could lead to a race condition (#1710) - [Wayland] Bugfix: Key repeat could lead to a race condition (#1710)
- [Wayland] Bugfix: Activating a window would emit two input focus events - [Wayland] Bugfix: Activating a window would emit two input focus events

View File

@ -98,7 +98,14 @@ static GLFWbool waitForData(struct pollfd* fds, nfds_t count, double* timeout)
static GLFWbool waitForX11Event(double* timeout) static GLFWbool waitForX11Event(double* timeout)
{ {
struct pollfd fd = { ConnectionNumber(_glfw.x11.display), POLLIN }; struct pollfd fd = { ConnectionNumber(_glfw.x11.display), POLLIN };
return waitForData(&fd, 1, timeout);
while (!XPending(_glfw.x11.display))
{
if (!waitForData(&fd, 1, timeout))
return GLFW_FALSE;
}
return GLFW_TRUE;
} }
// Wait for event data to arrive on any event file descriptor // Wait for event data to arrive on any event file descriptor
@ -115,7 +122,19 @@ static GLFWbool waitForAnyEvent(double* timeout)
fds[count++] = (struct pollfd) { _glfw.linjs.inotify, POLLIN }; fds[count++] = (struct pollfd) { _glfw.linjs.inotify, POLLIN };
#endif #endif
return waitForData(fds, count, timeout); while (!XPending(_glfw.x11.display))
{
if (!waitForData(fds, count, timeout))
return GLFW_FALSE;
for (int i = 1; i < count; i++)
{
if (fds[i].revents & POLLIN)
return GLFW_TRUE;
}
}
return GLFW_TRUE;
} }
// Waits until a VisibilityNotify event arrives for the specified window or the // Waits until a VisibilityNotify event arrives for the specified window or the
@ -2797,20 +2816,13 @@ void _glfwPlatformPollEvents(void)
void _glfwPlatformWaitEvents(void) void _glfwPlatformWaitEvents(void)
{ {
while (!XPending(_glfw.x11.display))
waitForAnyEvent(NULL); waitForAnyEvent(NULL);
_glfwPlatformPollEvents(); _glfwPlatformPollEvents();
} }
void _glfwPlatformWaitEventsTimeout(double timeout) void _glfwPlatformWaitEventsTimeout(double timeout)
{ {
while (!XPending(_glfw.x11.display)) waitForAnyEvent(&timeout);
{
if (!waitForAnyEvent(&timeout))
break;
}
_glfwPlatformPollEvents(); _glfwPlatformPollEvents();
} }