Resolved Get Prior Active Application?

Discussion in 'Mac Programming' started by ArtOfWarfare, Oct 16, 2013.

  1. ArtOfWarfare, Oct 16, 2013
    Last edited: Oct 17, 2013

    ArtOfWarfare macrumors G3


    Nov 26, 2007
    I implemented this in my Application Delegate expecting that it would tell me which Application had been active before my own became active:

    - (void)applicationWillBecomeActive:(NSNotification *)notification {
        NSLog(@"Am I active? %hhd", [NSRunningApplication currentApplication].active);
        for (NSRunningApplication * application in [[NSWorkspace sharedWorkspace] runningApplications]) {
            if ( {
                NSLog(@"%@ is active <----------------", application.localizedName);
            } else {
                NSLog(@"%@ is not active", application.localizedName);
        NSLog(@"Becoming active!");
    - (void)applicationDidBecomeActive:(NSNotification *)notification {
        NSLog(@"Did become active!");
    Unfortunately, despite what the title of the method would suggest, it seems that this code is called after the application has already become active. When I run the code, I consistently see printed to the console:

    "Am I active? 1", meaning it's active immediately when this method is entered.
    long list of running but not active applications, mine not in that part of the list
    my application, marked as the active one, immediately follow by
    "Becoming active!", immediately followed by
    "Did become active!"

    So... any suggestions about how I can get the previously activated application? I'd rather not poll in the background continuously.

    The reason I want this is because I have a button in my application which toggles whether it floats above all other applications or has ordinary windows. When this button is clicked toggling it off, I don't want the application to become active by the button being clicked. I can't find any way to block it from becoming active, so I'd rather just check, when the button is clicked, which application was active immediately prior and how long ago was it deactivated - if it was deactivated only 0.02 seconds ago or so, it means that it only was deactivated by the button being pressed and so it should be made the active application now.

    Edit: Just checked - I can poll for the current application in the background, but this doesn't seem like a particularly good solution to my problem. I intend for my application to be running 24/7, but for it to only want this kind of information once or twice an hour (if that often)... it's an awfully high cost for an awfully low priority feature.
  2. Red Menace macrumors 6502

    Red Menace

    May 29, 2011
    Littleton, Colorado, USA
    Maybe register for a NSWorkspaceDidActivateApplicationNotification notification and keep track of the latest one that isn't your application?
  3. ArtOfWarfare, Oct 16, 2013
    Last edited: Oct 17, 2013

    ArtOfWarfare thread starter macrumors G3


    Nov 26, 2007
    Hmmm... yes, that looks like it should work. I'll try implementing it in the morning and post back with an update.

    Edit: Yep, this seems to be working exactly as I intended (my entire .m file below):

    @interface BNApplicationDelegate () {
        NSTimer *_changeActiveApplicationDelayTimer;
        NSRunningApplication *_activeApplication;
    @implementation BNApplicationDelegate
    - (void)awakeFromNib {
        [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
    - (void)activeApplicationChanged:(NSNotification *)notification {
        [_changeActiveApplicationDelayTimer invalidate];
        NSRunningApplication *app = [notification.userInfo objectForKey:NSWorkspaceApplicationKey];
        if (![app isEqual:NSRunningApplication.currentApplication]) {
            _activeApplication = app;
        } else {
            _changeActiveApplicationDelayTimer = [NSTimer scheduledTimerWithTimeInterval:0.2
    - (void)becomeActiveApplication:(NSDictionary *)userInfo {
        _activeApplication = NSRunningApplication.currentApplication;
    - (void)activateActiveApplication {
        [_activeApplication activateWithOptions:NSApplicationActivateIgnoringOtherApps];
    The activateActiveApplication method is exposed in the header; the rest is private.

Share This Page