From d55e6dfc5e6a3074e624b7f4710a329b71a4f5be Mon Sep 17 00:00:00 2001
From: expikr <[EMAIL REDACTED]>
Date: Mon, 25 Nov 2024 10:54:27 +0800
Subject: [PATCH] hint for which system cursor to use as default
Co-Authored-By: Sam Lantinga <slouken@libsdl.org>
---
include/SDL3/SDL_hints.h | 11 ++++++++++
src/events/SDL_mouse.c | 13 +++++++++++
src/events/SDL_mouse_c.h | 3 +++
src/video/android/SDL_androidmouse.c | 3 ++-
src/video/cocoa/SDL_cocoamouse.m | 25 ++++++----------------
src/video/emscripten/SDL_emscriptenmouse.c | 4 +++-
src/video/haiku/SDL_bvideo.cc | 3 ++-
src/video/wayland/SDL_waylandmouse.c | 3 ++-
src/video/windows/SDL_windowsmouse.c | 11 +++++-----
src/video/x11/SDL_x11mouse.c | 12 +++++------
10 files changed, 54 insertions(+), 34 deletions(-)
diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h
index a8e03d03a82a0..313cdf474e9b1 100644
--- a/include/SDL3/SDL_hints.h
+++ b/include/SDL3/SDL_hints.h
@@ -2401,6 +2401,17 @@ extern "C" {
*/
#define SDL_HINT_MOUSE_DOUBLE_CLICK_TIME "SDL_MOUSE_DOUBLE_CLICK_TIME"
+/**
+ * A variable setting which system cursor to use as the default cursor.
+ * This should be an integer corresponding to the SDL_SystemCursor enum.
+ * The default value is zero (SDL_SYSTEM_CURSOR_DEFAULT).
+ *
+ * This hint needs to be set before SDL_Init().
+ *
+ * \since This hint is available since SDL 3.1.3.
+ */
+#define SDL_HINT_MOUSE_DEFAULT_SYSTEM_CURSOR "SDL_MOUSE_DEFAULT_SYSTEM_CURSOR"
+
/**
* A variable controlling whether warping a hidden mouse cursor will activate
* relative mouse mode.
diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c
index 2923e8b52b415..657bad9a6c237 100644
--- a/src/events/SDL_mouse.c
+++ b/src/events/SDL_mouse.c
@@ -440,6 +440,19 @@ void SDL_SetDefaultCursor(SDL_Cursor *cursor)
}
}
+SDL_SystemCursor SDL_GetDefaultSystemCursor(void)
+{
+ SDL_SystemCursor id = SDL_SYSTEM_CURSOR_DEFAULT;
+ const char *value = SDL_GetHint(SDL_HINT_MOUSE_DEFAULT_SYSTEM_CURSOR);
+ if (value) {
+ int index = SDL_atoi(value);
+ if (0 <= index && index < (int)SDL_SYSTEM_CURSOR_COUNT) {
+ id = (SDL_SystemCursor)index;
+ }
+ }
+ return id;
+}
+
SDL_Mouse *SDL_GetMouse(void)
{
return &SDL_mouse;
diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h
index 6b646a72b8fc4..d77d0a7e10bf4 100644
--- a/src/events/SDL_mouse_c.h
+++ b/src/events/SDL_mouse_c.h
@@ -158,6 +158,9 @@ extern SDL_Mouse *SDL_GetMouse(void);
// Set the default mouse cursor
extern void SDL_SetDefaultCursor(SDL_Cursor *cursor);
+// Get the preferred default system cursor
+extern SDL_SystemCursor SDL_GetDefaultSystemCursor(void);
+
// Set the mouse focus window
extern void SDL_SetMouseFocus(SDL_Window *window);
diff --git a/src/video/android/SDL_androidmouse.c b/src/video/android/SDL_androidmouse.c
index 42a91800b3435..b243c2b429a43 100644
--- a/src/video/android/SDL_androidmouse.c
+++ b/src/video/android/SDL_androidmouse.c
@@ -75,7 +75,8 @@ static SDL_Cursor *Android_WrapCursor(int custom_cursor, int system_cursor)
static SDL_Cursor *Android_CreateDefaultCursor(void)
{
- return Android_WrapCursor(0, SDL_SYSTEM_CURSOR_DEFAULT);
+ SDL_SystemCursor id = SDL_GetDefaultSystemCursor();
+ return Android_WrapCursor(0, id);
}
static SDL_Cursor *Android_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
diff --git a/src/video/cocoa/SDL_cocoamouse.m b/src/video/cocoa/SDL_cocoamouse.m
index 24d7863bed1df..8f2cef5816887 100644
--- a/src/video/cocoa/SDL_cocoamouse.m
+++ b/src/video/cocoa/SDL_cocoamouse.m
@@ -63,25 +63,6 @@ + (NSCursor *)invisibleCursor
}
@end
-static SDL_Cursor *Cocoa_CreateDefaultCursor(void)
-{
- @autoreleasepool {
- NSCursor *nscursor;
- SDL_Cursor *cursor = NULL;
-
- nscursor = [NSCursor arrowCursor];
-
- if (nscursor) {
- cursor = SDL_calloc(1, sizeof(*cursor));
- if (cursor) {
- cursor->internal = (void *)CFBridgingRetain(nscursor);
- }
- }
-
- return cursor;
- }
-}
-
static SDL_Cursor *Cocoa_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
{
@autoreleasepool {
@@ -229,6 +210,12 @@ + (NSCursor *)invisibleCursor
}
}
+static SDL_Cursor *Cocoa_CreateDefaultCursor(void)
+{
+ SDL_SystemCursor id = SDL_GetDefaultSystemCursor();
+ return Cocoa_CreateSystemCursor(id);
+}
+
static void Cocoa_FreeCursor(SDL_Cursor *cursor)
{
@autoreleasepool {
diff --git a/src/video/emscripten/SDL_emscriptenmouse.c b/src/video/emscripten/SDL_emscriptenmouse.c
index 44ca4dd773c9f..64f49a5e7b58e 100644
--- a/src/video/emscripten/SDL_emscriptenmouse.c
+++ b/src/video/emscripten/SDL_emscriptenmouse.c
@@ -62,7 +62,9 @@ static SDL_Cursor *Emscripten_CreateCursorFromString(const char *cursor_str, boo
static SDL_Cursor *Emscripten_CreateDefaultCursor(void)
{
- return Emscripten_CreateCursorFromString("default", false);
+ SDL_SystemCursor id = SDL_GetDefaultSystemCursor();
+ const char *cursor_name = SDL_GetCSSCursorName(id, NULL);
+ return Emscripten_CreateCursorFromString(cursor_name, false);
}
EM_JS_DEPS(sdlmouse, "$stringToUTF8,$UTF8ToString");
diff --git a/src/video/haiku/SDL_bvideo.cc b/src/video/haiku/SDL_bvideo.cc
index 23521f73f29b8..854c1b39c5895 100644
--- a/src/video/haiku/SDL_bvideo.cc
+++ b/src/video/haiku/SDL_bvideo.cc
@@ -180,7 +180,8 @@ static SDL_Cursor * HAIKU_CreateSystemCursor(SDL_SystemCursor id)
static SDL_Cursor * HAIKU_CreateDefaultCursor()
{
- return HAIKU_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT);
+ SDL_SystemCursor id = SDL_GetDefaultSystemCursor();
+ return HAIKU_CreateSystemCursor(id);
}
static void HAIKU_FreeCursor(SDL_Cursor * cursor)
diff --git a/src/video/wayland/SDL_waylandmouse.c b/src/video/wayland/SDL_waylandmouse.c
index 3c35424a2b35d..cdce66b1ed407 100644
--- a/src/video/wayland/SDL_waylandmouse.c
+++ b/src/video/wayland/SDL_waylandmouse.c
@@ -592,7 +592,8 @@ static SDL_Cursor *Wayland_CreateSystemCursor(SDL_SystemCursor id)
static SDL_Cursor *Wayland_CreateDefaultCursor(void)
{
- return Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT);
+ SDL_SystemCursor id = SDL_GetDefaultSystemCursor();
+ return Wayland_CreateSystemCursor(id);
}
static void Wayland_FreeCursorData(SDL_CursorData *d)
diff --git a/src/video/windows/SDL_windowsmouse.c b/src/video/windows/SDL_windowsmouse.c
index 3e09b92be54b3..d53a1f20c544c 100644
--- a/src/video/windows/SDL_windowsmouse.c
+++ b/src/video/windows/SDL_windowsmouse.c
@@ -84,11 +84,6 @@ static SDL_Cursor *WIN_CreateCursorAndData(HCURSOR hcursor)
return cursor;
}
-static SDL_Cursor *WIN_CreateDefaultCursor(void)
-{
- return WIN_CreateCursorAndData(LoadCursor(NULL, IDC_ARROW));
-}
-
static bool IsMonochromeSurface(SDL_Surface *surface)
{
int x, y;
@@ -342,6 +337,12 @@ static SDL_Cursor *WIN_CreateSystemCursor(SDL_SystemCursor id)
return WIN_CreateCursorAndData(LoadCursor(NULL, name));
}
+static SDL_Cursor *WIN_CreateDefaultCursor(void)
+{
+ SDL_SystemCursor id = SDL_GetDefaultSystemCursor();
+ return WIN_CreateSystemCursor(id);
+}
+
static void WIN_FreeCursor(SDL_Cursor *cursor)
{
SDL_CursorData *data = cursor->internal;
diff --git a/src/video/x11/SDL_x11mouse.c b/src/video/x11/SDL_x11mouse.c
index 8a366ad58946a..5015d957156af 100644
--- a/src/video/x11/SDL_x11mouse.c
+++ b/src/video/x11/SDL_x11mouse.c
@@ -89,12 +89,6 @@ static SDL_Cursor *X11_CreateCursorAndData(Cursor x11_cursor)
return cursor;
}
-static SDL_Cursor *X11_CreateDefaultCursor(void)
-{
- // None is used to indicate the default cursor
- return X11_CreateCursorAndData(None);
-}
-
#ifdef SDL_VIDEO_DRIVER_X11_XCURSOR
static Cursor X11_CreateXCursorCursor(SDL_Surface *surface, int hot_x, int hot_y)
{
@@ -279,6 +273,12 @@ static SDL_Cursor *X11_CreateSystemCursor(SDL_SystemCursor id)
return cursor;
}
+static SDL_Cursor *X11_CreateDefaultCursor(void)
+{
+ SDL_SystemCursor id = SDL_GetDefaultSystemCursor();
+ return X11_CreateSystemCursor(id);
+}
+
static void X11_FreeCursor(SDL_Cursor *cursor)
{
Cursor x11_cursor = cursor->internal->cursor;