feat(core): configurable gesture sensitivity and stabler swipe detection - #1245
feat(core): configurable gesture sensitivity and stabler swipe detection#1245robrab2000 wants to merge 3 commits into
Conversation
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.
Greptile SummaryThe 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.
Confidence Score: 3/5The 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
|
| 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]
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); |
There was a problem hiding this comment.
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
| cid == reprog_controls::HAPTIC_PANEL_CID | ||
| && !acc.gestures_down.contains(&cid), |
There was a problem hiding this comment.
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
| AppState::update(cx, |state, cx| { | ||
| state.set_device_gesture_sensitivity( | ||
| &key, | ||
| GestureSensitivity::DEFAULT, | ||
| ); | ||
| cx.emit(StateEvent::SettingsChanged); | ||
| }); |
There was a problem hiding this comment.
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
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
Changes
GestureSensitivity/GestureAxisBias; swipe accumulator settle + contact-kick discard; related tests.Testing
cargo test -p openlogi-core swipecargo test -p openlogi-device gesturecargo test -p openlogi-agent-core hookcargo test -p openlogi-ui localecargo test -p openlogi-desktop i18ncargo clippy -p openlogi-core -p openlogi-device -p openlogi-agent-core --all-targets -- -D warningscargo check -p openlogi-desktop -p openlogi-agentmaster; control capture active and gestures working in manual check.