Wayland: Fix key repeat on very old compositors

The client-side key repeat timer fd was only created for wl_seat version
4 or later, but was then used unconditionally during event processing.

Rather than have this mechanism do nothing in a more correct way on
wl_seat version 3 or earlier (which is very old by now), this commit
creates the key repeat timer fd and then sets (hopefully gentle)
hardcoded repeat delay and rate.
This commit is contained in:
Camilla Löwy
2026-02-09 19:48:45 +01:00
parent c4684b288d
commit a98badf088
3 changed files with 18 additions and 7 deletions

View File

@@ -148,6 +148,7 @@ information on what to include when reporting a bug.
potential segmentation fault (#2744)
- [Wayland] Bugfix: Confining or disabling the cursor could segfault on
compositors without `pointer-constraints-unstable-v1`
- [Wayland] Bugfix: Key repeat did not function on very old compositors
- [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

@@ -137,13 +137,6 @@ static void registryHandleGlobal(void* userData,
wl_registry_bind(registry, name, &wl_seat_interface,
_glfw_min(4, version));
_glfwAddSeatListenerWayland(_glfw.wl.seat);
if (wl_seat_get_version(_glfw.wl.seat) >=
WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
{
_glfw.wl.keyRepeatTimerfd =
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
}
}
}
else if (strcmp(interface, "wl_data_device_manager") == 0)
@@ -834,6 +827,16 @@ int _glfwInitWayland(void)
createKeyTables();
_glfw.wl.keyRepeatTimerfd =
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
if (_glfw.wl.keyRepeatTimerfd == -1)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to create timerfd: %s",
strerror(errno));
return GLFW_FALSE;
}
_glfw.wl.xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (!_glfw.wl.xkb.context)
{

View File

@@ -1942,6 +1942,13 @@ static void seatHandleCapabilities(void* userData,
{
_glfw.wl.keyboard = wl_seat_get_keyboard(seat);
wl_keyboard_add_listener(_glfw.wl.keyboard, &keyboardListener, NULL);
if (wl_keyboard_get_version(_glfw.wl.keyboard) <
WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
{
_glfw.wl.keyRepeatRate = 4;
_glfw.wl.keyRepeatDelay = 500;
}
}
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard)
{