Skip to content

Ignore trackpad setting for macos#45

Open
iljabauer wants to merge 1 commit intoTomBadash:masterfrom
iljabauer:master
Open

Ignore trackpad setting for macos#45
iljabauer wants to merge 1 commit intoTomBadash:masterfrom
iljabauer:master

Conversation

@iljabauer
Copy link

@iljabauer iljabauer commented Mar 24, 2026

Fixes #35
Hint: I created the code with the help of AI (Human in the loop)

Why

On macOS, Mouser's CGEventTap intercepts all mouse and scroll events regardless of input device. When using a MacBook with both a Logitech mouse and the built-in trackpad, two-finger trackpad gestures (horizontal scrolls) get captured by Mouser and mapped to browser back/forward actions -- making normal trackpad navigation unusable while Mouser is running.

Windows and Linux already have device-level filtering (Raw Input vendor ID filtering and evdev device grabbing respectively), but macOS had no equivalent.

How

The key technical mechanism is the kCGScrollWheelEventIsContinuous CGEvent field:

  • Physical mouse scroll wheels produce discrete/line-based events (field value 0)
  • Trackpads and Magic Mouse produce continuous/pixel-based events (field value 1)

The filter runs at the very top of the CGEventTap callback, before any mapping or blocking logic, so trackpad events pass through the system completely untouched by Mouser.

Edge case handled: Mouser's own scroll-inversion feature posts synthetic events using kCGScrollEventUnitPixel (which would look like trackpad events). These are identified by the existing _SCROLL_INVERT_MARKER in kCGEventSourceUserData and exempted from filtering.

Trade-off: Magic Mouse users who want Mouser to intercept their scroll events will need to disable this setting, since Magic Mouse also uses continuous scrolling. This is acceptable given Mouser targets Logitech mice.

What

Adds an "Ignore trackpad" setting (enabled by default) that filters out trackpad and Magic Mouse events on macOS so Mouser only processes input from discrete mouse scroll wheels.

Config (core/config.py):

  • New ignore_trackpad: true setting in DEFAULT_CONFIG
  • Config version bumped to 6 with migration that defaults existing users to enabled

Event filtering (core/mouse_hook.py):

  • New _is_trackpad_event() helper that uses kCGScrollWheelEventIsContinuous (field 88) to distinguish discrete scroll wheel events (value 0) from continuous trackpad/Magic Mouse events (value 1)
  • For non-scroll events, checks CGEvent field 109 (mouse subtype) which is non-zero for trackpad touch events
  • Early return in _event_tap_callback passes trackpad events through unmodified before any mapping/blocking logic runs
  • Correctly exempts Mouser's own synthetic scroll-inversion events (which use pixel units) by checking the _SCROLL_INVERT_MARKER first

Engine (core/engine.py):

  • Wires the setting to the hook in _setup_hooks(), guarded by hasattr for cross-platform safety

UI (ui/backend.py, ui/qml/ScrollPage.qml):

  • ignoreTrackpad property + setIgnoreTrackpad slot on the backend
  • isMacOS constant property for platform-conditional UI
  • Toggle in the Scroll Direction section, only visible on macOS, with subtitle explaining it also affects Magic Mouse

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.

[macos] create unwanted behavior with the trackpad

1 participant