Skip to content

alexeikaratai/smartdock

Repository files navigation

SmartDock icon

SmartDock

Automatic Dock manager for macOS — different Dock settings for different displays

Version 1.8.2 macOS 14+ Swift 6.2 MIT License


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.

✨ Features

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

📸 Screenshot

SmartDock Settings

📦 Installation

From Homebrew

brew install --cask alexeikaratai/tap/smartdock

After install, grant Accessibility permission in System Settings → Privacy & Security → Accessibility.

From GitHub Release

Download SmartDock.app from Releases. To open unsigned app:

xattr -cr /Applications/SmartDock.app
codesign --force --deep --sign - /Applications/SmartDock.app
open /Applications/SmartDock.app

Or: right-click → Open → Open in the dialog.

From Source

git clone https://github.com/alexeikaratai/smartdock.git
cd smartdock
make run

🧪 Run Tests

make test

🏗️ Architecture

Sources/
├── 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

Key Design Decisions

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

🔐 Permissions

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).

🛠️ Requirements

  • macOS 14.0+ (Sonoma)
  • Swift 6.2+
  • Xcode 16+ / Command Line Tools (xcode-select --install)

👤 Author

Alex Karatai

📄 License

MIT License. See LICENSE for details.

About

Automatic Dock manager for macOS — different Dock settings for different displays. Lives in menu bar, switches Dock config instantly when external monitor connects or disconnects.

Topics

Resources

License

Stars

Watchers

Forks

Packages