diff options
| author | Agent00Ming <107314235+Agent00Ming@users.noreply.github.com> | 2024-07-18 15:57:08 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-18 21:57:08 +0200 |
| commit | 8e15f91c2417c8f05d69a93f1294185ccc5f8f3e (patch) | |
| tree | 0aea9874615b9a953f0aef54c29047c3b8dbeb20 /src/managers/input/InputManager.cpp | |
| parent | 300228b503b36e5977b0d58713c5b4cf1f07b8a9 (diff) | |
input: Emulate discrete scrolling from v120 events (#6881)
* seat: avoid sending axis_stop() when source is wheel
* fix rounding for absolute discrete values greater than 1
Co-authored-by: Agent_00Ming <agent00ming9366@gmail.com>
Diffstat (limited to 'src/managers/input/InputManager.cpp')
| -rw-r--r-- | src/managers/input/InputManager.cpp | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index b2bbd577..23e183d0 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -760,6 +760,7 @@ void CInputManager::onMouseWheel(IPointer::SAxisEvent e) { static auto POFFWINDOWAXIS = CConfigValue<Hyprlang::INT>("input:off_window_axis_events"); static auto PINPUTSCROLLFACTOR = CConfigValue<Hyprlang::FLOAT>("input:scroll_factor"); static auto PTOUCHPADSCROLLFACTOR = CConfigValue<Hyprlang::FLOAT>("input:touchpad:scroll_factor"); + static auto PEMULATEDISCRETE = CConfigValue<Hyprlang::INT>("input:emulate_discrete_scroll"); auto factor = (*PTOUCHPADSCROLLFACTOR <= 0.f || e.source == WL_POINTER_AXIS_SOURCE_FINGER ? *PTOUCHPADSCROLLFACTOR : *PINPUTSCROLLFACTOR); @@ -798,9 +799,44 @@ void CInputManager::onMouseWheel(IPointer::SAxisEvent e) { } } } - double deltaDiscrete = (e.deltaDiscrete != 0) ? (factor * e.deltaDiscrete / std::abs(e.deltaDiscrete)) : 0; - g_pSeatManager->sendPointerAxis(e.timeMs, e.axis, factor * e.delta, deltaDiscrete > 0 ? std::ceil(deltaDiscrete) : std::floor(deltaDiscrete), - std::round(factor * e.deltaDiscrete), e.source, WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL); + + double discrete = (e.deltaDiscrete != 0) ? (factor * e.deltaDiscrete / std::abs(e.deltaDiscrete)) : 0; + double delta = e.delta * factor; + + if (e.source == 0) { + // if an application supports v120, it should ignore discrete anyways + if ((*PEMULATEDISCRETE >= 1 && std::abs(e.deltaDiscrete) != 120) || *PEMULATEDISCRETE >= 2) { + + const int interval = factor != 0 ? std::round(120 * (1 / factor)) : 120; + + // reset the accumulator when timeout is reached or direction/axis has changed + if (std::signbit(e.deltaDiscrete) != m_ScrollWheelState.lastEventSign || e.axis != m_ScrollWheelState.lastEventAxis || + e.timeMs - m_ScrollWheelState.lastEventTime > 500 /* 500ms taken from libinput default timeout */) { + + m_ScrollWheelState.accumulatedScroll = 0; + // send 1 discrete on first event for responsiveness + discrete = std::copysign(1, e.deltaDiscrete); + } else + discrete = 0; + + for (int ac = m_ScrollWheelState.accumulatedScroll; ac >= interval; ac -= interval) { + discrete += std::copysign(1, e.deltaDiscrete); + m_ScrollWheelState.accumulatedScroll -= interval; + } + + m_ScrollWheelState.lastEventSign = std::signbit(e.deltaDiscrete); + m_ScrollWheelState.lastEventAxis = e.axis; + m_ScrollWheelState.lastEventTime = e.timeMs; + m_ScrollWheelState.accumulatedScroll += std::abs(e.deltaDiscrete); + + delta = 15.0 * discrete * factor; + } + } + + int32_t value120 = std::round(factor * e.deltaDiscrete); + int32_t deltaDiscrete = std::abs(discrete) != 0 && std::abs(discrete) < 1 ? std::copysign(1, discrete) : std::round(discrete); + + g_pSeatManager->sendPointerAxis(e.timeMs, e.axis, delta, deltaDiscrete, value120, e.source, WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL); } Vector2D CInputManager::getMouseCoordsInternal() { |
