Skip to content

bugfix(mouse): Fix bad drag tolerances with high scroll speed factors, alternative#2826

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

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

Conversation

@xezon

@xezon xezon commented Jun 23, 2026

Copy link
Copy Markdown

Merge with Rebase

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.

This is an alternative implementation to #2823 using the 3D camera tolerance.

TODO

  • Add pull id's to commit titles
  • Rework BaseType.h
  • Add fix comments

@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 23, 2026
@greptile-apps

greptile-apps Bot commented Jun 23, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes incorrect drag detection that occurs when players scroll the camera quickly — specifically, the screen cursor stays nearly stationary but the camera moves significantly, causing what should be a click to be misidentified as a drag. The fix extends Mouse::isClick() to accept and compare two 3D camera positions (in addition to the existing 2D screen positions and timestamp), so camera movement now contributes to the drag decision.

  • isClick() signature extended: now takes two ICoord2D positions, two Coord3D camera positions, and two timestamps. Both CommandXlat and SelectionXlat record the camera position at mouse-down and pass it alongside the camera position at mouse-up.
  • Tolerance check changed from axis-aligned square to Euclidean circle: the old per-axis check (abs(dx) > T || abs(dy) > T) is replaced with lengthSqr() > sqr(T). This inscribes the tolerance region in the previous square, tightening click acceptance slightly along the diagonal.
  • BaseType.h enriched: operator+, operator-, operator+=, operator-=, and set(...) are added to Coord2D, ICoord2D, Coord3D, and ICoord3D to support the new subtraction-based delta calculation.

Confidence Score: 5/5

Safe to merge. The change correctly records camera positions at both mouse-down and mouse-up events and passes them through isClick(), directly addressing the root cause of false drag detection at high scroll speeds.

The camera-position recording and delta check are wired up symmetrically in both CommandXlat and SelectionXlat. The BaseType.h additions are mechanical and correct. The one notable side effect — the 2D tolerance zone shifting from a square to a circle — is a minor behavioral difference in a low-stakes path and does not cause incorrect data or crashes.

Mouse.cpp warrants a quick review of the square-to-circle tolerance change to confirm it is intentional.

Important Files Changed

Filename Overview
Core/GameEngine/Source/GameClient/Input/Mouse.cpp Core fix: isClick() extended with camera-position parameters and circle-based 2D tolerance. The square-to-circle change subtly tightens diagonal click acceptance.
Core/Libraries/Include/Lib/BaseType.h Adds operator overloads and set() methods to Coord2D, ICoord2D, Coord3D, ICoord3D. ICoord types use correctly-typed (Int/Int/Int) parameters. ICoord2D::lengthSqr() returns Real from an integer computation — harmless for screen coordinates but mildly surprising.
Core/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp Renames deselect-anchor fields to use consistent naming convention and threads camera positions into isClick(). Correctly captures camera at both mouse-down and mouse-up events.
Core/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp Records TheTacticalView->getPosition() at right-mouse-down and right-mouse-up events and threads both camera positions into both isClick() call sites.
Core/GameEngine/Include/GameClient/CommandXlat.h Adds Coord3D members for camera position tracking at right-mouse-down and right-mouse-up; renames existing anchor and time fields.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant SelectionXlat/CommandXlat
    participant TheTacticalView
    participant Mouse

    User->>SelectionXlat/CommandXlat: MSG_RAW_MOUSE_RIGHT_BUTTON_DOWN
    SelectionXlat/CommandXlat->>TheTacticalView: getPosition()
    TheTacticalView-->>SelectionXlat/CommandXlat: cameraPos0
    Note over SelectionXlat/CommandXlat: Store mouseAnchor0, timeMs0, cameraPos0

    User->>SelectionXlat/CommandXlat: MSG_RAW_MOUSE_RIGHT_BUTTON_UP
    SelectionXlat/CommandXlat->>TheTacticalView: getPosition()
    TheTacticalView-->>SelectionXlat/CommandXlat: cameraPos1
    SelectionXlat/CommandXlat->>Mouse: isClick(mouseAnchor0, mouseAnchor1, cameraPos0, cameraPos1, timeMs0, timeMs1)
    Note over Mouse: timeDelta > dragToleranceMS?
    Note over Mouse: mouseAnchorDelta.lengthSqr() > sqr(dragTolerance)?
    Note over Mouse: cameraPosDelta.lengthSqr() > sqr(dragTolerance3D)?
    Mouse-->>SelectionXlat/CommandXlat: TRUE (click) / FALSE (drag)
    alt is click
        SelectionXlat/CommandXlat->>User: Deselect / Cancel build placement
    else is drag
        SelectionXlat/CommandXlat->>User: Ignore (treat as drag)
    end
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"}}}%%
sequenceDiagram
    participant User
    participant SelectionXlat/CommandXlat
    participant TheTacticalView
    participant Mouse

    User->>SelectionXlat/CommandXlat: MSG_RAW_MOUSE_RIGHT_BUTTON_DOWN
    SelectionXlat/CommandXlat->>TheTacticalView: getPosition()
    TheTacticalView-->>SelectionXlat/CommandXlat: cameraPos0
    Note over SelectionXlat/CommandXlat: Store mouseAnchor0, timeMs0, cameraPos0

    User->>SelectionXlat/CommandXlat: MSG_RAW_MOUSE_RIGHT_BUTTON_UP
    SelectionXlat/CommandXlat->>TheTacticalView: getPosition()
    TheTacticalView-->>SelectionXlat/CommandXlat: cameraPos1
    SelectionXlat/CommandXlat->>Mouse: isClick(mouseAnchor0, mouseAnchor1, cameraPos0, cameraPos1, timeMs0, timeMs1)
    Note over Mouse: timeDelta > dragToleranceMS?
    Note over Mouse: mouseAnchorDelta.lengthSqr() > sqr(dragTolerance)?
    Note over Mouse: cameraPosDelta.lengthSqr() > sqr(dragTolerance3D)?
    Mouse-->>SelectionXlat/CommandXlat: TRUE (click) / FALSE (drag)
    alt is click
        SelectionXlat/CommandXlat->>User: Deselect / Cancel build placement
    else is drag
        SelectionXlat/CommandXlat->>User: Ignore (treat as drag)
    end
Loading

Reviews (3): Last reviewed commit: "bugfix(mouse): Fix bad drag tolerances w..." | Re-trigger Greptile

Comment thread Core/Libraries/Include/Lib/BaseType.h Outdated
@xezon xezon force-pushed the xezon/fix-drag-tolerance-2 branch from 920fa79 to a412fc5 Compare June 23, 2026 19:31
@Skyaero42

Copy link
Copy Markdown

Would be nice if GO could do some A/B testing.

@xezon xezon force-pushed the xezon/fix-drag-tolerance-2 branch from a412fc5 to 8399669 Compare June 28, 2026 06:47
@xezon xezon force-pushed the xezon/fix-drag-tolerance-2 branch from 8399669 to cc8df7b Compare June 28, 2026 06:49
@xezon

xezon commented Jun 28, 2026

Copy link
Copy Markdown
Author

LoGicA

for me test build 2826 is good, i dont have any issue with any building or deselecting
in 2823 i dont think my clicks always register
ive tested this out alot on skirmish

@xezon

xezon commented Jun 28, 2026

Copy link
Copy Markdown
Author

SR_MaD^

both builds were fine for me, but this one was a bit better: #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

2 participants