Search code examples
objective-ccocoawindowmanual

NSWindow is always on top ( or invisible )


I have been working on a project where I am manually creating a floating NSWindow in objective C, based on code from GLFW. The problem is, whenever I run the following code, the window is on top of absolutely everything. When switching to other apps, it is still on top of everything else until I close my app. What I would like is the typical OS X window behavior, where it will go behind other windows who have be come "active".

The problem seems to be related to the line where I call [window orderFront:nil]. But if I don't call that, then my window does not appear at all. Does anybody know what might be causing this?

@interface MyApplicationDelegate : NSObject
@end

@implementation MyApplicationDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
    [NSApp stop:nil];
}

@end

@interface MyWindowDelegate : NSObject
@end

@implementation MyWindowDelegate

- (BOOL)windowShouldClose:(id)sender
{
    return NO;
}

@end


int main(int argc, const char * argv[]) {

[NSApplication sharedApplication];

MyApplicationDelegate* appDelegate = [[MyApplicationDelegate alloc] init];

[NSApp setDelegate:appDelegate];
[NSApp run];


NSRect contentRect = NSMakeRect(0, 0, 400, 400);
unsigned int styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;

NSWindow* window = [[NSWindow alloc]
                     initWithContentRect:contentRect
                     styleMask:styleMask
                     backing:NSBackingStoreBuffered
                     defer:NO];

[window center];
[window setLevel:NSFloatingWindowLevel];

MyWindowDelegate* windowDelegate = [[MyWindowDelegate alloc] init];

[window setTitle:@"Manual"];
[window setDelegate:windowDelegate];

[window orderFront:nil];

while (true)
{
    for (;;)
    {
        NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
                                            untilDate:[NSDate distantPast]
                                               inMode:NSDefaultRunLoopMode
                                              dequeue:YES];
        if (event == nil)
            break;

        [NSApp sendEvent:event];
    }
}
}

Solution

  • I think I may have found the solution. If I add this:

    [window setHidesOnDeactivate:true];                      
    

    ... then the window behaves as I would expect. It boggles my mind a bit that this isn't on by default, but it seems to do what I need.