I'm building a macOS menu bar app with SwiftUI's new MenuBarExtra
API and running into a bit of an odd issue.
I've implemented a settings window that I can open with the following call:
if #available(macOS 13, *) {
NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil)
} else {
NSApp.sendAction(Selector(("showPreferencesWindow:")), to: nil, from: nil)
}
I've also set the Application is agent
flag to YES
in info my project's properties.
Unfortunately, whenever I open the settings window via the MenuBar, it opens in the background and isn't visible at all. I'm really not sure how to proceed from here. I've thought about the following:
Has anyone come across this issue and implemented a solution to it?
You can change the activation policy programatically. Before you open your preferences, run the following code:
NSApp.setActivationPolicy(.regular) //makes the app a "normal" app again with a menu bar and a visible dock icon
NSApp.activate(ignoringOtherApps: ignoringOtherApps) // Activates the app in order to bring the window to front. Otherwise your window may be hidden behind windows of other apps
As soon as your last window closes, make the app an agent/accessory app again:
NSApp.hide(self)
NSApp.setActivationPolicy(.accessory)
You may want to use this extension:
extension NSApplication {
static func show(ignoringOtherApps: Bool = true) {
NSApp.setActivationPolicy(.regular)
NSApp.activate(ignoringOtherApps: ignoringOtherApps)
}
static func hide() {
NSApp.hide(self)
NSApp.setActivationPolicy(.accessory)
}