0

I want to write a simple menubar app for Mac OS X. The user will only want to use that app when Safari is opened. To not clutter the menubar unnecessarily, I want to hide and show the menubar icon depending on whether Safari is open or not.

Is there maybe some notification that my app could register for? The only workaround I can imagine is poll the running processes and see if Safari is launched, but that doesn't seem to be an elegant way to solve my problem...

Shebuka
  • 3,148
  • 1
  • 26
  • 43
ryyst
  • 9,563
  • 18
  • 70
  • 97

4 Answers4

3

NSWorkspaceDidLaunchApplicationNotification and NSWorkspaceDidTerminateApplicationNotification. (There are equivalent Carbon Events.)

JWWalker
  • 22,385
  • 6
  • 55
  • 76
1

Use kEventAppFrontSwitched in Carbon Event Manager to get notifications when another application becomes active.

Community
  • 1
  • 1
Chin Huang
  • 12,912
  • 4
  • 46
  • 47
0

Got same problem, but thanks to JWWalker, documentation and google wrote this code:

// i need to register on button event, you can do it even in applicationDidFinishLaunching
- (IBAction)Btn_LoginAction:(id)sender {
    ...
    NSNotificationCenter *center = [[NSWorkspace sharedWorkspace] notificationCenter];
    [center addObserver:self selector:@selector(appLaunched:) name:NSWorkspaceDidLaunchApplicationNotification object:nil];
    [center addObserver:self selector:@selector(appTerminated:) name:NSWorkspaceDidTerminateApplicationNotification object:nil];
}

// remember to unregister
- (void)ManageLogout:(NSInteger)aResult {
    ...
    NSNotificationCenter *center = [[NSWorkspace sharedWorkspace] notificationCenter];
    [center removeObserver:self name:NSWorkspaceDidLaunchApplicationNotification object:nil];
    [center removeObserver:self name:NSWorkspaceDidTerminateApplicationNotification object:nil];
}

- (void)appLaunched:(NSNotification *)note {
    [GTMLogger myLog:kGTMLoggerLevelDebug fmt:@"MainWinDelegate::appLaunched: %@ (%@)\n", [[note userInfo] objectForKey:@"NSApplicationBundleIdentifier"], [[note userInfo] objectForKey:@"NSApplicationProcessIdentifier"]];

    if ( [[[note userInfo] objectForKey:@"NSApplicationBundleIdentifier"] isEqualToString:@"app.you.monitor.bundle.identifier"] ) {
        // do stuff
    }
}

- (void)appTerminated:(NSNotification *)note {
    [GTMLogger myLog:kGTMLoggerLevelDebug fmt:@"MainWinDelegate::appTerminated: %@ (%@)\n", [[note userInfo] objectForKey:@"NSApplicationBundleIdentifier"], [[note userInfo] objectForKey:@"NSApplicationProcessIdentifier"]];

    if ( [[[note userInfo] objectForKey:@"NSApplicationBundleIdentifier"] isEqualToString:@"app.you.monitor.bundle.identifier"] ) {
        // do stuff
    }
}
Shebuka
  • 3,148
  • 1
  • 26
  • 43
0

Use this code: http://cl.ly/2LbB

// usleep(40500);

ProcessNotif * x = [[ProcessNotif new] autorelease];
[x setProcessName: @"Safari"];
[x setTarget: self];
[x setAction: @selector(doStuff)];
[x start];

This will run the selector -doStuff when Safari runs. If you get an error, uncomment the usleep() line.

Alexsander Akers
  • 15,967
  • 12
  • 58
  • 83