MagicMirror flips an Apple Magic Trackpad for upside-down use on macOS.
It does not warp the cursor, intercept pointer events, or require BetterTouchTool. Instead, it calls Apple's private MultitouchSupport framework to set the trackpad surface orientation directly.
With trackpads that have different ProductIDs, it can keep one normal and
another flipped durably. mt-orient assigns orientation by ProductID — a model
identifier that is stable across USB and Bluetooth, but is not unique to one
physical unit — and re-applies it across reconnects, wake, and login. Two units
that report the same ProductID necessarily share one policy.
Apple's Magic Trackpad is physically comfortable upside down in some desk setups, but macOS does not expose a modern setting for mirroring pointer and scroll directions. Event-tap approaches can make the direction correct, but they often cause ghost cursors, jitter, stuck clicks, or jumpy motion.
MagicMirror uses the same class of driver-level orientation path that dedicated tools use, but packages it as a tiny local helper.
git clone https://github.com/smkwray/magicmirror.git
cd magicmirror
./install.shThe installer compiles src/mt-orient.m, installs runtime scripts under:
~/.hammerspoon/trackpad-orientation/
and installs a login LaunchAgent:
~/Library/LaunchAgents/com.smkwray.magicmirror.plist
The installer creates and starts a user KeepAlive LaunchAgent immediately.
A first install is policy-neutral: edit orient.conf before any trackpad will be
changed. Reinstalling preserves an existing mapping.
Apply upside-down orientation for the configured toggle-target:
~/.hammerspoon/trackpad-orientation/apply-upside-down.shApply normal orientation:
~/.hammerspoon/trackpad-orientation/apply-normal.shToggle saved state:
~/.hammerspoon/trackpad-orientation/toggle.shList detected multitouch devices:
~/.hammerspoon/trackpad-orientation/mt-orient listExample output:
device 0: transport=1 builtIn=0 product=804 desired=0
transport is an undocumented diagnostic value and is not used as identity.
MagicMirror exposes only the verified orientations: 0 normal and 2
upside-down. Quarter-turn values are not supported by this tool.
The original mt-orientation helper flips all external Bluetooth trackpads
to the same orientation. That cannot express "trackpad A normal, trackpad B
flipped", and it breaks when a device moves between USB and Bluetooth (the
device index and transport both change).
mt-orient keys orientation to ProductID.
It correlates every live multitouch device to its IOKit AppleMultitouchDevice
record (matching MTDeviceGetDeviceID to the IOKit Multitouch ID) and reads
ProductID — a fixed hardware model id that does not change with the cable.
It is not a unique unit identifier: two same-model trackpads that report the same
ProductID cannot receive different policies. Transport, device index, GUID, and
the reported serial are connection-dependent and therefore unsuitable as keys.
Configure the mapping in ~/.hammerspoon/trackpad-orientation/orient.conf:
# <productID> <normal|upside-down>; unlisted ProductIDs are left untouched
product 804 normal
product 613 upside-down
# Optional default for toggle.sh / apply-*.sh when no argument is supplied:
toggle-target 613
Find your ProductIDs with mt-orient list. Commands:
mt-orient list # show devices, ProductIDs, and resolved orientation
mt-orient apply # apply the config once
mt-orient watch # daemon: re-apply on reconnect/wake, self-heal every 60s
mt-orient reset # force all external trackpads back to normalThe installer runs mt-orient watch from the login LaunchAgent with
KeepAlive, so the per-ProductID orientation survives reconnect, sleep/wake, and
reboot. The toggle.sh / apply-*.sh scripts edit orient.conf and re-apply,
so the manual shortcut and the daemon cooperate instead of fighting.
Hammerspoon:
- Copy
examples/hammerspoon-menubar.luainto~/.hammerspoon/init.lua. - It adds a small
TP UD/TP OKmenu bar item.
./uninstall.shThis resets the trackpad to normal, unloads the LaunchAgent, and removes the installed runtime folder.
src/mt-orient.m dynamically loads:
/System/Library/PrivateFrameworks/MultitouchSupport.framework/MultitouchSupport
and calls:
MTDeviceCreateList
MTDeviceGetTransportMethod
MTDeviceIsBuiltIn
MTDeviceGetDeviceID
MTDeviceSetSurfaceOrientation
The manager skips built-in devices and resolves external devices through IOKit. It does not gate behavior on a particular private transport number.
This uses private Apple API. It is free and local, but Apple could rename or remove these symbols in a future macOS release.
- Ask Different: palm rejection on Apple Trackpad 2
- Ask Different: reverse Magic Trackpad
- Cult of Mac: use Magic Trackpad upside down
MIT