Cheezy Hack To Get "Front App Changed" Events

  • In searching for answers about getting "the active application changed"
    notifications from a Cocoa app, I found responses of mostly "sorry, you
    can't do that."  Some people mentioned using Accessibility APIs or the
    undocumented "AppleSystemUIModeChanged" notification.  These seem more
    troublesome than the approach I've tentatively decided to take.

    I'm posting my cheezy hack in the hopes that:

    1. Somebody will tell me of an even less cheezy way.
    2. Others will have another option to work with if they want to
    (unwisely) do the same in their own apps.
    3. Somebody who knows why this is a really bad idea will convince me
    not to do it.

    I've decided that I really wish Cocoa would pass the app-switched
    events on to Carbon so I could get at them by registering for  the
    ""kEventAppFrontSwitched" event.  I've even decided to hold out hope
    that in some future OS release Apple will cave in and special case
    these events for "free passage to Carbon."  So I have blissfully
    implemented my solution as a Carbon event callback for that event type,
    and coerced Cocoa into sending these events to Carbon by adding the
    following to my NSApplication subclass implementation of sendEvent:

    // Because Cocoa intercepts these events and doesn't pass them through
    to Carbon, I have
    // to do sneaky junk with undocumented event types...
    if (([theEvent type] == 21) && ([theEvent subtype] == 2))
    {
      ProcessSerialNumber newSerial;
      EventRef myCarbonEvent;

      GetFrontProcess(&newSerial);

      // Do my own darned event notification
      if (MacCreateEvent(NULL, kEventClassApplication,
    kEventAppFrontSwitched, TicksToEventTime(TickCount()),
    kEventAttributeNone, &myCarbonEvent) == noErr)
      {
      // Tack on the process serial number
      (void) SetEventParameter(myCarbonEvent, kEventParamProcessID,
    typeProcessSerialNumber, sizeof(ProcessSerialNumber), &newSerial);
      SendEventToEventTarget(myCarbonEvent, GetApplicationEventTarget());
      ReleaseEvent(myCarbonEvent);
      }
    }

    It seems to me that this is less prone to future failure because:

    1. Event types and subtypes are probably more static than notification
    names.
    2. Events are more liable to keep getting delivered than undocumented
    notifications.
    3. If these events stop getting delivered, then it probably means Cocoa
    started handing off the events to Carbon before calling sendEvent.  In
    this case, I should continue to get my registered Carbon event
    callbacks as expected.

    I know I'm still taking chances, playing with fire, etc.  But I don't
    just want this functionality, I need it.  The only "no hack"
    alternative I can think of would be switching my app's event model
    entirely from Cocoa to Carbon.  That would be annoying enough that I'd
    rather break some rules...

    Appreciate comments!
    Daniel
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On 11 ao{t 04, at 08:44, Daniel Jalkut wrote:

    > In searching for answers about getting "the active application changed"
    > notifications from a Cocoa app, I found responses of mostly "sorry, you
    > can't do that."  Some people mentioned using Accessibility APIs or the
    > undocumented "AppleSystemUIModeChanged" notification.  These seem more
    > troublesome than the approach I've tentatively decided to take.
    >
    > I'm posting my cheezy hack in the hopes that:
    >
    > 1. Somebody will tell me of an even less cheezy way.
    > 2. Others will have another option to work with if they want to
    > (unwisely) do the same in their own apps.
    > 3. Somebody who knows why this is a really bad idea will convince me
    > not to do it.

    I personnaly use the following in my Cocoa app :

    [[NSDistributedNotificationCenter defaultCenter] addObserver:self
                selector:@selector(checkFrontApp:)
                name:@"com.apple.HIToolbox.menuBarShownNotification"
                object:nil];

    Note that the selector is called "checkFrontApp:" as you might be
    notified even if the front app hasn't changed. You need to check
    manually if the front app is the same.

    Hope this helps,
    Jirome
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • The following snippet allows you to determine the application that has
    just become front most.

    - (void)applicationDidResignActive:(NSNotification *)aNotification
    {
      NSDictionary *appInfo = [[NSWorkspace sharedWorkspace]
    activeApplication];

      NSLog( @"%@", appInfo );
    }

    It works by implementing the NSApplication delegate method
    applicationDidResignActive. When your Cocoa application is no longer
    the front most application, it asks the shared NSWorkspace for
    information on the new front most application. There are also some
    useful utilities in the NSWorkspace API for determining applications
    that have been launched in the background.

    Ed
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On Aug 11, 2004, at 12:46 AM, Jirome Foucher wrote:

    > I personnaly use the following in my Cocoa app :
    >
    > [[NSDistributedNotificationCenter defaultCenter] addObserver:self
    > name:@"com.apple.HIToolbox.menuBarShownNotification"

    I can't recommend this approach, because we're going to stop sending
    that notification in Tiger.

    -eric
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • Am 11.08.2004 um 16:11 Uhr schrieb Eric Schlegel:

    >> I personnaly use the following in my Cocoa app :
    >>
    >> [[NSDistributedNotificationCenter defaultCenter] addObserver:self
    >> name:@"com.apple.HIToolbox.menuBarShownNotification"
    >
    > I can't recommend this approach, because we're going to stop sending
    > that notification in Tiger.

    BTW: I noticed that NSWorkspaceDidLaunchApplicationNotification will
    not be sent when a faceless application (LSUIElement 1) is started. Is
    that intentional or is it a flaw?

    I find it unfortunate. I have to send my own notification now ...

    Andreas
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On 11 ao{t 04, at 16:11, Eric Schlegel wrote:

    > On Aug 11, 2004, at 12:46 AM, Jirome Foucher wrote:
    >
    >> I personnaly use the following in my Cocoa app :
    >>
    >> [[NSDistributedNotificationCenter defaultCenter] addObserver:self
    >> name:@"com.apple.HIToolbox.menuBarShownNotification"
    >
    > I can't recommend this approach, because we're going to stop sending
    > that notification in Tiger.

    So could you please consider implementing the notification directly
    into NSWorkspace ? Just like DidLaunch and DidTerminate ?
    It's way nicer than having to poll ;o)

    Thanks
    Jirome
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On Aug 11, 2004, at 7:53 AM, Jirome Foucher wrote:

    > So could you please consider implementing the notification directly
    > into NSWorkspace ? Just like DidLaunch and DidTerminate ?
    > It's way nicer than having to poll ;o)

    I believe it's on the list for one of the AppKit engineers, but I can't
    promise anything since I'm not the one doing the work.

    -eric
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On Aug 11, 2004, at 7:53 AM, Jirome Foucher wrote:

    > On 11 ao{t 04, at 16:11, Eric Schlegel wrote:
    >
    >> On Aug 11, 2004, at 12:46 AM, Jirome Foucher wrote:
    >>
    >>> I personnaly use the following in my Cocoa app :
    >>>
    >>> [[NSDistributedNotificationCenter defaultCenter] addObserver:self
    >>> name:@"com.apple.HIToolbox.menuBarShownNotification"
    >>
    >> I can't recommend this approach, because we're going to stop sending
    >> that notification in Tiger.
    >
    > So could you please consider implementing the notification directly
    > into NSWorkspace ? Just like DidLaunch and DidTerminate ?
    > It's way nicer than having to poll ;o)

    Make sure to ask for it... <http://developer.apple.com/bugreporter/>
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • Is there an alternative? Will AppleSystemUIModeChanged still be sent?
    Seems to serve the same "purpose".

    That is whenever I need to know if the front app switched in Cocoa, I
    register for both "com.apple.HIToolbox.menuBarShownNotification" and
    "AppleSystemUIModeChanged".

    I so love NoisyApp.

    Then again, I am not sure if registering for the CarbonEvent works or
    not in cocoa runloops.

    Ack, at 8/11/04, Eric Schlegel said:

    > On Aug 11, 2004, at 12:46 AM, Jirome Foucher wrote:
    >
    >> I personnaly use the following in my Cocoa app :
    >>
    >> [[NSDistributedNotificationCenter defaultCenter] addObserver:self
    >> name:@"com.apple.HIToolbox.menuBarShownNotification"
    >
    > I can't recommend this approach, because we're going to stop sending
    > that notification in Tiger.

    --

    Sincerely,
    Rosyna Keller
    Technical Support/Holy Knight/Always needs a hug

    Unsanity: Unsane Tools for Insanely Great People
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On Aug 11, 2004, at 9:27 AM, Rosyna wrote:

    > Is there an alternative? Will AppleSystemUIModeChanged still be sent?
    > Seems to serve the same "purpose".

    Nope, we're going to yank that notification as well.

    > I so love NoisyApp.

    Yes, except when it causes you to rely on undocumented and unsupported
    notifications that get removed. :)

    -eric
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • It seems that notifications are inherently less reliable than
    intercepting at the event delivery.  If Apple wants to eliminate a
    notification from the system, it has a "rendezvous" point in the
    notification center to easily tell who all of its clients are.  They
    can easily add log messages, etc, warning internal developers to stop
    requesting that notification.  To root out an undocumented event code
    would require confidence that every event-looker in the system is
    itself no longer interested in that code.  It also seems unlikely that
    an undocumented event code that provides the straightforward
    implementation for a PUBLIC Carbon API will not go away anytime soon.

    Of course, Eric can't tell us it's OK to do either one.  I'm just
    talking myself into being OK with my bad self :)  And if I was any of
    you depending on weird notifications, I'd be bad like me instead.

    D

    On Aug 11, 2004, at 10:53 AM, Eric Schlegel wrote:

    > Yes, except when it causes you to rely on undocumented and unsupported
    > notifications that get removed. :)
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • I don't know of any alternative method for a cocoa product to get a
    front app changed notification. Subclassing NSApplication is not an
    option as the only time I ever really need it is for cocoa plugins
    (like prefpanes that are open).

    I am not sure if the Carbon Events thing works in this situation.
    This is one of those things where a developer needs a specific
    feature (notification) but it doesn't exist in any public form.
    Granted, if something were to replace it it'd be super with me if the
    unsupported API were removed. It was my own damn fault for using it.

    But if nothing will replace these notifications...

    Ack, at 8/11/04, Eric Schlegel said:

    > On Aug 11, 2004, at 9:27 AM, Rosyna wrote:
    >
    >> Is there an alternative? Will AppleSystemUIModeChanged still be
    >> sent? Seems to serve the same "purpose".
    >
    > Nope, we're going to yank that notification as well.
    >
    >> I so love NoisyApp.
    >
    > Yes, except when it causes you to rely on undocumented and
    > unsupported notifications that get removed. :)
    >
    > -eric

    --

    Sincerely,
    Rosyna Keller
    Technical Support/Holy Knight/Always needs a hug

    Unsanity: Unsane Tools for Insanely Great People
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
previous month august 2004 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today