6
votes

I am developing a menubar-only application for OS X and I am struggeling to get a settings window to show up in front of other apps.

App setup

"Menubar-only application" means:

  • I removed the "Is Initial Controller" from the NSWindowController in the main storyboard file. The main storyboard's window is not used in my app
  • I added an NSMenu to the "Application Scene" in the main storyboard. This will become my menubar menu
  • I set LSUIElement to YES to hide the dock icon
  • I set LSBackgroundOnly to NO (see NSWindow makeKeyAndOrderFront makes window appear, but not Key or Front)

When the app starts, I create an NSStatusItem and add the NSMenu from the storyboard as its menu. This all works fine - the app starts, shows no window and no dock icon but a menubar item that contains the menu from the storyboard.

Settings window

I now wanted to add a settings window that is shown when a menubar entry is clicked. I therefore:

  • Created a new .xib-file and added an NSWindow to it
  • Created a custom NSWindowController that connects the outlets and actions
  • Instantiated the custom NSWindowController using initWithNibNamed: on app launch

When the "Settings"-entry from the menu is clicked, I then try to bring the settings window to front using:

[self.settingsWindowController.window center];
[self.settingsWindowController.window showWindow:self];
[self.settingsWindowController.window makeKeyAndOrderFront:NSApp];

The window is shown, but not brought to the front but rather hidden behind other apps.

Any ideas how to solve this? Thanks!

2

2 Answers

13
votes

You need to call:

[NSApp activateIgnoringOtherApps:YES];

(This is one of the rare occasions where it's correct to pass YES to that method.)

For Swift you can use

NSApp.activate(ignoringOtherApps: true)
4
votes

I know you're asking for obj-c and already received an answer, but just incase anyone is Googling for Swift 4 implementation.

In your class that extends NSWindowController define the function:

func bringToFront() {
  self.window?.center()
  self.window?.makeKeyAndOrderFront(nil)
  NSApp.activate(ignoringOtherApps: true)
}

Then whenever you wanna bring it up, call bringToFront().