(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 Terminal.app
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, that’s 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.