bugfix(input): Fix touchpad upward scrolling in UI list boxes#2586
bugfix(input): Fix touchpad upward scrolling in UI list boxes#2586afc-afc0 wants to merge 1 commit intoTheSuperHackers:mainfrom
Conversation
Preserve wheel delta sign when normalizing for touchpad scroll direction detection. Touchpad devices send small continuous deltas that were truncated to 0 by integer division with MOUSE_WHEEL_DELTA, causing upward scroll to be misidentified as downward scroll. Clamp the normalized value to at least 1 or -1 based on the original sign.
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Source/GameClient/Input/Mouse.cpp | Clamps normalized wheel ticks to ±1 minimum based on original wheelPos sign, fixing direction detection for small touchpad deltas that previously truncated to 0 |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["WM_MOUSEWHEEL\nwheelPos e.g. +30 (touchpad) or +120 (mouse)"] --> B["Mouse::createStreamMessages()"]
B --> C{"wheelPos != 0?"}
C -- No --> D["Skip wheel message"]
C -- Yes --> E["wheelTicks = wheelPos / MOUSE_WHEEL_DELTA (120)"]
E --> F{"wheelPos > 0?"}
F -- Yes --> G["max(1, wheelTicks)\ne.g. max(1, 0) = 1"]
F -- No --> H["min(-1, wheelTicks)\ne.g. min(-1, 0) = -1"]
G --> I["appendIntegerArgument(1)"]
H --> J["appendIntegerArgument(-1)"]
I --> K["WindowXlat: argument > 0?\n1 > 0 → true → GWM_WHEEL_UP ✓"]
J --> L["WindowXlat: argument > 0?\n-1 > 0 → false → GWM_WHEEL_DOWN ✓"]
Reviews (1): Last reviewed commit: "bugfix(input): Fix touchpad upward scrol..." | Re-trigger Greptile
|
Good catch, closes #2584 |
| msg = TheMessageStream->appendMessage( GameMessage::MSG_RAW_MOUSE_WHEEL ); | ||
| msg->appendPixelArgument( m_currMouse.pos ); | ||
| msg->appendIntegerArgument( m_currMouse.wheelPos / 120 ); // wheel delta | ||
| // TheSuperHackers @bugfix Preserve wheel delta sign for touchpad scroll direction detection |
There was a problem hiding this comment.
The comment is a bit incomplete. It would be better if it clarified that it now guarantees a non-zero value.
| msg->appendIntegerArgument( m_currMouse.wheelPos / 120 ); // wheel delta | ||
| // TheSuperHackers @bugfix Preserve wheel delta sign for touchpad scroll direction detection | ||
| const Int wheelTicks = m_currMouse.wheelPos / MOUSE_WHEEL_DELTA; | ||
| msg->appendIntegerArgument( m_currMouse.wheelPos > 0 ? max( 1, wheelTicks ) : min( -1, wheelTicks ) ); |
There was a problem hiding this comment.
Minor: could be written as.
Int wheelTicks = m_currMouse.wheelPos / MOUSE_WHEEL_DELTA;
wheelTicks = m_currMouse.wheelPos > 0 ? max( 1, wheelTicks ) : min( -1, wheelTicks );
msg->appendIntegerArgument( wheelTicks );| msg->appendIntegerArgument( m_currMouse.wheelPos / 120 ); // wheel delta | ||
| // TheSuperHackers @bugfix Preserve wheel delta sign for touchpad scroll direction detection | ||
| const Int wheelTicks = m_currMouse.wheelPos / MOUSE_WHEEL_DELTA; | ||
| msg->appendIntegerArgument( m_currMouse.wheelPos > 0 ? max( 1, wheelTicks ) : min( -1, wheelTicks ) ); |
There was a problem hiding this comment.
It is not clear to me that this fix proposal is the best approach. Perhaps it would be better to make this message argument a float type instead of integer? It looks like it would be possible. Follow all code at MSG_RAW_MOUSE_WHEEL.
Summary
Root Cause
In
Mouse::createStreamMessages(), the wheel delta was divided byMOUSE_WHEEL_DELTA(120) before being sent as a message argument.Touchpad devices send small deltas (e.g. +30) that truncate to 0 on integer division. In
WindowXlat.cpp, the direction checkif (argument > 0)maps 0 toGWM_WHEEL_DOWN, causing upward touchpad scroll to be treated as downward.Fix
Clamp the normalized wheel delta to at least
1or-1based on the original sign ofwheelPos, ensuring the scroll direction isalways preserved. Only
Mouse.cppis changed — no consumers need modification.Test plan