From db7defff5af3b318ad286400c8b267aa0cb80395 Mon Sep 17 00:00:00 2001 From: bicarus <202771338+bicarus-dev@users.noreply.github.com> Date: Thu, 25 Jun 2026 15:30:59 -0700 Subject: [PATCH] overlay: fix OS cursor showing up in some games (#776) ## Link to GitHub Issue or related Pull Request, if one exists regressed by #766, fixes #775 ## Description of change Some games like DDR leave `ShowCursor` ref count at non-negative number, so when spice handles `WM_SETCURSOR` to change the cursor shape, it ends up showing the OS cursor. ## Testing --- src/spice2x/overlay/imgui/impl_spice.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/spice2x/overlay/imgui/impl_spice.cpp b/src/spice2x/overlay/imgui/impl_spice.cpp index 844d16c..1c49aae 100644 --- a/src/spice2x/overlay/imgui/impl_spice.cpp +++ b/src/spice2x/overlay/imgui/impl_spice.cpp @@ -210,7 +210,15 @@ bool ImGui_ImplSpice_UpdateMouseCursor() { // update cursor ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); - if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) { + + // in auto-hide mode imgui owns cursor drawing, so the OS cursor must stay + // hidden. this function is also called from the game window's WM_SETCURSOR + // handler, which fires on every mouse move; without forcing it hidden here, + // the else branch below would set IDC_ARROW on the next mouse move once the + // overlay is closed. that arrow is conspicuous on games whose window class + // has hCursor==NULL (e.g. DDR), since those normally show no client-area + // cursor at all. + if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor || g_MouseCursorAutoHide) { // hide OS mouse cursor if imgui is drawing it or if it wants no cursor ::SetCursor(nullptr); @@ -592,8 +600,12 @@ void ImGui_ImplSpice_NewFrame() { } } } else { - // update OS mouse cursor with the cursor requested by imgui - ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); + // in auto-hide mode imgui owns the cursor, so keep the OS cursor hidden + // even when the overlay is closed (io.MouseDrawCursor is false then). + ImGuiMouseCursor mouse_cursor = + (io.MouseDrawCursor || g_MouseCursorAutoHide) + ? ImGuiMouseCursor_None + : ImGui::GetMouseCursor(); if (g_LastMouseCursor != mouse_cursor) { g_LastMouseCursor = mouse_cursor; ImGui_ImplSpice_UpdateMouseCursor();