Skip to content

feat(core): configurable gesture sensitivity and stabler swipe detection - #1245

Open
robrab2000 wants to merge 3 commits into
AprilNEA:masterfrom
robrab2000:feat/gesture-sensitivity-swipe-stability
Open

feat(core): configurable gesture sensitivity and stabler swipe detection#1245
robrab2000 wants to merge 3 commits into
AprilNEA:masterfrom
robrab2000:feat/gesture-sensitivity-swipe-stability

Conversation

@robrab2000

@robrab2000 robrab2000 commented Sep 2, 2026

Copy link
Copy Markdown

Problem

Gesture swipes on MX Master–class mice (especially the gesture button) were easy to mis-trigger or mis-classify: thumb contact often injected a large first-sample “kick,” short accidental motions could commit as flicks, and Left/Right vs Up/Down were hard to balance. Users also had no way to tune how quickly or how far a hold must move before a swipe fires, short of rebuilding with hardcoded thresholds.

Summary

  • Add configurable gesture sensitivity and axis bias (settings UI, TOML, diagnostics, i18n).
  • Harden swipe detection against thumb-contact kick and premature flick commits (settle window, discard first sample, require confirmed post-kick travel).
  • Double-click resets sensitivity/bias sliders to defaults.

Changes

  • openlogi-core: GestureSensitivity / GestureAxisBias; swipe accumulator settle + contact-kick discard; related tests.
  • openlogi-device: gesture session wired to sensitivity/bias and kick-clear when haptic already drops the first jump.
  • openlogi-agent-core: pass tuning into capture/gesture paths; hook tests for settle/kick behavior.
  • openlogi-desktop: Pointer/settings sliders, double-click reset, diagnostics fields (semantic i18n keys).
  • openlogi-ui: locale keys for the new settings copy (all catalogs).

Testing

  • cargo test -p openlogi-core swipe
  • cargo test -p openlogi-device gesture
  • cargo test -p openlogi-agent-core hook
  • cargo test -p openlogi-ui locale
  • cargo test -p openlogi-desktop i18n
  • cargo clippy -p openlogi-core -p openlogi-device -p openlogi-agent-core --all-targets -- -D warnings
  • cargo check -p openlogi-desktop -p openlogi-agent
  • Release rebuild + relaunch on Windows after merging latest master; control capture active and gestures working in manual check.
  • Hardware: gesture L/R/U/D on MX Master gesture button with default and biased settings (maintainer).

Add sensitivity and axis-bias settings with UI and diagnostics, and harden
swipe detection against thumb-contact kick and premature flick commits.
# Conflicts:
#	crates/openlogi-agent-core/src/capture_plan.rs
#	crates/openlogi-agent-core/src/orchestrator.rs
#	crates/openlogi-agent-core/src/runtime/hook.rs
#	crates/openlogi-agent-core/src/runtime/hook/tests.rs
#	crates/openlogi-agent-core/src/watchers/gesture.rs
#	crates/openlogi-agent-core/src/watchers/keyboard.rs
#	crates/openlogi-desktop/src/features/pointer/smartshift.rs
#	crates/openlogi-device/src/session/gesture.rs
Extract capture accumulator init and take CapturedInput by reference so
too-many-lines and needless-pass-by-value stay clean with the new fields.
@robrab2000
robrab2000 requested a review from AprilNEA as a code owner September 2, 2026 12:36
@greptile-apps

greptile-apps Bot commented Sep 2, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds configurable gesture sensitivity and axis bias across persisted configuration, desktop controls, diagnostics, and both gesture-capture paths. It also introduces contact-settle and first-sample filtering, but two source-specific paths can now discard genuine movement.

  • Adds app-wide and per-device sensitivity and axis-bias values with TOML serialization and effective-value resolution.
  • Propagates gesture tuning into HID++ capture sessions and OS-hook gesture maps.
  • Adds settle, contact-kick filtering, directional confirmation, gesture traces, and related tests.
  • Adds desktop sliders, double-click reset behavior, diagnostics fields, and localized copy.

Confidence Score: 3/5

The PR should not merge until genuine motion is preserved in the OS-hook and haptic-panel takeover paths.

The new shared first-sample suppression is applied to OS pointer deltas and can be applied a second time after haptic-panel overlap, causing deliberate swipes to execute click actions or require extra movement.

Files Needing Attention: crates/openlogi-agent-core/src/runtime/hook.rs, crates/openlogi-device/src/session/gesture.rs, crates/openlogi-desktop/src/features/pointer/smartshift.rs

Important Files Changed

Filename Overview
crates/openlogi-core/src/binding/swipe.rs Introduces configurable classification and shared settle/filtering state; unconditional first-sample discard is unsafe for sources without contact-kick packets.
crates/openlogi-device/src/session/gesture.rs Integrates configured accumulators and haptic jump handling, but panel takeover can suppress both the contact jump and the first real delta.
crates/openlogi-agent-core/src/runtime/hook.rs Wires effective tuning into OS-hook holds while unintentionally enabling hardware-specific first-sample filtering for pointer deltas.
crates/openlogi-core/src/config/settings.rs Defines bounded gesture sensitivity and axis-bias value types and their derived recognition thresholds.
crates/openlogi-desktop/src/features/pointer/smartshift.rs Adds per-device sliders and reset behavior; reset emits the wrong state event, leaving parent-rendered labels stale.
crates/openlogi-desktop/src/windows/settings/general.rs Adds app-wide gesture controls and reusable double-click reset presentation.
crates/openlogi-core/src/config/device.rs Adds optional per-device gesture overrides to current and raw persisted configuration shapes.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    Config[App and device gesture settings] --> Plan[Effective capture configuration]
    Plan --> HID[HID++ gesture session]
    Plan --> Hook[OS hook hold]
    HID --> Filter[Settle and contact-kick filtering]
    Hook --> Filter
    Filter --> Classify[Threshold and axis-bias classification]
    Classify -->|Direction committed| Swipe[Directional action]
    Classify -->|No commit before release| Click[Click action]
Loading

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

Reviews (1): Last reviewed commit: "fix(device): satisfy clippy after gestur..." | Re-trigger Greptile

press,
});
self.swipe.begin();
self.swipe.begin_with_config(sensitivity, axis_bias);

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 OS hook drops real motion

When an OS-hook gesture produces one coalesced pointer-move event before release, begin_with_config causes the accumulator to discard that genuine cursor delta as a contact kick. The swipe never commits, so release executes the click binding instead of the intended directional action.

Knowledge Base Used: Background agent service

Fix in Codex Fix in Claude Code

Comment on lines 1018 to 1019
cid == reprog_controls::HAPTIC_PANEL_CID
&& !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 Panel takeover double-drops motion

When the haptic panel remains pressed after an overlapping gesture source releases, the contact jump has already been dropped during the overlap, but takeover starts another accumulator with contact-kick suppression armed. This discards the first real post-takeover delta, causing sparse swipes to become clicks or require additional unintended movement.

Knowledge Base Used: Device integration stack

Fix in Codex Fix in Claude Code

Comment on lines +469 to +475
AppState::update(cx, |state, cx| {
state.set_device_gesture_sensitivity(
&key,
GestureSensitivity::DEFAULT,
);
cx.emit(StateEvent::SettingsChanged);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Reset emits wrong state event

Double-clicking a per-device gesture slider persists the reset but emits SettingsChanged, which this panel's subscription ignores, rather than the DeviceConfigChanged event used by normal slider releases. The child thumb resets directly while the parent-rendered numeric or axis label remains stale until another relevant state change triggers a render.

Knowledge Base Used: Desktop application shell

Fix in Codex Fix in Claude Code

@davidbudnick davidbudnick added type: feature New feature request platform: all Cross-platform issue labels Sep 3, 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: feature New feature request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants