Skip to content

Fix Universal Control support#1779

Open
evoleinik wants to merge 1 commit intonoah-nuebling:masterfrom
evoleinik:fix/universal-control-v2
Open

Fix Universal Control support#1779
evoleinik wants to merge 1 commit intonoah-nuebling:masterfrom
evoleinik:fix/universal-control-v2

Conversation

@evoleinik
Copy link
Copy Markdown

Summary

Mac Mouse Fix doesn't work on the receiving Mac when using Universal Control (or other virtual input sources like screen sharing, VMs). This PR fixes three root causes:

  1. Scroll events filtered outScroll.m:eventTapCallback filters scrollPhase != 0, which discards ALL Universal Control scroll events. UC relays trackpad gestures that carry phase data real scroll wheels never have. Fix: skip the scrollPhase filter when CGEventGetSendingDevice returns NULL (virtual input source).

  2. Button events pass through unprocessedButtonInputReceiver.m returns immediately when sendingDev is NULL, so button remapping never happens for UC events. The NO_FILTER macro that would handle this was never defined despite comments saying it should be on ("We're leaving NO_FILTER on for now, because I can't really think of a good reason to filter"). Fix: always use [Device strangeDevice] for unknown sources.

  3. Event taps disabled without physical device — All someDeviceHas* guards in SwitchMaster.swift prevent taps from enabling when no IOHIDDevice is attached. Fix: remove these guards. Event taps that receive no events consume zero CPU.

Additionally:

  • DeviceManager.m: default maxButtonNumberAmongDevices to 5 when no physical devices are attached
  • Scroll.m: remove assert(sendingDev != NULL) that crashes on UC events in pre-release builds

Files changed

File Change
Helper/Core/Scroll/Scroll.m Skip scrollPhase filter for virtual input; remove sendingDev assert
Helper/Core/Buttons/ButtonInputReceiver.m Use strangeDevice for NULL device instead of pass-through
Helper/Core/Coordinate/SwitchMaster.swift Remove all someDeviceHas* guards from toggle functions
Shared/Devices/DeviceManager.m Default to 5 buttons when no devices attached

Testing

  • Compiles clean on Xcode 26.3 / macOS 26.2 SDK (only pre-existing deprecation warnings)
  • Could not test at runtime due to code signing requirements (no development certificate for com.nuebling.mac-mouse-fix)

Issues

Fixes #277, #365, #526, #554, #803, #1235

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

…urces

The previous attempt (865db46) removed someDeviceHas* guards from SwitchMaster
but missed three critical blockers:

1. Scroll.m: eventTapCallback filtered scrollPhase != 0, which discards ALL
   Universal Control scroll events (UC relays trackpad gestures with phase data
   that real scroll wheels never have). Fix: skip the scrollPhase filter when
   CGEventGetSendingDevice returns NULL (virtual input source).

2. ButtonInputReceiver.m: NULL sendingDev caused immediate pass-through, so
   button remapping never happened for UC events. The NO_FILTER macro that
   would have handled this was never defined despite comments saying it should
   be on. Fix: always use strangeDevice for unknown sources.

3. SwitchMaster.swift: all toggle functions still had someDeviceHas* guards
   (v1 only removed some). Fix: remove all guards — event taps that receive
   no events consume zero CPU.

4. DeviceManager.m: default maxButtonNumberAmongDevices to 5 when no physical
   devices are attached.

5. Scroll.m heavyProcessing: remove assert(sendingDev != NULL) that would
   crash on UC events in pre-release builds.

Fixes: noah-nuebling#803, noah-nuebling#1235, noah-nuebling#554, noah-nuebling#526, noah-nuebling#365, noah-nuebling#277

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@evoleinik
Copy link
Copy Markdown
Author

@noah-nuebling Hi Noah! I hope it's OK that I sent an AI-generated PR. Bascially, the point is to make MMF work on the second mac, connected via Universal Control. I can't properly test it on my local mac.

@evoleinik
Copy link
Copy Markdown
Author

Hey Noah, gentle bump on this. 👋

I wasn't able to test at runtime because building without your signing identity means the Helper can't register as a login agent (SMAppService requires a proper code signature with keychain entitlements).

Is there a recommended workflow for contributors to test locally? E.g. a way to bypass the login item registration for dev builds, or should I just sign up for a free Apple Developer account and use automatic signing with my own team ID?

Happy to adjust anything in the PR if you have feedback on the approach.

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.

Mac Mouse Fix settings don't propagate when using universal control

1 participant