Skip to content

fix: discard first raw-XY sample for all gesture sources - #765

Open
HoneyTyagii wants to merge 1 commit into
AprilNEA:masterfrom
HoneyTyagii:issue-752-gesture-button-first-sample
Open

fix: discard first raw-XY sample for all gesture sources#765
HoneyTyagii wants to merge 1 commit into
AprilNEA:masterfrom
HoneyTyagii:issue-752-gesture-button-first-sample

Conversation

@HoneyTyagii

@HoneyTyagii HoneyTyagii commented Aug 21, 2026

Copy link
Copy Markdown

Summary

Fixes #752

The HID++ raw-XY divert buffer accumulates deltas from the moment diversion is activated, not from when the user starts moving. The first sample after any gesture source press carries this buffered noise and must be discarded for ALL gesture sources, not just the haptic panel.

Problem

Previously, only the HapticPanel (CID 0x01A0) discarded its first raw-XY sample via skip_first_raw_xy. The GestureButton (CID 0x00C3), the primary gesture source on most MX mice, did not, causing the SwipeAccumulator to be poisoned with spurious deltas, resulting in wrong-direction commits.

Example from the issue:

swipe accumulate raw_dx=-81 raw_dy=592  ← first sample, massive dy (buffered noise)
swipe accumulate raw_dx=0  raw_dy=1    accum_dx=-81 accum_dy=593
swipe accumulate raw_dx=3  raw_dy=0    accum_dx=-78 accum_dy=593
...
swipe accumulate raw_dx=28 raw_dy=0    accum_dx=142 accum_dy=598 held_long_enough=true
swipe COMMIT dir=Down accum_dx=142 accum_dy=598  ← wrong direction (should be Right)

All deltas after the first are dx>0, dy=0 (clear rightward swipe), but dy=598 from the first sample dominates the accumulator and forces Down.

Root Cause

In openlogi-hid/src/session/gesture.rs, the skip_first_raw_xy logic was:

acc.skip_first_raw_xy = cid == reprog_controls::HAPTIC_PANEL_CID
    && !acc.gestures_down.contains(&cid);

Only the HapticPanel got the discard, despite the GestureButton exhibiting the same first-sample noise from the HID++ raw-XY divert buffer.

Fix

Changed the logic to apply to ALL gesture sources:

acc.skip_first_raw_xy = !acc.gestures_down.contains(&cid);

Now any newly-pressed gesture source will have its first raw-XY sample discarded, preventing buffered noise from poisoning the SwipeAccumulator.

Testing

Updated the test the_dedicated_buttons_first_sample_is_also_discarded (formerly the_dedicated_buttons_first_sample_is_not_discarded) to verify the new behavior: the first sample is now discarded and the second sample commits the swipe correctly.

Devices Affected

  • MX Master 3/3S/4 with GestureButton (CID 0x00C3)
  • MX Master 4 HapticPanel (CID 0x01A0) already worked, no change in behavior

The HID++ raw-XY divert buffer accumulates deltas from the moment
diversion is activated, not from when the user starts moving. The
first sample after any gesture source press carries this buffered
noise and must be discarded for ALL gesture sources, not just the
haptic panel.

Previously, only the HapticPanel (CID 0x01A0) discarded its first
raw-XY sample. The GestureButton (CID 0x00C3) did not, causing
the SwipeAccumulator to be poisoned with spurious deltas that
resulted in wrong-direction commits.

Fixes AprilNEA#752
@HoneyTyagii
HoneyTyagii requested a review from AprilNEA as a code owner August 21, 2026 16:52
Copilot AI lite review requested due to automatic review settings August 21, 2026 16:52

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@greptile-apps

greptile-apps Bot commented Aug 21, 2026

Copy link
Copy Markdown

Greptile Summary

This PR extends first-sample raw-XY filtering from the haptic panel to every gesture source to prevent buffered motion from selecting the wrong swipe direction.

  • Applies the fresh-press discard to the dedicated gesture button.
  • Updates the gesture test to verify that buffered noise is ignored and the following movement commits.
  • Leaves the skip flag pending when the first report is discarded during a multi-source overlap, causing another report to be lost after overlap.

Confidence Score: 4/5

The overlap transition should be fixed before merging because it can discard genuine dedicated-button movement after the buffered sample was already ignored.

The new skip assignment extends a stale-flag state transition to the dedicated gesture button: overlap drops the buffered report without consuming the flag, so the resumed holder loses its next real report as well.

Files Needing Attention: crates/openlogi-hid/src/session/gesture.rs

Important Files Changed

Filename Overview
crates/openlogi-hid/src/session/gesture.rs Extends first-report filtering to all gesture sources but can double-discard around an overlap transition.
crates/openlogi-hid/src/session/gesture/tests.rs Updates the dedicated-button first-sample test but does not cover press, overlap, and resume behavior.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Fresh gesture-button press] --> B[Set skip_first_raw_xy]
  B --> C[Second source overlaps]
  C --> D[Raw-XY report dropped]
  D --> E[Skip flag remains set]
  E --> F[Second source released]
  F --> G[Next genuine report also dropped]
Loading

Fix all with Greploop Fix All in Codex Fix All in Claude Code

Reviews (1): Last reviewed commit: "fix: discard first raw-XY sample for all..." | Re-trigger Greptile

// The first sample after any gesture source press carries this
// buffered noise and must be discarded for all gesture sources,
// not just the haptic panel.
acc.skip_first_raw_xy = !acc.gestures_down.contains(&cid);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Skip flag survives source overlap

When a dedicated gesture-button press overlaps with a second gesture source, the overlap branch discards the buffered raw-XY report without clearing skip_first_raw_xy; after the second source is released, the pending flag discards the next genuine movement report, causing a short swipe to commit late or be emitted as a click.

Knowledge Base Used: openlogi-hid: device inventory, pairing, and HID++ feature control

Fix in Codex Fix in Claude Code

@davidbudnick davidbudnick added type: bug Something is broken or behaves incorrectly platform: all Cross-platform issue labels Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform: all Cross-platform issue type: bug Something is broken or behaves incorrectly

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: First raw-XY sample after GestureButton press is not discarded — poisons swipe accumulator with spurious deltas

3 participants