Skip to content

SDL3: leave mouse cursor alone (animated cursors) #12163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
zkrx opened this issue Feb 2, 2025 · 0 comments · May be fixed by #12917
Open

SDL3: leave mouse cursor alone (animated cursors) #12163

zkrx opened this issue Feb 2, 2025 · 0 comments · May be fixed by #12917
Milestone

Comments

@zkrx
Copy link

zkrx commented Feb 2, 2025

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:

SDL_SetCursor(NULL);

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 :

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants