summaryrefslogtreecommitdiff
path: root/src/managers/input/InputManager.cpp
diff options
context:
space:
mode:
authorAgent00Ming <107314235+Agent00Ming@users.noreply.github.com>2024-07-18 15:57:08 -0400
committerGitHub <noreply@github.com>2024-07-18 21:57:08 +0200
commit8e15f91c2417c8f05d69a93f1294185ccc5f8f3e (patch)
tree0aea9874615b9a953f0aef54c29047c3b8dbeb20 /src/managers/input/InputManager.cpp
parent300228b503b36e5977b0d58713c5b4cf1f07b8a9 (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.cpp42
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() {