Skip to content

feat(thumbwheel-tap): expose thumbwheel tap separately#341

Open
MoosaTae wants to merge 1 commit into
AprilNEA:masterfrom
MoosaTae:codex/fix-thumbwheel-tap
Open

feat(thumbwheel-tap): expose thumbwheel tap separately#341
MoosaTae wants to merge 1 commit into
AprilNEA:masterfrom
MoosaTae:codex/fix-thumbwheel-tap

Conversation

@MoosaTae

@MoosaTae MoosaTae commented Jul 1, 2026

Copy link
Copy Markdown

What changed

  • default the capacitive thumbwheel tap to Do Nothing
  • expose separate Thumb Wheel Up, Tap, and Down controls in the mouse model
  • preserve explicit existing tap mappings
  • keep rotation capture active on devices that do not advertise single-tap capability
  • add translations, documentation, and focused regression tests

Why

The MX Master 3S reports capacitive tap separately from rotation while the thumbwheel is diverted. OpenLogi hid that tap binding while defaulting it to App Exposé, so rolling and releasing the wheel could trigger App Exposé even when both rotation directions were configured as Do Nothing.

The capture setup also used single-tap support as a prerequisite for all thumbwheel diversion, unintentionally disabling customized rotation on devices without tap support.

User impact

Users can configure rotation and tap independently. Tap is inert by default, while horizontal scrolling remains the default for rotation. Existing explicit tap actions remain intact.

Validation

  • cargo test -p openlogi-core -p openlogi-hid -p openlogi-agent-core --lib — 180 passed
  • cargo +1.94.0 test -p openlogi-gui — 40 passed
  • cargo fmt --all --check
  • git diff --check
  • release macOS app bundle built and codesign verification passed

Rust 1.94 was used for the GUI test and bundle because the current locked smol_str 0.3.6 requires Rust 1.89+, while the local default toolchain is Rust 1.88.

Fixes #340

@MoosaTae MoosaTae marked this pull request as ready for review July 1, 2026 05:19
@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown

Greptile Summary

This PR exposes thumbwheel tap as its own control. The main changes are:

  • Thumbwheel tap now defaults to Do Nothing.
  • Thumbwheel up, tap, and down are separate GUI controls.
  • Rotation capture can run without single-tap support.
  • Locales, docs, and regression tests were updated.

Confidence Score: 5/5

This looks safe to merge after checking whether explicit old tap defaults should arm capture.

  • No blocking issues found in the changed code.
  • The remaining note affects upgraded configs that explicitly stored the old thumbwheel tap action.
  • Core serialization, explicit binding projection, tap capability gating, and GUI localization look consistent.

crates/openlogi-agent-core/src/watchers/gesture.rs

Important Files Changed

Filename Overview
crates/openlogi-core/src/binding.rs Changes the thumbwheel tap label and default action while keeping the enum id stable for stored config.
crates/openlogi-agent-core/src/bindings.rs Adds coverage for the new tap default and preservation of explicit tap bindings.
crates/openlogi-agent-core/src/watchers/gesture.rs Adds thumbwheel arming coverage, but explicit old default tap bindings now arm capture under the new default comparison.
crates/openlogi-hid/src/gesture.rs Separates tap capability from rotation capture and keeps tap dispatch gated by the reported capability.
crates/openlogi-hid/src/thumbwheel.rs Adds regression coverage for independent rotation and tap decoding.
crates/openlogi-gui/src/mouse_model/geometry.rs Replaces one thumbwheel marker with three non-overlapping controls for up, tap, and down.
crates/openlogi-gui/locales/*.yml Adds the new Thumb Wheel Tap translation key across locales.

Fix All in Codex Fix All in Claude Code

Reviews (1): Last reviewed commit: "fix: expose thumbwheel tap separately" | Re-trigger Greptile

let maps = Arc::new(RwLock::new(hook_runtime::HookMaps::default()));
assert!(!thumbwheel_armed(&maps, DEFAULT_THUMBWHEEL_SENSITIVITY));

maps.write()

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 Explicit Default Starts Capture

When an upgraded config contains an explicit Thumbwheel = AppExpose, this check treats it as non-default because the code default is now None. That arms HID++ thumbwheel diversion even if rotation bindings and sensitivity are unchanged, so a user who only preserved the old tap action can have native thumbwheel scroll captured and re-synthesized unexpectedly.

Fix in Codex Fix in Claude Code

@MoosaTae MoosaTae changed the title [codex] expose thumbwheel tap separately feat(thumbwheel-tap): expose thumbwheel tap separately Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Thumbwheel rotation can trigger hidden App Exposé tap binding

1 participant