From 0a80aefd4997cdfc90640cdc9f41e1b66bb9d866 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Mon, 24 Aug 2026 12:04:36 -0400 Subject: [PATCH] wayland: Don't perform hit testing during implicit pointer grabs Skip hit testing when an implicit grab is active, or button raise events may be lost, and the cursor icon may be improperly set if the client reports hit test results while the pointer is outside the window bounds. (cherry picked from commit bc0a43ec7fc5fbddc28d2c06eb7e190eebf19ca5) --- src/video/wayland/SDL_waylandevents.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 410c440d75..5970b18db3 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -693,7 +693,8 @@ static void pointer_dispatch_absolute_motion(SDL_WaylandSeat *seat) Wayland_SeatUpdatePointerGrab(seat); } - if (window->hit_test) { + // Don't perform hit testing if an implicit grab is active. + if (!(window->flags & SDL_WINDOW_MOUSE_CAPTURE) && window->hit_test) { SDL_HitTestResult rc = window->hit_test(window, &seat->pointer.last_motion, window->hit_test_data); // Apply the toplevel constraints if the window isn't resizable from those directions. @@ -1001,14 +1002,14 @@ static void pointer_handle_button_common(SDL_WaylandSeat *seat, uint32_t serial, if (state) { Wayland_UpdateImplicitGrabSerial(seat, serial); seat->pointer.buttons_pressed |= SDL_BUTTON_MASK(sdl_button); + + if (sdl_button == SDL_BUTTON_LEFT && Wayland_ProcessHitTest(seat, seat->last_implicit_grab_serial)) { + return; // don't pass this event on to app. + } } else { seat->pointer.buttons_pressed &= ~(SDL_BUTTON_MASK(sdl_button)); } - if (sdl_button == SDL_BUTTON_LEFT && Wayland_ProcessHitTest(seat, serial)) { - return; // don't pass this event on to app. - } - // Possibly ignore this click if it was to gain focus. if (window->last_focus_event_time_ns) { if (state == WL_POINTER_BUTTON_STATE_PRESSED &&