Show/Hide dock icon on macOS App
If you are looking for just hide dock icon on macOS App, check it here How to hide the Dock icon.
Sometimes this needs to be configurable, like Dash and CloudApp.
When you wish to hide the Dock icon of your macOS app, you can achieve this by setting setActivationPolicy
to accessory
or regular
, representing “hide” and “regular” modes, respectively. But there is some unexpected side effect:
Some apps, like Dash, may briefly display their Dock icon during launch before hiding it programmatically. Because show dock icon is set to true by default, and there is not such LSUIElement
in its Info.plist
.
To avoid this behavior, you can set the LSUIElement
to YES
in the app’s Info.plist
file. By combining this setting with the setActivationPolicy
set to regular
the Dock icon will remain hidden during launch.
For some reason, When setting the setActivationPolicy
to regular
, all app windows may automatically hide, which is not the desired behavior. Take a look at below gif. You may notice that the window is flashing when toggling the icon. Because hide the icon will hide the window as well.
To retain app windows while hiding the Dock icon, similar to CloudApp’s behavior, consider implementing NSApp.activate(ignoringOtherApps: true)
in the main thread to enforce app activation.
In this case, CloudApp probably implemented NSApp.activate(ignoringOtherApps: true)
in the main thread to enforce app activation.. And as you can see, there’re more than one dock icon as you click fast.
To address the first issue, you can set the window’s canHide
property to false
. Although this may prevent the window menu from showing until it is reopened, it effectively avoids the Dash-like icon display during app launch.
To tackle the second issue, set a scheduled timer of around 0.3 seconds. Every time the user changes the Dock icon setting, invalidate the timer and reschedule it accordingly. This approach ensures that the app responds smoothly and avoids multiple dock icons appearing with rapid clicks.
var timer: Timer?
func showDockIconClicked(_ sender: Any) {
timer?.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: 0.3, repeats: false, block: { _ in
// toggle dock icon shown/hidden.
})
}
That’s it! Here is the result:
If you have alternative, more elegant methods for handling these scenarios, feel free to share your valuable insights.