Skip to content

added option to set any button as "pan" #248

Open
edwonedwon wants to merge 2 commits into
TomBadash:masterfrom
edwonedwon:feature/pan
Open

added option to set any button as "pan" #248
edwonedwon wants to merge 2 commits into
TomBadash:masterfrom
edwonedwon:feature/pan

Conversation

@edwonedwon

Copy link
Copy Markdown

added an option to set any button as "pan" so that you can scroll left on right on mouses that don't have a horizontal scroll wheel

also added an option to settings to "hide in menu bar" as I don't need mouser visible in menu bar always

Adds "Pan", the hand-tool mode Logitech Options+ offers on its gesture
button: hold a mapped button, move the mouse, and the content under the
pointer scrolls in any direction while the pointer stays put. Optional
momentum lets a flick-release "throw" the content so it keeps gliding.

macOS only for now. The logic is platform-neutral; only the scroll
injection is macOS-specific, and config/backend gating keeps the chip out
of the UI on platforms that have not implemented it, so the seam is ready
for Windows/Linux without offering a dead button there.

How it fits the existing code:

* Pan is a second *mode* of the per-button slide machinery that already
  backs Gesture Swipe, not a parallel system. A pan owner is a
  button-gesture owner whose held motion streams out as scroll instead of
  resolving into a discrete swipe, so every platform hook's existing
  button dispatch arms and feeds it unchanged.

* PanScroller (core/pan_scroller.py) owns the delta->scroll math, kept
  separate from GestureRecognizer on purpose: that recognizer is a
  discrete-swipe machine built to reject the sustained slow motion panning
  is made of. It carries sub-unit motion so a slow drag still scrolls.

* Side buttons arm over HID++. Some devices never report a sustained
  side-button hold through the OS (an MX Anywhere 3S over Bluetooth emits
  a ~20ms click on tap and nothing while held), so when a hold mode needs
  xbutton1/xbutton2 their CIDs (0x0053/0x0056) are diverted and the hold
  arms from the HID press -- the same hybrid mode shift already uses.
  Diverts also apply at runtime via a new pending-command on the listener
  loop, so a remap takes effect without waiting for a reconnect.

* Momentum runs the post-release glide on a small ~240 Hz thread with
  drift-corrected timing for a smooth cadence; the decay is dt-based, so
  the tick rate changes only smoothness, never distance. Off by default,
  so a plain Pan mapping keeps its exact feel.

Speed and glide are exposed as sliders on the Pan editor with en/zh
translations. Config migrates v11 -> v12, seeding pan settings; all new
toggles default to preserving existing behavior. Covered by tests/test_pan.py.
Personal-branch addition on top of the Pan feature (not part of the Pan
PR). A 'Hide menu bar icon' toggle on the Point & scroll page removes the
tray / NSStatusItem entirely so Mouser runs with no visible UI; the app
keeps running (window close already only hides it), and relaunching from
Spotlight or Applications activates the running instance via the existing
single-instance socket. Off by default. Applied live -- both the Qt tray
and the native macOS status item are covered. Config migrates v12 -> v13.
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