mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-05 18:23:16 +00:00
imgui/renderer: Hide Cursor on Idle Implementation (#1266)
Implement hide cursor on idle w/ idle timeout duration (configurable via GUI). While at it add always and never to hide the cursor options as well. * Revert commit #1211 as to not interfere with the cursor states. * Make hide cursor on idle as the default setting w/ timeout duration of 5 seconds to hide. * Add an input tab in the settings page to add the hide cursor setting, with hiding the idle timeout box with respect to the cursor hide option. Co-authored-by: georgemoralis <giorgosmrls@gmail.com>
This commit is contained in:
parent
96344873d6
commit
f139762c64
7 changed files with 296 additions and 12 deletions
|
@ -4,6 +4,7 @@
|
|||
// Based on imgui_impl_sdl3.cpp from Dear ImGui repository
|
||||
|
||||
#include <imgui.h>
|
||||
#include "common/config.h"
|
||||
#include "imgui_impl_sdl3.h"
|
||||
|
||||
// SDL
|
||||
|
@ -36,6 +37,8 @@ struct SdlData {
|
|||
SDL_Cursor* mouse_cursors[ImGuiMouseCursor_COUNT]{};
|
||||
SDL_Cursor* mouse_last_cursor{};
|
||||
int mouse_pending_leave_frame{};
|
||||
ImVec2 prev_mouse_pos{0, 0};
|
||||
Uint64 lastCursorMoveTime{};
|
||||
|
||||
// Gamepad handling
|
||||
ImVector<SDL_Gamepad*> gamepads{};
|
||||
|
@ -371,6 +374,13 @@ bool ProcessEvent(const SDL_Event* event) {
|
|||
? ImGuiMouseSource_TouchScreen
|
||||
: ImGuiMouseSource_Mouse);
|
||||
io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
|
||||
if (mouse_pos.x != bd->prev_mouse_pos.x || mouse_pos.y != bd->prev_mouse_pos.y) {
|
||||
bd->prev_mouse_pos.x = mouse_pos.x;
|
||||
bd->prev_mouse_pos.y = mouse_pos.y;
|
||||
if (Config::getCursorState() == Config::HideCursorState::Idle) {
|
||||
bd->lastCursorMoveTime = bd->time;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case SDL_EVENT_MOUSE_WHEEL: {
|
||||
|
@ -447,6 +457,7 @@ bool ProcessEvent(const SDL_Event* event) {
|
|||
return false;
|
||||
bd->mouse_window_id = event->window.windowID;
|
||||
bd->mouse_pending_leave_frame = 0;
|
||||
bd->lastCursorMoveTime = bd->time;
|
||||
return true;
|
||||
}
|
||||
// - In some cases, when detaching a window from main viewport SDL may send
|
||||
|
@ -459,6 +470,7 @@ bool ProcessEvent(const SDL_Event* event) {
|
|||
if (GetViewportForWindowId(event->window.windowID) == NULL)
|
||||
return false;
|
||||
bd->mouse_pending_leave_frame = ImGui::GetFrameCount() + 1;
|
||||
bd->lastCursorMoveTime = bd->time;
|
||||
return true;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
||||
|
@ -600,7 +612,18 @@ static void UpdateMouseData() {
|
|||
int window_x, window_y;
|
||||
SDL_GetGlobalMouseState(&mouse_x_global, &mouse_y_global);
|
||||
SDL_GetWindowPosition(focused_window, &window_x, &window_y);
|
||||
io.AddMousePosEvent(mouse_x_global - (float)window_x, mouse_y_global - (float)window_y);
|
||||
mouse_x_global -= (float)window_x;
|
||||
mouse_y_global -= (float)window_y;
|
||||
io.AddMousePosEvent(mouse_x_global, mouse_y_global);
|
||||
// SDL_EVENT_MOUSE_MOTION isn't triggered before the first frame is rendered
|
||||
// force update the prev_cursor coords
|
||||
if (mouse_x_global != bd->prev_mouse_pos.x || mouse_y_global != bd->prev_mouse_pos.y &&
|
||||
bd->prev_mouse_pos.y == 0 &&
|
||||
bd->prev_mouse_pos.x == 0) {
|
||||
bd->prev_mouse_pos.x = mouse_x_global;
|
||||
bd->prev_mouse_pos.y = mouse_y_global;
|
||||
bd->lastCursorMoveTime = bd->time;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -611,10 +634,25 @@ static void UpdateMouseCursor() {
|
|||
return;
|
||||
SdlData* bd = GetBackendData();
|
||||
|
||||
s16 cursorState = Config::getCursorState();
|
||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||
if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None) {
|
||||
if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None ||
|
||||
cursorState == Config::HideCursorState::Always) {
|
||||
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
||||
SDL_HideCursor();
|
||||
|
||||
} else if (cursorState == Config::HideCursorState::Idle &&
|
||||
bd->time - bd->lastCursorMoveTime >=
|
||||
Config::getCursorHideTimeout() * SDL_GetPerformanceFrequency()) {
|
||||
|
||||
bool wasCursorVisible = SDL_CursorVisible();
|
||||
SDL_HideCursor();
|
||||
|
||||
if (wasCursorVisible) {
|
||||
SDL_WarpMouseInWindow(SDL_GetKeyboardFocus(), bd->prev_mouse_pos.x,
|
||||
bd->prev_mouse_pos.y); // Force refresh the cursor state
|
||||
}
|
||||
|
||||
} else {
|
||||
// Show OS mouse cursor
|
||||
SDL_Cursor* expected_cursor = bd->mouse_cursors[imgui_cursor]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue