From c4e0e7fadea0bf4f9da7bdea4335f619a6f14385 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 24 Dec 2024 13:52:01 +1000 Subject: [PATCH] InputManager: Fix mouse-mapped axes getting stuck Regression from f0deab2. --- src/util/input_manager.cpp | 28 +++++++++++++++++----------- src/util/input_manager.h | 3 +++ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/util/input_manager.cpp b/src/util/input_manager.cpp index 6b9df1911..809ebd54c 100644 --- a/src/util/input_manager.cpp +++ b/src/util/input_manager.cpp @@ -1224,13 +1224,15 @@ void InputManager::GenerateRelativeMouseEvents() { PointerAxisState& state = s_pointer_state[device][axis]; const float delta = static_cast(state.delta.exchange(0, std::memory_order_acquire)) / 65536.0f; - if (delta == 0.0f) + const float unclamped_value = delta * s_pointer_axis_scale[axis]; + const float value = std::clamp(unclamped_value, -1.0f, 1.0f); + if (value == state.last_value) continue; - const float unclamped_value = delta * s_pointer_axis_scale[axis]; + state.last_value = value; const InputBindingKey key(MakePointerAxisKey(device, static_cast(axis))); - if (axis >= static_cast(InputPointerAxis::WheelX) && + if (device == 0 && axis >= static_cast(InputPointerAxis::WheelX) && ImGuiManager::ProcessPointerAxisEvent(key, unclamped_value)) { continue; @@ -1239,12 +1241,7 @@ void InputManager::GenerateRelativeMouseEvents() if (!system_running) continue; - const float value = std::clamp(unclamped_value, -1.0f, 1.0f); - if (value != state.last_value) - { - state.last_value = value; - InvokeEvents(key, value, GenericInputBinding::Unknown); - } + InvokeEvents(key, value, GenericInputBinding::Unknown); if (delta != 0.0f) { @@ -1302,18 +1299,27 @@ void InputManager::UpdatePointerAbsolutePosition(u32 index, float x, float y) if (dx != 0.0f) { s_pointer_state[index][static_cast(InputPointerAxis::X)].delta.fetch_add(static_cast(dx * 65536.0f), - std::memory_order_release); + std::memory_order_acq_rel); } if (dy != 0.0f) { s_pointer_state[index][static_cast(InputPointerAxis::Y)].delta.fetch_add(static_cast(dy * 65536.0f), - std::memory_order_release); + std::memory_order_acq_rel); } if (index == 0) ImGuiManager::UpdateMousePosition(x, y); } +void InputManager::ResetPointerRelativeDelta(u32 index) +{ + if (index >= MAX_POINTER_DEVICES || s_relative_mouse_mode_active) [[unlikely]] + return; + + s_pointer_state[index][static_cast(InputPointerAxis::X)].delta.store(0, std::memory_order_release); + s_pointer_state[index][static_cast(InputPointerAxis::Y)].delta.store(0, std::memory_order_release); +} + void InputManager::UpdatePointerRelativeDelta(u32 index, InputPointerAxis axis, float d, bool raw_input) { if (index >= MAX_POINTER_DEVICES || (axis < InputPointerAxis::WheelX && !s_relative_mouse_mode_active)) diff --git a/src/util/input_manager.h b/src/util/input_manager.h index 4437ffc53..9bde738b1 100644 --- a/src/util/input_manager.h +++ b/src/util/input_manager.h @@ -338,6 +338,9 @@ std::pair GetPointerAbsolutePosition(u32 index); /// Updates absolute pointer position. Can call from UI thread, use when the host only reports absolute coordinates. void UpdatePointerAbsolutePosition(u32 index, float x, float y); +/// Resets the accumulated pointer movement. Use when pointer tracking was interrupted. +void ResetPointerRelativeDelta(u32 index); + /// Updates relative pointer position. Can call from the UI thread, use when host supports relative coordinate /// reporting. void UpdatePointerRelativeDelta(u32 index, InputPointerAxis axis, float d, bool raw_input = false);