From 35a80bdf1f114550d7e84b8a6478180bcf132267 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Fri, 16 Jan 2026 10:48:55 -0500
Subject: [PATCH] wayland: Also check tools for cursor usage during cursor
destruction
---
src/video/wayland/SDL_waylandevents_c.h | 1 -
src/video/wayland/SDL_waylandmouse.c | 18 ++++++++++++++++--
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/src/video/wayland/SDL_waylandevents_c.h b/src/video/wayland/SDL_waylandevents_c.h
index 32abf467d2af9..4e98e6f69f7be 100644
--- a/src/video/wayland/SDL_waylandevents_c.h
+++ b/src/video/wayland/SDL_waylandevents_c.h
@@ -189,7 +189,6 @@ typedef struct SDL_WaylandSeat
struct zwp_pointer_gesture_pinch_v1 *gesture_pinch;
SDL_WindowData *focus;
- SDL_CursorData *current_cursor;
// According to the spec, a seat can only have one active gesture of any type at a time.
SDL_WindowData *gesture_focus;
diff --git a/src/video/wayland/SDL_waylandmouse.c b/src/video/wayland/SDL_waylandmouse.c
index 61e3e71d805c7..db8381ca1b6d1 100644
--- a/src/video/wayland/SDL_waylandmouse.c
+++ b/src/video/wayland/SDL_waylandmouse.c
@@ -897,7 +897,7 @@ static void Wayland_FreeCursorData(SDL_CursorData *d)
// Stop any frame callbacks and detach buffers associated with the cursor being destroyed.
wl_list_for_each (seat, &video_data->seat_list, link)
{
- if (seat->pointer.current_cursor == d) {
+ if (seat->pointer.cursor_state.current_cursor == d) {
Wayland_CursorStateDestroyFrameCallback(&seat->pointer.cursor_state);
// Custom cursor buffers are about to be destroyed, so ensure they are detached.
@@ -905,7 +905,21 @@ static void Wayland_FreeCursorData(SDL_CursorData *d)
wl_surface_attach(seat->pointer.cursor_state.surface, NULL, 0, 0);
}
- seat->pointer.current_cursor = NULL;
+ seat->pointer.cursor_state.current_cursor = NULL;
+ }
+
+ SDL_WaylandPenTool *tool;
+ wl_list_for_each (tool, &seat->tablet.tool_list, link) {
+ Wayland_CursorStateDestroyFrameCallback(&tool->cursor_state);
+
+ if (tool->cursor_state.current_cursor == d) {
+ // Custom cursor buffers are about to be destroyed, so ensure they are detached.
+ if (!d->is_system_cursor && tool->cursor_state.surface) {
+ wl_surface_attach(seat->pointer.cursor_state.surface, NULL, 0, 0);
+ }
+
+ tool->cursor_state.current_cursor = NULL;
+ }
}
}