From ca537d651b82f28bc280685391665eb25c856e00 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Sun, 11 Jan 2026 11:23:33 -0500
Subject: [PATCH] wayland: Dispatch pointer leave when destroying the pointer
or a surface
No pointer frame event will occur when synthesizing a leave event, so dispatch immediately.
---
src/video/wayland/SDL_waylandevents.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index ece3e4c18f27f..0ed28abd215b8 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -2407,7 +2407,9 @@ static void Wayland_SeatDestroyPointer(SDL_WaylandSeat *seat)
// Make sure focus is removed from a surface before the pointer is destroyed.
if (seat->pointer.focus) {
- pointer_handle_leave(seat, seat->pointer.wl_pointer, 0, seat->pointer.focus->surface);
+ seat->pointer.pending_frame.leave_window = seat->pointer.focus;
+ pointer_dispatch_leave(seat);
+ seat->pointer.pending_frame.leave_window = NULL;
}
SDL_RemoveMouse(seat->pointer.sdl_id);
@@ -3675,7 +3677,11 @@ void Wayland_DisplayRemoveWindowReferencesFromSeats(SDL_VideoData *display, SDL_
}
if (seat->pointer.focus == window) {
- pointer_handle_leave(seat, seat->pointer.wl_pointer, 0, window->surface);
+ seat->pointer.pending_frame.leave_window = seat->pointer.focus;
+ pointer_dispatch_leave(seat);
+ Wayland_SeatUpdatePointerGrab(seat);
+ Wayland_SeatUpdatePointerCursor(seat);
+ seat->pointer.pending_frame.leave_window = NULL;
}
// Need the safe loop variant here as cancelling a touch point removes it from the list.