Introduction
DockMaster Pro is a powerful, customizable multi-row Dock replacement for macOS. It replaces the native macOS Dock with a feature-rich overlay that supports multiple rows, sections, workspaces, themes, and much more.
Built with Swift and SwiftUI, DockMaster Pro is designed to be fast, lightweight, and beautiful.
Installation
- Download the latest version from the Releases page.
- Choose the appropriate architecture: Universal (recommended), Apple Silicon, or Intel.
- Unzip the downloaded file.
- Drag
DockMaster Pro.appto your Applications folder. - Open the app from Applications. If Gatekeeper blocks it, right-click and select Open.
System Requirements
- macOS 13.0 (Ventura) or later
- Apple Silicon (arm64) or Intel (x86_64)
Permissions
DockMaster Pro requires the following permissions to function properly:
- Accessibility — Required to control the Dock process and manage other applications.
- Apple Events — Required to launch and interact with other applications.
Grant these permissions in System Settings > Privacy & Security > Accessibility.
Quick Start
- Launch DockMaster Pro from Applications.
- Grant Accessibility permission when prompted.
- The app will automatically replace your native Dock with the DockMaster overlay.
- Click the menu bar icon to access settings and workspace switcher.
- Right-click on any dock icon to access context menu options.
Dock Layout
Customize the dock appearance from Settings:
- Position — Bottom, Left, or Right edge of the screen.
- Icon Size — 32px to 128px.
- Max Rows / Columns — Control the grid layout.
- Margin — Distance from the screen edge.
- Auto-hide — Hide when not in use, show on mouse proximity.
Sections
Organize your apps into logical groups:
- Click the + button in Settings to add a new section.
- Drag apps from Finder or Launchpad into any section.
- Right-click a section header to rename or delete it.
- Drag section headers to reorder them.
Workspaces
Create multiple workspaces, each with its own dock layout:
- Open the menu bar extra and select Workspace Switcher.
- Create new workspaces and assign unique dock layouts.
- Bind workspaces to macOS Spaces for automatic switching.
- Assign keyboard shortcuts for instant workspace switching.
Themes
Customize the dock appearance with themes:
- Choose from 3 built-in themes: Dark, Light, and Minimal.
- Edit colors, corner radius, blur intensity, shadows, and icon padding.
- Export themes as
.dmthemefiles to share with others. - Import themes by dragging
.dmthemefiles onto the app.
Quick Search
Press Option + Space to open the search panel:
- Search for installed applications.
- Search for files, documents, and bookmarks.
- View recent items when the search field is empty.
- Use arrow keys to navigate, Enter to open.
Animations
Choose from a rich set of animations:
- 20 hover styles — Bounce, Shake, Pulse, Flip 3D, Glitch, Tada, Heartbeat, and more.
- 8 launch animations — Scale, Fade, Slide, Pop, and more.
- 7 quit animations — Shrink, Fade, Dissolve, and more.
Animations respect the macOS Reduce Motion accessibility setting.
Plugin Development
DockMaster Pro supports a powerful plugin system that allows developers to extend the application's functionality. Plugins can add new widgets, search providers, menu items, themes, and more.
Overview
The plugin system is designed with the following principles:
- Self-contained — Each plugin manages its own localization, configuration, and resources.
- Type-safe — Plugins implement specific protocols based on their functionality type.
- Internationalized — Full support for multi-language plugins using the
PluginLocalizableprotocol. - Hot-swappable — Plugins can be enabled/disabled at runtime without restarting the app.
Plugin Types
DockMaster Pro supports the following plugin types:
| Type | Protocol | Description |
|---|---|---|
| Widget | WidgetPlugin |
Add custom metrics to the status widget (weather, CPU stats, etc.) |
| Search | SearchPlugin |
Extend Quick Search with custom search providers |
| Menu | MenuPlugin |
Add custom items to dock icon context menus |
| Theme | ThemePlugin |
Provide custom themes and icon packs |
| Shortcut | ShortcutPlugin |
Register custom keyboard shortcuts |
| Notification | NotificationPlugin |
Create custom notification rules |
| DataSource | DataSourcePlugin |
Provide external data feeds |
| Layout | LayoutPlugin |
Implement custom dock layout algorithms |
Plugin Structure
Every plugin must implement the base DockMasterPlugin protocol and one or more type-specific protocols:
import SwiftUI
class MyPlugin: WidgetPlugin, PluginLocalizable {
// Required: Plugin metadata
let metadata = PluginMetadata(
id: "com.example.myplugin",
name: "My Plugin",
nameLocalized: [
"en": "My Plugin",
"zh-Hans": "我的插件",
"zh-Hant": "我的外掛",
"ja": "マイプラグイン"
],
version: "1.0.0",
buildNumber: "1",
author: "Your Name",
description: "A sample plugin",
descriptionLocalized: [
"en": "A sample plugin",
"zh-Hans": "一个示例插件",
"zh-Hant": "一個範例外掛",
"ja": "サンプルプラグイン"
],
type: .widget,
icon: "star"
)
// Required: Plugin context (injected by system)
var context: PluginContext?
// Required: Plugin state
private(set) var state: PluginState = .installed
// MARK: - PluginLocalizable
let localizedStrings: [String: [String: String]] = [
"my.label": [
"en": "Label",
"zh-Hans": "标签",
"zh-Hant": "標籤",
"ja": "ラベル"
],
"my.description": [
"en": "Description",
"zh-Hans": "描述",
"zh-Hant": "描述",
"ja": "説明"
]
]
// MARK: - Lifecycle
func activate() async throws {
state = .active
// Initialize your plugin here
}
func deactivate() async {
state = .installed
// Clean up resources here
}
// MARK: - WidgetPlugin
var widgetItems: [PluginWidgetItem] {
[
PluginWidgetItem(
id: "my-item",
name: localized("my.label"),
icon: "star.fill",
value: "42",
detail: localized("my.description")
)
]
}
func updateData() async {
// Refresh your data here
}
// Optional: Configuration view
var configurationView: AnyView? {
AnyView(MyPluginConfigView(plugin: self))
}
}
Internationalization
Plugins should support multiple languages using the PluginLocalizable protocol. This allows your plugin to be used by users worldwide.
Metadata Localization
Provide localized names and descriptions in the PluginMetadata:
let metadata = PluginMetadata(
id: "com.example.plugin",
name: "Default Name", // Fallback language
nameLocalized: [
"en": "Weather",
"zh-Hans": "天气",
"zh-Hant": "天氣",
"ja": "天気"
],
description: "Default description",
descriptionLocalized: [
"en": "Display weather in Dock",
"zh-Hans": "在 Dock 显示天气",
"zh-Hant": "在 Dock 顯示天氣",
"ja": "Dockに天気を表示"
],
// ...
)
UI String Localization
Implement PluginLocalizable for UI strings:
class MyPlugin: WidgetPlugin, PluginLocalizable {
let localizedStrings: [String: [String: String]] = [
"settings.city": [
"en": "City",
"zh-Hans": "城市",
"zh-Hant": "城市",
"ja": "都市"
],
"settings.placeholder": [
"en": "Enter city name",
"zh-Hans": "输入城市名称",
"zh-Hant": "輸入城市名稱",
"ja": "都市名を入力"
]
]
// Use localized strings
var widgetItems: [PluginWidgetItem] {
[PluginWidgetItem(
id: "weather",
name: localized("settings.city"),
icon: "cloud.sun",
value: "22°C"
)]
}
}
Supported Languages
- en — English
- zh-Hans — 简体中文 (Simplified Chinese)
- zh-Hant — 繁體中文 (Traditional Chinese)
- ja — 日本語 (Japanese)
Plugin Permissions
Declare required permissions in your plugin metadata:
let metadata = PluginMetadata(
id: "com.example.plugin",
name: "My Plugin",
version: "1.0.0",
buildNumber: "1",
author: "Your Name",
description: "Description",
type: .widget,
permissions: [.network, .filesystem]
)
Available permissions:
.filesystem— Access to file system.network— Network access for API calls.accessibility— Accessibility features.notifications— Send notifications.workspace— Access workspace data.theme— Access theme data.settings— Access app settings.runningApps— Access running app information
Plugin API Reference
PluginContext
The PluginContext provides access to app functionality:
protocol PluginContext {
// App info
var appVersion: String { get }
var appName: String { get }
// Localization
var currentLanguage: String { get }
func localizedString(_ key: String, _ args: CVarArg...) -> String
// Data access
func getSections() -> [DockSection]
func getPinnedItems() -> [DockPinnedItem]
func getRecentItems() -> [DockItem]
func getWorkspaces() -> [Workspace]
func getCurrentWorkspace() -> Workspace?
func getActiveTheme() -> Theme
// System metrics
func getSystemMetrics() async -> SystemMetricsSnapshot
// Actions
func launchApp(bundleIdentifier: String)
func showNotification(title: String, message: String)
func openSettings()
}
PluginWidgetItem
Represents a widget item displayed in the status widget:
struct PluginWidgetItem {
let id: String // Unique identifier
let name: String // Display name (should be localized)
let icon: String // SF Symbol name
let value: String // Primary value to display
let detail: String? // Optional detail text
}
Complete Example: Weather Plugin
Here's a complete example of a weather plugin:
import SwiftUI
import Foundation
class WeatherPlugin: WidgetPlugin, PluginLocalizable {
let metadata: PluginMetadata
var context: PluginContext?
private(set) var state: PluginState = .installed
// MARK: - Localization
let localizedStrings: [String: [String: String]] = [
"weather.temp": [
"en": "Temperature",
"zh-Hans": "温度",
"zh-Hant": "溫度",
"ja": "温度"
],
"weather.humidity": [
"en": "Humidity",
"zh-Hans": "湿度",
"zh-Hant": "濕度",
"ja": "湿度"
],
"settings.city": [
"en": "City",
"zh-Hans": "城市",
"zh-Hant": "城市",
"ja": "都市"
]
]
// MARK: - Init
init() {
self.metadata = PluginMetadata(
id: "com.example.weather",
name: "Weather",
nameLocalized: [
"en": "Weather",
"zh-Hans": "天气",
"zh-Hant": "天氣",
"ja": "天気"
],
version: "1.0.0",
buildNumber: "1",
author: "Example",
description: "Display weather in Dock",
descriptionLocalized: [
"en": "Display weather in Dock",
"zh-Hans": "在 Dock 显示天气",
"zh-Hant": "在 Dock 顯示天氣",
"ja": "Dockに天気を表示"
],
type: .widget,
icon: "cloud.sun",
permissions: [.network]
)
}
// MARK: - Lifecycle
func activate() async throws {
state = .active
await fetchWeather()
}
func deactivate() async {
state = .installed
}
// MARK: - WidgetPlugin
var widgetItems: [PluginWidgetItem] {
[
PluginWidgetItem(
id: "weather-temp",
name: localized("weather.temp"),
icon: "thermometer",
value: "22°C",
detail: "Sunny"
),
PluginWidgetItem(
id: "weather-humidity",
name: localized("weather.humidity"),
icon: "humidity",
value: "65%"
)
]
}
func updateData() async {
await fetchWeather()
}
// MARK: - Private
private func fetchWeather() async {
// Fetch weather data from API
}
}
Best Practices
- Always localize — Use
PluginLocalizablefor all user-facing strings. - Handle errors gracefully — Don't crash the host app if your plugin fails.
- Clean up resources — Release timers, observers, and network connections in
deactivate(). - Use unique IDs — Ensure your plugin ID and item IDs are globally unique.
- Declare permissions — Only request permissions your plugin actually needs.
- Test thoroughly — Test with all supported languages and macOS versions.
Troubleshooting
App doesn't open
DockMaster Pro is a menu bar app (LSUIElement). It won't show a window on launch. Look for the icon in the menu bar at the top of your screen.
Gatekeeper blocks the app
Right-click the app and select Open from the context menu. Alternatively, go to System Settings > Privacy & Security and click Open Anyway.
Dock doesn't appear
Make sure you've granted Accessibility permission. Go to System Settings > Privacy & Security > Accessibility and ensure DockMaster Pro is enabled.
App crashes on launch
Check the Console app for crash logs. Search for "DockMasterPro" to find relevant entries. Common causes include corrupted preferences — try deleting ~/Library/Application Support/DockMasterPro/ and restarting.