From b0a42784f1143051313832bf9b6ef2b7afbe2656 Mon Sep 17 00:00:00 2001 From: Dery Almas Date: Thu, 27 Nov 2025 19:50:42 +0100 Subject: [PATCH 1/3] Wayland: Fix SIGFPE with repeat rate of 0 We always divided by the rate, which could be zero, which is a valid value (it means "disable key repeating"). --- platform/linuxbsd/wayland/wayland_thread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linuxbsd/wayland/wayland_thread.cpp b/platform/linuxbsd/wayland/wayland_thread.cpp index 50e3d11a74e..b0131f48bf1 100644 --- a/platform/linuxbsd/wayland/wayland_thread.cpp +++ b/platform/linuxbsd/wayland/wayland_thread.cpp @@ -2295,7 +2295,7 @@ void WaylandThread::_wl_keyboard_on_repeat_info(void *data, struct wl_keyboard * SeatState *ss = (SeatState *)data; ERR_FAIL_NULL(ss); - ss->repeat_key_delay_msec = 1000 / rate; + ss->repeat_key_delay_msec = rate ? 1000 / rate : 0; ss->repeat_start_delay_msec = delay; } From a79239e332ef08d15ec2ada2ef04c881511f11b5 Mon Sep 17 00:00:00 2001 From: Dery Almas Date: Thu, 27 Nov 2025 22:01:02 +0100 Subject: [PATCH 2/3] Wayland: Add default keyboard repetition values The `wl_keyboard::repeat_info` event got introduced in version 4. On versions older than that, we defaulted to 0 delay, which means no repetition. That's a veeery old version and basically everything offers it, but it doesn't hurt to add a reasonable default. --- platform/linuxbsd/wayland/wayland_thread.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/linuxbsd/wayland/wayland_thread.h b/platform/linuxbsd/wayland/wayland_thread.h index e45e3ce957e..16851220952 100644 --- a/platform/linuxbsd/wayland/wayland_thread.h +++ b/platform/linuxbsd/wayland/wayland_thread.h @@ -480,8 +480,11 @@ public: xkb_layout_index_t current_layout_index = 0; - int32_t repeat_key_delay_msec = 0; - int32_t repeat_start_delay_msec = 0; + // Clients with `wl_seat`s older than version 4 do not support + // `wl_keyboard::repeat_info`, so we'll provide a reasonable default of 25 + // keys per second, with a start delay of 600 milliseconds. + int32_t repeat_key_delay_msec = 1000 / 25; + int32_t repeat_start_delay_msec = 600; xkb_keycode_t repeating_keycode = XKB_KEYCODE_INVALID; uint64_t last_repeat_start_msec = 0; From f90a9ad6596ee752e3648611df3e4d4f447ef674 Mon Sep 17 00:00:00 2001 From: Riteo Siuga Date: Thu, 27 Nov 2025 23:02:08 +0100 Subject: [PATCH 3/3] Destroy XKB keymap and state on seat capability change Wasn't that much of a concern as it would have been disposed of next time a keyboard got added, but it's still a good thing to do. --- platform/linuxbsd/wayland/wayland_thread.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platform/linuxbsd/wayland/wayland_thread.cpp b/platform/linuxbsd/wayland/wayland_thread.cpp index b0131f48bf1..67ca1de696c 100644 --- a/platform/linuxbsd/wayland/wayland_thread.cpp +++ b/platform/linuxbsd/wayland/wayland_thread.cpp @@ -1613,6 +1613,16 @@ void WaylandThread::_wl_seat_on_capabilities(void *data, struct wl_seat *wl_seat ss->xkb_compose_state = nullptr; } + if (ss->xkb_keymap) { + xkb_keymap_unref(ss->xkb_keymap); + ss->xkb_keymap = nullptr; + } + + if (ss->xkb_state) { + xkb_state_unref(ss->xkb_state); + ss->xkb_state = nullptr; + } + if (ss->wl_keyboard) { wl_keyboard_destroy(ss->wl_keyboard); ss->wl_keyboard = nullptr;