Description
I didn't find a way to use animated mouse cursors with SDL.
Ideally, I'd like to use system cursors in my application. Let's say I'm running Linux, and I want to use a custom X11 cursor following the xcursors format (same train of thoughts applies to Windows and Wayland): I would need to call XcursorFilenameLoadCursor()
. Understandably, and probably out of portability concerns, SDL doesn't expose X11 system-specific cursor functions to the user. So one can choose to deal with X11 directly and use something like the following code, which is really straightforward:
void set_cursor(SDL_Window *window, const char *path)
{
Display *xdisplay = (Display *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
Window xwindow = (Window)SDL_GetNumberProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
XcursorSetDefaultSize(xdisplay, 72);
Cursor c = XcursorFilenameLoadCursor(xdisplay, path);
ASSERT(c, "XcursorFilenameLoadCursor error (%s)", path);
XDefineCursor(xdisplay, xwindow, c);
XFlush(xdisplay);
}
But this will not work (it works as long as I don't call SDL_PollEvent
): SDL overwrites my manually-set mouse cursor on every mouse focus event, here's a backtrace:
[0] from 0x00007ffff7e61080 in XFlush+0 at /usr/src/debug/libx11/libX11-1.8.10/src/Flush.c:37
[1] from 0x00007ffff7b55f69 in X11_ShowCursor+233 at /usr/src/debug/sdl3/SDL3-3.2.0/src/video/x11/SDL_x11mouse.c:321
[2] from 0x00007ffff7a45900 in SDL_SetCursor_REAL+144 at /usr/src/debug/sdl3/SDL3-3.2.0/src/events/SDL_mouse.c:1574
[3] from 0x00007ffff7b51e27 in X11_DispatchEvent+3127 at /usr/src/debug/sdl3/SDL3-3.2.0/src/video/x11/SDL_x11events.c:1235
[4] from 0x00007ffff7b545bb in X11_PumpEvents+203 at /usr/src/debug/sdl3/SDL3-3.2.0/src/video/x11/SDL_x11events.c:2128
[5] from 0x00007ffff7a5108d in SDL_PumpEventsInternal+317 at /usr/src/debug/sdl3/SDL3-3.2.0/src/events/SDL_events.c:1405
[6] from 0x00007ffff7a51842 in SDL_WaitEventTimeoutNS+882 at /usr/src/debug/sdl3/SDL3-3.2.0/src/events/SDL_events.c:1580
Here's the offending line:
Line 582 in be99123
I looked into ways to tell SDL to stop doing this (stop calling SDL_SetCursor
each time the window gets mouse focus), but I couldn't find any. In my case, I had to build SDL 3.2.0 with this trivial patch so that my animated cursor works:
[user@computer SDL]$ git diff
diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c
index 25dfef7f2..78ab2d470 100644
--- a/src/events/SDL_mouse.c
+++ b/src/events/SDL_mouse.c
@@ -579,7 +579,7 @@ void SDL_SetMouseFocus(SDL_Window *window)
}
// Update cursor visibility
- SDL_SetCursor(NULL);
+ //SDL_SetCursor(NULL);
}
So what about adding an API function that lets us disable SDL's cursor display management? I.e. just neuter SDL_SetCursor
. Something likeSDL_DisableCursorIcon
. To be clear, the cursor would still be handled, SDL would just stop messing with the actual display of the cursor.
Is it something that sounds interesting to some? Is it practical? If so, what would be the best way to solve this? Or does someone sees a better way to support animated cursors?
Here's an example using an animated xcursor from https://www.gnome-look.org/p/999537 :