TransformProcessType() : Better but Still Finicky in 10.9 2

(Most of this post originally was published in an Apple Developer Forum.)

I am happy to see that a 5-years longstanding bug in TransformProcessType(), noted by Mike Ash, and earlier by others, has been fixed!

(The bug was that after invoking TransformProcessType to bring a process from the background to the foreground, the foregrounded app would not get the menu bar until after a different app was activated and then the foregrounded app was activated by the user clicking it in the Dock or doing ⌘-tab.  Trying to do these activations programatically, as a workaround, experimenting with delays, etc., resulted only in hours of frustration.)

But, for BookMacster, it requires a code change to do this during app launching.  BookMacster has a user preference to Launch in Background.  The way it works is  straightforward:  We set LSUIElement to "1" in the Info.plist, then during launch, check the user's preference, and if user wants it in the foreground, TransformProcessType() to foreground type.  Prior to Mavericks, this needed to be done early, in the app delegate's -init, or it wouldn't work.  Now, it needs to be done later, in -applicationDidFinishLaunching.   Here are our complete experimental results …

  OS X     -init    -aDFL      Result

  10.8-      -        TPT      FAIL
            TPT        -       PASS  <— Solution used
            TPT       TPT      PASS


  10.9       -        TPT      PASS  <— Solution Used
            TPT        -       FAIL
            TPT       TPT      FAIL

Sorry for the terminology, but abbreviations help in this case… 

• 10.8- means Mac OS X 10.8 and earlier
• TPT under -init means: Invoke TransformProcessType in -[AppDelegate init].
• TPT under -adfl means: Invoke TransformProcessType in -[AppDelegate applicationDidFinishLaunching].
• PASS means that the app's menu appears in the main menu bar immediately after activating.
• FAIL means the app’s menu does not so appear . 

As you can see, there is no place(s) to invoke TransformProcessType() which works for both 10.9 and earlier systems, so I've had to work around this by  testing for (NSAppKitVersion >= 1200) and invoking TransformProcessType() in the appropriate method to get PASS. 

Although there is nothing in the documentation of TransformProcessType() which mentions that it doesn't work at some times, I can certainly understand how the "process type" would be ill-defined during app launch, causing unexpected behavior.  I have reproduced the behavior in a small demo project, but my inclination is to not file a bug – Because it took 5 years to get this fixed,  I'm worried that if it gets touched again it might get re-broken in a different way which is not amenable to workaround. 

In case you’d like to test it yourself, I put my demo project on GitHub.

UPDATE, 2013-11-05

Further tests, using the indicated solution, in 10.9 showed one failure.

PASS  Doubleclick in Finder
PASS  Put in Dock and click 
PASS  AppleScript "Launch Application
PASS  Launch using the open(1) command in
PASS  Launch from another app, using -[NSWorkspace launchApplicationAtURL:options:configuration:error:]
PASS  Launch from another app, using -[NSWorkspace launchApplication:]
PASS  Launch using the LaunchBar app launcher
FAIL  Launch using the Alfred app launcher

We think that the failure is because Alfred is itself a background or LSUIElement app.  (No, thats not an explanation.)  Any, this is all documented now, with several links in the header file of my class SSYProcessTyper, which now features a strange but working fix for this issue, which I call Dance with Finder.