Automatic Dock manager for macOS — different Dock settings for different displays
SmartDock lives in your menu bar and automatically switches Dock configuration when you connect or disconnect an external monitor. Configure separate settings for each mode — position, icon size, magnification, autohide — and SmartDock applies them instantly.
| Feature | Details | |
|---|---|---|
| 🖥️ | Two-mode Dock profiles | Separate settings for external monitor vs. built-in display |
| 📍 | Position control | Bottom, Left, or Right — per mode |
| 📐 | Icon size & magnification | Independent size sliders for each mode |
| 👁️ | Autohide toggle | Show/hide Dock per mode |
| ⚡ | Instant detection | Event-driven via CGDisplayRegisterReconfigurationCallback — no polling |
| 🔄 | System sync | Auto-imports Dock changes from System Settings via KVO |
| 🔔 | Notifications | macOS banner when profile switches (optional) |
| ⌨️ | Global hotkeys | 5 customizable shortcuts — toggle autohide, refresh, switch profiles, open settings |
| 🎨 | Glass UI | Tabbed settings window (Settings / Shortcuts / About) with NSVisualEffectView |
| 🚀 | Launch at Login | Native SMAppService integration |
| 🛡️ | Smooth transitions | Per-property AppleScript — no Dock restart needed |
| 👋 | Onboarding | Welcome screen on first launch |
brew install --cask alexeikaratai/tap/smartdockAfter install, grant Accessibility permission in System Settings → Privacy & Security → Accessibility.
Download SmartDock.app from Releases. To open unsigned app:
xattr -cr /Applications/SmartDock.app
codesign --force --deep --sign - /Applications/SmartDock.app
open /Applications/SmartDock.appOr: right-click → Open → Open in the dialog.
git clone https://github.com/alexeikaratai/smartdock.git
cd smartdock
make runmake testSources/
├── SmartDockCore/ # Testable business logic
│ ├── DockConfiguration.swift # DockConfiguration + HotkeyBinding + UserPreferences
│ ├── DisplayMonitor.swift # CG callback + debounce for display changes
│ ├── DockController.swift # AppleScript Dock control + KVO system sync
│ ├── SmartDockService.swift # Orchestrator: display state → dock config
│ └── Log.swift # Logger API (macOS 14+)
└── SmartDock/ # AppKit UI layer
├── App.swift # @main entry, manual NSApplication run loop
├── StatusBarController.swift # Menu bar icon & dropdown with SF Symbol icons
├── SettingsWindow.swift # Tabbed glass window (Settings / Shortcuts / About)
├── OnboardingWindow.swift # First-launch welcome screen
├── NotificationManager.swift # macOS banner notifications
├── HotkeyManager.swift # Global keyboard shortcuts (5 actions)
├── LaunchAtLogin.swift # SMAppService wrapper
└── AccessibilityChecker.swift # First-launch Accessibility prompt
| Decision | Why |
|---|---|
| AppleScript via System Events | Graceful Dock updates without killall Dock — no visual glitch, no restart |
Per-property tell blocks |
Each setting applied independently — one failure doesn't block others |
| Debounced display callbacks | 1s settle delay filters transient CG callbacks during Mission Control / fullscreen transitions |
| Swift 6 strict concurrency | @MainActor on all UI and service types — no data races |
| Protocol-based DI | DisplayMonitoring / DockControlling protocols enable mock-based testing |
| Event-driven detection | CGDisplayRegisterReconfigurationCallback — no timers, no polling |
| Diff-based apply | Only runs AppleScript for properties that actually changed — no dock flash |
| KVO system sync | Observes com.apple.dock UserDefaults — auto-imports changes from System Settings |
| Hotkey caching | Bindings cached in memory — no UserDefaults reads on every keystroke |
| Wake recovery | Re-applies config after sleep/wake to fix macOS resetting dock state |
On first launch, SmartDock prompts for Accessibility permission (System Settings → Privacy & Security → Accessibility). This is needed for global keyboard shortcuts. Core dock switching works without it via Automation permission (granted automatically for AppleScript → System Events).
- macOS 14.0+ (Sonoma)
- Swift 6.2+
- Xcode 16+ / Command Line Tools (
xcode-select --install)
Alex Karatai
MIT License. See LICENSE for details.
