Skip to content

Add Rotate and Zoom as drag effects - #1862

Open
miguelAngelo1999 wants to merge 2 commits into
noah-nuebling:masterfrom
miguelAngelo1999:feature/drag-rotate-zoom
Open

Add Rotate and Zoom as drag effects#1862
miguelAngelo1999 wants to merge 2 commits into
noah-nuebling:masterfrom
miguelAngelo1999:feature/drag-rotate-zoom

Conversation

@miguelAngelo1999

Copy link
Copy Markdown

Adds rotate and zoom as drag output plugins — hold a button and move the mouse to rotate or zoom.

  • Rotate: horizontal mouse movement → rotation (like twisting 2 fingers on trackpad). Works in Apple Maps, Photos, Preview.
  • Zoom: vertical mouse movement → magnification (like pinching on trackpad). Works in Safari, Maps, any app supporting pinch-to-zoom.

Uses existing TouchSimulator methods with proper phase handling (Began/Changed/Ended/Cancelled).

New files: ModifiedDragOutputRotateZoom.h/.m

miguelAngelo1999 and others added 2 commits April 30, 2026 15:12
…a buttons

Fixes noah-nuebling#1791, noah-nuebling#1790, noah-nuebling#1800, noah-nuebling#1740, noah-nuebling#1744

Logitech mice with extra buttons (thumb, tilt wheel, precision, side buttons)
use HID++ 2.0 ReprogControlsV4 (feature 0x1B04). These buttons are silently
consumed by the mouse firmware until the host sends a SetCidReporting command
to divert them. Once diverted, they arrive as 0x11 long reports.

This implementation calls Buttons.handleInput() directly — no CGEvent
round-trip needed, no extra event tap overhead.

Protocol:
- GetFeature(0x1B04) -> feature index
- GetCount -> number of controls on this device
- GetCidInfo for each control -> CID, TID, capability flags
- Skip controls whose TID maps to a native HID button (L/R/M/Back/Fwd)
- SetCidReporting with flags=0x03 (divert=1, divert_valid=1) for the rest

The flags byte follows the 'valid bit' pattern documented in Solaar
(pwr-Solaar/Solaar hidpp20.py): each flag bit has a corresponding valid bit
= flag << 1, telling firmware the field is being intentionally set.

TID-based filtering correctly excludes natively-reported buttons across all
Logitech models without any per-device hardcoding.

Tested on: Logitech M720 Triathlon (Bluetooth), macOS 15 Sequoia, macOS 26
- Left tilt  (CID=0x005B) -> button 6 in MMF ✅
- Right tilt (CID=0x005D) -> button 7 in MMF ✅
- Thumb      (CID=0x00D0) -> button 8 in MMF ✅
- Back/forward continue working natively (not diverted) ✅

References:
- https://github.com/pwr-Solaar/Solaar (hidpp20.py)
- https://github.com/libratbag/libratbag (hidpp20.c)
- https://lekensteyn.nl/files/logitech/x1b04_specialkeysmsebuttons.html
Hold button + move mouse to rotate or zoom:
- Rotate: horizontal movement → rotation (like twisting 2 fingers on trackpad)
- Zoom: vertical movement → magnification (like pinching on trackpad)

Uses TouchSimulator postRotationEventWithRotation/postMagnificationEventWithMagnification.
Proper phase handling (Began/Changed/Ended/Cancelled).
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.

2 participants