A headless macOS daemon that keeps the Dock anchored to a specific display in multi-monitor setups.
By default, macOS lets the Dock migrate to whichever display the cursor approaches — anchor stops that. It intercepts mouse movements near the Dock trigger zones on non-anchor displays and, if the Dock ever drifts, nudges it back automatically at startup.
- macOS (tested on macOS Sequoia)
- Swift compiler (
swiftc) — included with Xcode Command Line Tools
Important
The binary must be granted Accessibility access before it can intercept mouse events: System Settings → Privacy & Security → Accessibility
1. Compile the binary
swiftc -framework Cocoa -framework ApplicationServices anchor.swift -o anchor2. Move it somewhere on your PATH (the default plist expects /usr/local/bin/anchor)
sudo mv anchor /usr/local/bin/anchor3. Install the LaunchAgent to run anchor automatically at login
cp flesch.anchor.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/flesch.anchor.plistanchor [display_index] # 0 = primary display (default), 1 = second display, etc.
anchor --list # print available displays and exit
# Anchor the Dock to the primary display (default)
anchor
# Anchor the Dock to the second display
anchor 1
# List available displays
anchor --list
# [0] Built-in Display (primary) — (0.0, 0.0, 1512.0, 982.0)
# [1] Pro Display XDR — (1512.0, 0.0, 3008.0, 1692.0)On startup, anchor:
- Enumerates active displays and selects the anchor display by index.
- Detects where the Dock currently lives using the Accessibility API.
- If the Dock is on the wrong display, it synthesizes a smooth mouse movement to the anchor display's Dock trigger zone to relocate it.
- Installs a low-level
CGEventTapthat blocks mouse movements from entering the Dock trigger zone on any non-anchor display, preventing macOS from moving the Dock away.
Synthetic events are tagged with a private marker so anchor can distinguish its own events from real user input and never accidentally blocks itself.
The flesch.anchor.plist LaunchAgent can be customized:
| Key | Default | Description |
|---|---|---|
ProgramArguments |
/usr/local/bin/anchor |
Path to the binary. Add a display index as a second argument to pin to a non-primary display. |
KeepAlive |
true |
Restart automatically if the daemon crashes. |
StandardOutPath |
/tmp/anchor.log |
Stdout log file. |
StandardErrorPath |
/tmp/anchor.err |
Stderr log file. |
To reload after changes:
launchctl unload ~/Library/LaunchAgents/flesch.anchor.plist
launchctl load ~/Library/LaunchAgents/flesch.anchor.plistThe Dock still moves to another display
Make sure the binary has been granted Accessibility access. anchor will print a warning and exit if the permission is missing.
Failed to create event tap
Revoke and re-grant Accessibility access in System Settings, then restart anchor.
Checking logs
tail -f /tmp/anchor.log
tail -f /tmp/anchor.err