From 5f94ef4478ba78af991f1a9e4e12084ccd5a4337 Mon Sep 17 00:00:00 2001 From: bicarus <202771338+bicarus-dev@users.noreply.github.com> Date: Sun, 3 May 2026 03:49:52 -0700 Subject: [PATCH] overlay: fix scroll bar jumping around when regaining focus (#673) ## Link to GitHub Issue or related Pull Request, if one exists Regression caused by #604, probably ## Description of change When spicecfg or the game loses focus and regains it, scroll bar jumps around. This was because we weren't keeping proper track of mouse wheel position while not in focus, so when we gain it back, it's as if the scroll bar was moved a huge distance. ## Testing Tested spicecfg and in overlay. --- src/spice2x/overlay/imgui/impl_spice.cpp | 58 ++++++++++++++---------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/src/spice2x/overlay/imgui/impl_spice.cpp b/src/spice2x/overlay/imgui/impl_spice.cpp index 1f46eb3..26f7316 100644 --- a/src/spice2x/overlay/imgui/impl_spice.cpp +++ b/src/spice2x/overlay/imgui/impl_spice.cpp @@ -373,7 +373,7 @@ void ImGui_ImplSpice_NewFrame() { // read new keys state static long mouse_wheel_last = 0; long mouse_wheel = 0; - if (RI_MGR != nullptr && accept_new_input) { + if (RI_MGR != nullptr) { auto devices = RI_MGR->devices_get(); for (auto &device : devices) { switch (device.type) { @@ -381,40 +381,46 @@ void ImGui_ImplSpice_NewFrame() { auto &mouse = device.mouseInfo; // mouse button triggers - if (GetSystemMetrics(SM_SWAPBUTTON)) { - if (mouse->key_states[rawinput::MOUSEBTN_RIGHT]) { - g_MouseDown[ImGuiMouseButton_Left] = true; + if (accept_new_input) { + if (GetSystemMetrics(SM_SWAPBUTTON)) { + if (mouse->key_states[rawinput::MOUSEBTN_RIGHT]) { + g_MouseDown[ImGuiMouseButton_Left] = true; + } + if (mouse->key_states[rawinput::MOUSEBTN_LEFT]) { + g_MouseDown[ImGuiMouseButton_Right] = true; + } + } else { + if (mouse->key_states[rawinput::MOUSEBTN_LEFT]) { + g_MouseDown[ImGuiMouseButton_Left] = true; + } + if (mouse->key_states[rawinput::MOUSEBTN_RIGHT]) { + g_MouseDown[ImGuiMouseButton_Right] = true; + } } - if (mouse->key_states[rawinput::MOUSEBTN_LEFT]) { - g_MouseDown[ImGuiMouseButton_Right] = true; + if (mouse->key_states[rawinput::MOUSEBTN_MIDDLE]) { + g_MouseDown[ImGuiMouseButton_Middle] = true; } - } else { - if (mouse->key_states[rawinput::MOUSEBTN_LEFT]) { - g_MouseDown[ImGuiMouseButton_Left] = true; - } - if (mouse->key_states[rawinput::MOUSEBTN_RIGHT]) { - g_MouseDown[ImGuiMouseButton_Right] = true; - } - } - if (mouse->key_states[rawinput::MOUSEBTN_MIDDLE]) { - g_MouseDown[ImGuiMouseButton_Middle] = true; } // final mouse wheel value should be all devices combined + // need to continuously calculate mouse wheel position even when not in focus + // to avoid values jumping (since mouse wheel values are absolute not relative) mouse_wheel += mouse->pos_wheel; break; } case rawinput::KEYBOARD: { - - // iterate all virtual key codes - for (size_t vKey = 0; vKey < VKEY_MAX; vKey++) { - // get state (combined from all pages) - auto &key_states = device.keyboardInfo->key_states; - for (size_t page_index = 0; page_index < 1024; page_index += 256) { - g_KeysDown[vKey] |= key_states[page_index + vKey]; + if (accept_new_input) { + // iterate all virtual key codes + for (size_t vKey = 0; vKey < VKEY_MAX; vKey++) { + // get state (combined from all pages) + auto &key_states = device.keyboardInfo->key_states; + for (size_t page_index = 0; page_index < 1024; page_index += 256) { + g_KeysDown[vKey] |= key_states[page_index + vKey]; + } } } + break; } default: @@ -464,9 +470,11 @@ void ImGui_ImplSpice_NewFrame() { } // set mouse wheel - auto wheel_diff = mouse_wheel - mouse_wheel_last; + long wheel_diff = mouse_wheel - mouse_wheel_last; mouse_wheel_last = mouse_wheel; - io.AddMouseWheelEvent(0, wheel_diff); + if (wheel_diff != 0 && accept_new_input) { + io.AddMouseWheelEvent(0, wheel_diff); + } // update OS mouse position const auto old_mouse_pos = io.MousePos;