← Home

Dynamically toggle visibility of macOS app’s dock icon

Show and hide a macOS app's dock icon at runtime by switching its activation policy – without losing window focus or keyboard input.

Some macOS apps live in the menu bar but still want an optional dock icon – a preference power users can flip on or off. The catch: changing the dock icon at runtime tends to steal focus, drop the app's window, or leave a duplicate icon behind. Here's the approach I settled on.

macOS derives the dock icon from the app's activation policy: .regular shows it, .accessory hides it. Toggling the icon is really just switching between the two:

extension NSApplication {
    static func toggleActivationPolicy() {
        let current = NSApp.activationPolicy()
        let next: NSApplication.ActivationPolicy = current == .regular ? .accessory : .regular
        NSApp.setActivationPolicy(next)

        // Switching to .accessory deactivates the app – bring it back.
        if next == .accessory { NSApp.activate() }
    }
}

Three details make it behave:

Mark the app as an agent. Add Application is agent (UIElement) = YES to Info.plist so it can start without a dock icon.

Launch without stealing focus. Set .prohibited in applicationWillFinishLaunching, then your real policy in applicationDidFinishLaunching – and open the window yourself, since .prohibited stops SwiftUI from doing it for you.

Debounce the toggle. The dock's show/hide animation takes a moment; flip faster than that and you can end up with two icons. A ~150 ms guard between toggles avoids it.

Through all of this the window keeps keyboard focus, so shortcuts keep firing while the icon comes and goes. Full sample on GitHub:

(GitHub Repo) Dynamically toggle visibility of macOS app’s dock icon

A SwiftUI sample that toggles the dock icon at runtime.

It's the runtime companion to Fine-Tuning macOS App Activation Behavior, which covers these activation policies in depth.