Make a NSAlert the topmost window?
Asked Answered
U

4

10

I've created the main window in my application to have these settings:

[self setLevel:kCGDesktopWindowLevel + 1];
[self setCollectionBehavior:
     (NSWindowCollectionBehaviorCanJoinAllSpaces | 
      NSWindowCollectionBehaviorStationary | 
      NSWindowCollectionBehaviorIgnoresCycle)];

It's a very custom window that sort of floats above the desktop.

In addition, it's a menu-bar application (LSUIElement).

Alright, so I need to display an alert if something isn't right. Here's how I'm doing it:

NSAlert *alert = [NSAlert alertWithMessageText:@"" 
                                 defaultButton:@"" 
                               alternateButton:@"" 
                                   otherButton:@"" 
                     informativeTextWithFormat:@""];
[alert runModal];

Of course I have filled in the buttons and other text.

Here's my problem: When my application is not currently the key application, and this alert pops up, it's not a key window. Like this:

enter image description here

See how the window isn't selected? Is there any way around this without changing my whole app window level? Thanks!

Ulm answered 11/3, 2011 at 4:57 Comment(0)
P
12

Have you tried activating your application in the code that displays the alert?

[[NSRunningApplication currentApplication] activateWithOptions:0];

If passing 0 doesn't work, you can pass NSApplicationActivateIgnoringOtherApps as your option, but Apple recommends against it unless really necessary (see docs for NSRunningApplication).


Update: You have activate before running the alert. This works for me in a new app with LSUIElement set:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSAlert *alert = [NSAlert alertWithMessageText: @"Blah"
                                     defaultButton: @"Blah"
                                   alternateButton: @"Blah"
                                       otherButton: @"Blah"
                         informativeTextWithFormat: @"Blah"];

    [[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
    [alert runModal];
}
Previous answered 11/3, 2011 at 5:35 Comment(4)
Unfortunately doing so still doesn't fix the problem.Ulm
Did you add it before or after the runModal call? runModal blocks so you have to put the NSRunningApplication call first. See updated answer.Previous
[NSApp activateIgnoringOtherApps:YES] is shorterBurseraceous
If this still isn't working for you, make sure it's the line right before [alert runModal].Laryngology
H
2

If you want to support 10.5 also. you can use

[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
Hexagram answered 29/5, 2012 at 13:1 Comment(0)
D
2

Forcing an application to move forefront is a rather bad idea. One would probably prefer to make the alert floating over everything using the dedicated NSPanel property 'floatingPanel':

NSPanel* panel = static_cast<NSPanel*>([alert window]);
panel.floatingPanel = YES;
Decile answered 6/8, 2018 at 13:51 Comment(0)
C
0

If you need to ensure the NSAlert is topmost use:

alert.window.level = NSFloatingWindowLevel;

Otherwise, if you want the default button to be highlighted, use (as others have suggested):

[[NSApplication sharedApplication] activateIgnoringOtherApps : YES];
Conservancy answered 14/9, 2023 at 15:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.