9

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!

Community
  • 1
  • 1
BlackWolf
  • 5,239
  • 5
  • 33
  • 60

2 Answers2

17

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)
Saqib Omer
  • 5,387
  • 7
  • 50
  • 71
Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • 2
    Of course! You're the man, thank you, that absolutely worked. – BlackWolf Mar 29 '15 at 18:02
  • In a document-based application, with this exact setup, how can you force the application to show its menu? The window appears correctly, but without its menu. Switching apps back and forth makes the menu appear correctly. – Oscar Swanros Nov 04 '16 at 23:06
5

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().

Abushawish
  • 1,466
  • 3
  • 20
  • 35
  • 1
    Thanks! Just putting `NSApp.activate(ignoringOtherApps: true)` in my prepare for segue function worked well for me. Calling bringToFront() from windowDidLoad did not. – Josh Jan 15 '19 at 22:40