diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 8b8ba6cf3..3f39e0093 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -2289,6 +2289,17 @@ extern "C" { */ #define SDL_HINT_MOUSE_RELATIVE_WARP_MOTION "SDL_MOUSE_RELATIVE_WARP_MOTION" +/** + * \brief A variable controlling whether the hardware cursor stays visible when relative mode is active. + * + * This variable can be set to the following values: + * "0" - The cursor will be hidden while relative mode is active (default) + * "1" - The cursor will remain visible while relative mode is active + * + * Note that for systems without raw hardware inputs, relative mode is implemented using warping, so the hardware cursor will visibly warp between frames if this is enabled on those systems. + */ +#define SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE "SDL_MOUSE_RELATIVE_CURSOR_VISIBLE" + /** * A variable controlling whether mouse events should generate synthetic touch * events. diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 476959ecc..29fe106d8 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -171,6 +171,13 @@ static void SDLCALL SDL_MouseRelativeWarpMotionChanged(void *userdata, const cha mouse->relative_mode_warp_motion = SDL_GetStringBoolean(hint, SDL_FALSE); } +static void SDLCALL SDL_MouseRelativeCursorVisibleChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_Mouse *mouse = (SDL_Mouse *)userdata; + + mouse->relative_mode_cursor_visible = SDL_GetStringBoolean(hint, SDL_FALSE); +} + /* Public functions */ int SDL_PreInitMouse(void) { @@ -210,6 +217,9 @@ int SDL_PreInitMouse(void) SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, SDL_MouseRelativeWarpMotionChanged, mouse); + SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, + SDL_MouseRelativeCursorVisibleChanged, mouse); + mouse->was_touch_mouse_events = SDL_FALSE; /* no touch to mouse movement event pending */ mouse->cursor_shown = SDL_TRUE; @@ -1119,6 +1129,9 @@ void SDL_QuitMouse(void) SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, SDL_MouseRelativeWarpMotionChanged, mouse); + + SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, + SDL_MouseRelativeCursorVisibleChanged, mouse); for (int i = SDL_mouse_count; i--; ) { SDL_RemoveMouse(SDL_mice[i].instance_id, SDL_FALSE); @@ -1541,7 +1554,7 @@ int SDL_SetCursor(SDL_Cursor *cursor) } } - if (cursor && (!mouse->focus || (mouse->cursor_shown && !mouse->relative_mode))) { + if (cursor && (!mouse->focus || (mouse->cursor_shown && (mouse->relative_mode_cursor_visible || !mouse->relative_mode) ) ) ) { if (mouse->ShowCursor) { mouse->ShowCursor(cursor); } diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h index b2f4d25df..6d120ec3e 100644 --- a/src/events/SDL_mouse_c.h +++ b/src/events/SDL_mouse_c.h @@ -91,6 +91,7 @@ typedef struct SDL_bool relative_mode; SDL_bool relative_mode_warp; SDL_bool relative_mode_warp_motion; + SDL_bool relative_mode_cursor_visible; SDL_bool enable_normal_speed_scale; float normal_speed_scale; SDL_bool enable_relative_speed_scale;