Skip to content

bugfix(mouse): Fix bad drag tolerances with high scroll speed factors#2823

Open
xezon wants to merge 2 commits into
TheSuperHackers:mainfrom
xezon:xezon/fix-drag-tolerance
Open

bugfix(mouse): Fix bad drag tolerances with high scroll speed factors#2823
xezon wants to merge 2 commits into
TheSuperHackers:mainfrom
xezon:xezon/fix-drag-tolerance

Conversation

@xezon

@xezon xezon commented Jun 22, 2026

Copy link
Copy Markdown

This change fixes the bad drag tolerances with high scroll speed factors, which was introduced by #1501 and is especially pronounced in this Project because players are encouraged to set way higher scroll factors after #1026 when higher frame rates no longer increase the camera movement.

@xezon xezon added Bug Something is not working right, typically is user facing Critical Severity: Minor < Major < Critical < Blocker Gen Relates to Generals ZH Relates to Zero Hour Input labels Jun 22, 2026
@greptile-apps

greptile-apps Bot commented Jun 22, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes click vs. drag misdetection that occurs when players use high keyboard scroll speed factors, which became more common after frame-rate-independent scrolling was introduced. The two-part fix scales down the drag tolerance in isClick() inversely proportional to the scroll speed factor and removes the 3D camera-position change check that was independently firing false "drag" signals whenever the camera moved between right-click-down and right-click-up.

  • Adds Mouse::getDragToleranceAdjustedForScrollFactor(), which returns m_dragTolerance * (defaultScrollFactor / currentScrollFactor) so that a higher scroll factor yields a tighter pixel tolerance.
  • Removes m_deselectDownCameraPosition and all associated camera-delta logic from SelectionTranslator, eliminating the third deselect-suppression condition that was overly sensitive to fast scrolling.

Confidence Score: 5/5

Safe to merge — the right-click deselect path is cleanly fixed and the removed camera-drift check had no other dependents.

Both changes are tightly scoped: the tolerance formula in getDragToleranceAdjustedForScrollFactor is mathematically straightforward, and stripping the camera-position delta from right-click deselect removes a known false-positive trigger without breaking any other behavior. No new state is introduced and the removed m_deselectDownCameraPosition member has no remaining references.

No files require special attention. The one open question — whether SelectionXlat.cpp:409 and MetaEvent.cpp:514 also need the scroll-factor-adjusted tolerance — is worth confirming but does not affect correctness of the changes in this PR.

Important Files Changed

Filename Overview
Core/GameEngine/Source/GameClient/Input/Mouse.cpp Adds getDragToleranceAdjustedForScrollFactor() and wires it into isClick(); formula is mathematically correct and the integer-to-float promotion for the comparison is safe.
Core/GameEngine/Include/GameClient/Mouse.h Adds the getDragToleranceAdjustedForScrollFactor() declaration; no structural concerns.
Core/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp Removes the camera-position drift check from right-click deselect detection; correctly updates the comment to reflect only two remaining suppression conditions.
Core/GameEngine/Include/GameClient/SelectionXlat.h Removes the m_deselectDownCameraPosition member now that the camera-drift check is gone; no remaining references.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[MSG_RAW_MOUSE_RIGHT_BUTTON_DOWN] --> B[Record anchor pixel position\nRecord timestamp]
    A --> C["~~Record 3D camera position~~\n(removed)"]
    style C stroke:#f66,stroke-dasharray:5 5,color:#f66

    D[MSG_RAW_MOUSE_RIGHT_BUTTON_UP] --> E[Read current pixel position\nRead current timestamp]
    E --> F["isClick(anchor, current, t0, t1)"]
    F --> G["dragTolerance =\nm_dragTolerance x (defaultScrollFactor / currentScrollFactor)"]
    G --> H{"abs(dx) > dragTolerance\nOR abs(dy) > dragTolerance\nOR elapsed > dragToleranceMS?"}
    H -- Yes --> I[Not a click - ignore deselect]
    H -- No --> J[Click detected - deselect / cancel GUI]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[MSG_RAW_MOUSE_RIGHT_BUTTON_DOWN] --> B[Record anchor pixel position\nRecord timestamp]
    A --> C["~~Record 3D camera position~~\n(removed)"]
    style C stroke:#f66,stroke-dasharray:5 5,color:#f66

    D[MSG_RAW_MOUSE_RIGHT_BUTTON_UP] --> E[Read current pixel position\nRead current timestamp]
    E --> F["isClick(anchor, current, t0, t1)"]
    F --> G["dragTolerance =\nm_dragTolerance x (defaultScrollFactor / currentScrollFactor)"]
    G --> H{"abs(dx) > dragTolerance\nOR abs(dy) > dragTolerance\nOR elapsed > dragToleranceMS?"}
    H -- Yes --> I[Not a click - ignore deselect]
    H -- No --> J[Click detected - deselect / cancel GUI]
Loading

Reviews (2): Last reviewed commit: "Remove legacy m_deselectDownCameraPositi..." | Re-trigger Greptile

Comment thread Core/GameEngine/Source/GameClient/Input/Mouse.cpp
@Caball009

Caball009 commented Jun 22, 2026

Copy link
Copy Markdown

#1501 Seems related.

Maybe using DragTolerance3D (or the idea behind it: distance in the actual game world) makes more sense than accounting for scroll factor?

@xezon

xezon commented Jun 22, 2026

Copy link
Copy Markdown
Author

Maybe using DragTolerance3D (or the idea behind it: distance in the actual game world) makes more sense than accounting for scroll factor?

In principle yes, but that would require

DragTolerance3D = 30 ; How many feet in world space should we allow before it is a drag?

to be a reasonable value and the arguments of the isClick function to take in world positions instead of mouse positions.

#1501 Seems related.

It looks related yes.

@Skyaero42 Skyaero42 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for now this is a sufficient fix.

@Caball009 Caball009 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GeneralsOnline devs are going to include this in a test build for the affected users to test. Let's wait a bit for the results.

@xezon

xezon commented Jun 23, 2026

Copy link
Copy Markdown
Author

#1501 Seems related.

Maybe using DragTolerance3D (or the idea behind it: distance in the actual game world) makes more sense than accounting for scroll factor?

Here is the fix using DragTolerance3D: #2826

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something is not working right, typically is user facing Critical Severity: Minor < Major < Critical < Blocker Gen Relates to Generals Input ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Army gets deselected when moving camera with drag right click

3 participants