objective-ccocoaxcode4nswindowcontrollernspanel

How to tell when NSPanel gets focus or becomes key?


I am writing a Cocoa/Objective-C app in XCode4, and I need to know when my preferences panel is opened. I need some callback like windowDidBecomeKey; I attempted to follow the solution provided in this question, but neither windowDidBecomeKey or windowDidExpose appear as delegate methods(but others, like windowDidLoad, windowWillLoad, etc do).

To clarify exactly what I mean by "don't appear as delegate methods", I mean they don't show up in the auto complete when I begin typing the method name. I did try defining them anyway, but they were never called.

Do NSPanel objects lack these methods, or is there something more I have to do?

Currently, I have an interface PrefWindowController:

PrefWindowController.h:

#import <Cocoa/Cocoa.h>

@interface PrefWindowController : NSWindowController
    //Delegate methods like windowDidBecomeKey appear to not be available here
@end

PrefWindowController.m:

@implementation PrefWindowController

- (id)initWithWindow:(NSWindow *)window
{
    self = [super initWithWindow:window];
    if (self) {
        NSAlert *alert = [[[NSAlert alloc] init] autorelease];
        [alert setMessageText:@".."];
        [alert runModal];
    }

    return self;
}

- (void)windowDidLoad
{
    NSAlert *alert = [[[NSAlert alloc] init] autorelease];
    [alert setMessageText:@"Loaded"];
    [alert runModal];
}

@end

When the window loads from the .xib as the application starts, windowDidLoad fires and the notification defined above is shown. I did this just to test that methods were actually getting called.

Any advice about how to get a callback for when the panel becomes key or takes focus would be very helpful.

Update:

I added a windowDidBecomeKey method to the window controller, like so:

PrefWindowController.h:

- (void)windowDidBecomeKey:(NSNotification *)notification;

PrefWindowController.m:

- (void)windowDidBecomeKey:(NSNotification *)notification
{
    NSLog(@"Test");
}

The test message gets logged the first time I open the window, but on the return line in my main.m file I get the error:

Thread 1: Program Received Signal: "EXC_BAD_ACCESS"


Solution

  • The NSWindowDelegate protocol has the following methods

    - (void)windowDidBecomeKey:(NSNotification *)notification
    - (void)windowDidResignKey:(NSNotification *)notification
    

    so you can set your NSWindowController as the NSWindow delegate to get this callback. You can also register for these notifications:

    NSWindowDidResignKeyNotification
    NSWindowDidBecomeKeyNotification
    

    NSPanel is an NSWindow subclass so all this behaviour applies in your case.