Skip to content

Add remappable support for horizontal scroll wheel tilt actions#359

Open
srako wants to merge 3 commits into
AprilNEA:masterfrom
srako:master
Open

Add remappable support for horizontal scroll wheel tilt actions#359
srako wants to merge 3 commits into
AprilNEA:masterfrom
srako:master

Conversation

@srako

@srako srako commented Jul 6, 2026

Copy link
Copy Markdown

…buttons

Add WheelLeft and WheelRight to the ButtonId enum so the main scroll wheel's horizontal tilt — which arrives as a horizontal scroll event at the OS hook, not as a button press — can be intercepted and remapped to any Action, just like a physical button.

Core changes:

  • binding.rs: WheelLeft/WheelRight variants, ALL array, labels, and default bindings (native horizontal scroll, pass-through)
  • hook_runtime.rs: intercept MouseEvent::Scroll with non-zero delta_x from a non-trackpad source; look up the bound action and dispatch it with a 250ms per-direction cooldown so one deliberate tilt fires once
  • mouse_buttons.rs: GUI hotspots flanking the middle-click area
  • geometry.rs: with_wheel_tilt() auto-derives tilt hotspots from the MiddleClick position; default_labels() updated for the new buttons

Default behavior is unchanged: unbound or default-bound tilt events pass through as native horizontal scroll. Only when the user maps WheelLeft/WheelRight to a non-default action does the hook suppress the scroll event and fire the bound action instead.

…buttons

Add WheelLeft and WheelRight to the ButtonId enum so the main scroll
wheel's horizontal tilt — which arrives as a horizontal scroll event at
the OS hook, not as a button press — can be intercepted and remapped
to any Action, just like a physical button.

Core changes:
- binding.rs: WheelLeft/WheelRight variants, ALL array, labels, and
  default bindings (native horizontal scroll, pass-through)
- hook_runtime.rs: intercept MouseEvent::Scroll with non-zero delta_x
  from a non-trackpad source; look up the bound action and dispatch it
  with a 250ms per-direction cooldown so one deliberate tilt fires once
- mouse_buttons.rs: GUI hotspots flanking the middle-click area
- geometry.rs: with_wheel_tilt() auto-derives tilt hotspots from the
  MiddleClick position; default_labels() updated for the new buttons

Default behavior is unchanged: unbound or default-bound tilt events
pass through as native horizontal scroll. Only when the user maps
WheelLeft/WheelRight to a non-default action does the hook suppress
the scroll event and fire the bound action instead.
@greptile-apps

greptile-apps Bot commented Jul 6, 2026

Copy link
Copy Markdown

Greptile Summary

This PR makes horizontal wheel tilt actions remappable. The main changes are:

  • Added WheelLeft and WheelRight button IDs with default native scroll bindings.
  • Added hook handling for non-trackpad horizontal scroll events.
  • Added cooldown handling so one tilt burst fires a custom action once.
  • Added GUI hotspots and labels for wheel tilt bindings.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
crates/openlogi-agent-core/src/hook_runtime.rs Adds horizontal wheel tilt interception, pass-through handling for native scroll bindings, and cooldown-based custom action dispatch.
crates/openlogi-core/src/binding.rs Adds wheel tilt button IDs, labels, catalog entries, and native horizontal scroll defaults.
crates/openlogi-gui/src/data/mouse_buttons.rs Adds fallback wheel tilt hotspots to the mouse button model.
crates/openlogi-gui/src/mouse_model/geometry.rs Derives wheel tilt hotspots from the middle-click geometry and updates default label placement.

Reviews (3): Last reviewed commit: "fix(wheel): suppress entire tilt burst t..." | Re-trigger Greptile

Comment thread crates/openlogi-agent-core/src/hook_runtime.rs
Comment thread crates/openlogi-agent-core/src/hook_runtime.rs Outdated
…mbwheel

Two bugs found in code review (PR AprilNEA#359):

1. (P1) Horizontal scroll from a thumbwheel (or any non-tilt source)
   was suppressed whenever WheelLeft/WheelRight had a custom binding,
   breaking native thumbwheel scrolling. Fix: only suppress when we
   actually fire the action; pass through when the cooldown blocks
   the fire so continuous horizontal wheels keep scrolling.

2. (P2) Action::None suppressed native horizontal scroll instead of
   passing it through. Fix: treat None the same as the default binding
   — pass through so the user keeps native scrolling.
Comment thread crates/openlogi-agent-core/src/hook_runtime.rs Outdated
Greptile review (PR AprilNEA#359, comment 3) found that the previous fix for
thumbwheel compatibility (passing through when the cooldown blocks)
introduced a scroll leak: the remaining events in a wheel-tilt burst
pass through as native horizontal scroll, so a tilt mapped to e.g.
Mission Control also nudges the page sideways.

Fix: always Suppress when a custom action is bound, regardless of
whether the cooldown allows a fire. The cooldown still prevents
repeated dispatches, and the entire burst is consumed so no native
scroll leaks.

Document the known limitation: on devices with both a tilt wheel and
a thumbwheel (e.g. MX Master 3S), mapping WheelLeft/WheelRight will
also intercept the thumbwheel's native scroll. Users who need native
thumbwheel scroll should not remap these buttons.
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.

1 participant