Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In OS X, how can I detect when the currently active application changes?

Trying to write an application for OS X that triggers a behavior depending on which application is current. It doesn't need to interact with it. It just needs to know when it's changed, and to what.

Can anyone recommend which APIs are available for this? My guess would be something in the assistive services since that's what most apps like BetterTouchTool and similar need to interact with the current application. However, those applications directly manipulate those windows whereas I'm looking only for read-only access, therefore I'm not sure if that's needed.

Any guidance or referring links to something similar would be greatly appreciated.

(P.S. Sorry about the tags. Nothing I tried was there 'active application', 'current application', 'focused application' all drew blanks.)

like image 518
Mark A. Donohoe Avatar asked Feb 22 '23 13:02

Mark A. Donohoe


1 Answers

You can use NSWorkspace to get notified when an app becomes active (NSWorkspaceDidActivateApplicationNotification) or resigns active (NSWorkspaceDidDeactivateApplicationNotification). See the documentation on NSWorkspace for more info.

In your controller class, you'd do something like this:

- (id)init {
   if ((self = [super init])) {
       [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
                             selector:@selector(appDidActivate:)
                            name:NSWorkspaceDidActivateApplicationNotification
                              object:nil];
   }
   return self;
}

- (void)dealloc {
    [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
    [super dealloc];
}

- (void)appDidActivate:(NSNotification *)notification {
   NSDictionary *userInfo = [notification userInfo];
   NSLog(@"userInfo == %@", userInfo);

}

The key points are basically that you need to register to receive the notifications like shown in -init. You'd repeat the code to add another observer for each additional notification name that you want (e.g NSWorkspaceDidDeactivateApplicationNotification).

Another important thing to remember is to remove yourself as an observer in -dealloc (or elsewhere), so that NSWorkspace doesn't try to notify your controller object after it's been released+dealloc'd (and would no longer be valid).

In the specified -appDidActivate: method, do whatever you need to with the info about the app in question.

like image 130
NSGod Avatar answered May 15 '23 00:05

NSGod