13

I want to be notified when the current application will change. I looked at NSWorkspace. It will send notifications only when your own application becomes active or loses the activity. I want to be informed about every application. How can I do this in Cocoa?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
cocoafan
  • 4,884
  • 4
  • 37
  • 45
  • 2
    It is impossible to get this information from Cocoa. You have to use the Carbon Event Manager to get notifications on when a process other than your own becomes active. – Jason Coco Apr 18 '09 at 06:14

2 Answers2

26

If you're targeting 10.6 or later there's a notification for this:

// NSWorkspaceDidActivateApplicationNotification
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(foremostAppActivated:) name:NSWorkspaceDidActivateApplicationNotification object:nil];

Apple docs: http://developer.apple.com/library/mac/DOCUMENTATION/Cocoa/Reference/ApplicationKit/Classes/NSWorkspace_Class/Reference/Reference.html#//apple_ref/doc/uid/20000391-SW97

mrwalker
  • 1,883
  • 21
  • 23
  • Confirmed working in 2014 on OS X 10.9 (except I had to remove the colon in the @selector method). Thank you! – Jimmie Tyrrell Jun 19 '14 at 09:10
  • 1
    The colon is there because I expect your selector to look like this: `- (void)foremostAppActivated:(NSNotification *)notification` – mrwalker Jun 26 '14 at 11:24
13

Thank you Jason. kEventAppFrontSwitched in Carbon Event Manager is the magic word

- (void) setupAppFrontSwitchedHandler
{
    EventTypeSpec spec = { kEventClassApplication,  kEventAppFrontSwitched };
    OSStatus err = InstallApplicationEventHandler(NewEventHandlerUPP(AppFrontSwitchedHandler), 1, &spec, (void*)self, NULL);

    if (err)
        NSLog(@"Could not install event handler");
}

- (void) appFrontSwitched {
    NSLog(@"%@", [[NSWorkspace sharedWorkspace] activeApplication]);
}

And the handler

static OSStatus AppFrontSwitchedHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
    [(id)inUserData appFrontSwitched];
    return 0;
}
cocoafan
  • 4,884
  • 4
  • 37
  • 45
  • Yeah, I made a little example for somebody that actually posted notifications a while back, but I couldn't find it. You gave a nice summary, you should accept this answer :) – Jason Coco Apr 18 '09 at 07:16
  • Remark: To successfully build an application using this, you have to add the Carbon and Core Services Frameworks to your build and include and in the implementation file that contains the handler. See http://stackoverflow.com/questions/801976/mixing-c-functions-in-an-objective-c-class/ on how to mix C with Objective-C – Christoph Aug 06 '09 at 17:40