Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
kCGScrollWheelEventIsContinuousCGEvent field:0)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_MARKERinkCGEventSourceUserDataand 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):ignore_trackpad: truesetting inDEFAULT_CONFIGEvent filtering (
core/mouse_hook.py):_is_trackpad_event()helper that useskCGScrollWheelEventIsContinuous(field 88) to distinguish discrete scroll wheel events (value 0) from continuous trackpad/Magic Mouse events (value 1)_event_tap_callbackpasses trackpad events through unmodified before any mapping/blocking logic runs_SCROLL_INVERT_MARKERfirstEngine (
core/engine.py):_setup_hooks(), guarded byhasattrfor cross-platform safetyUI (
ui/backend.py,ui/qml/ScrollPage.qml):ignoreTrackpadproperty +setIgnoreTrackpadslot on the backendisMacOSconstant property for platform-conditional UI