SplashScreen and NSApplication instance initialization
Mike Swingler
swingler at apple.com
Wed Nov 30 11:41:29 PST 2011
On Nov 30, 2011, at 10:21 AM, Anthony Petrov wrote:
> On 11/30/2011 9:08 PM, Mike Swingler wrote:
>>> On 11/30/2011 3:14 AM, Mike Swingler wrote:
>>>> I'd actually suggest creating a helper process to show the splash screen with a minimal UIElement NSApplication instance, and would forward all clicks to the original process over IPC. This would have the added benefit of (potentially) showing the splash screen window before the Dock icon had completely materialized. The only major trick would be handing off image data that was extracted from a jar file (which could be done via a temp file).
>>> Rather than playing with IPC, would it be simpler (and faster for that matter) to simply postpone showing the splash screen till the JVM is loaded and initialized but before calling user's main()? This way the NSApplicationAWT code (moved to the Java launcher) could access the necessary system properties. We don't exactly need to have the awt library loaded to init and start an NSApplicationAWT instance properly, do we? The only dependency is setting the ApplicationDelegate, but I guess this could be done later when AWT is finally loaded.
>>>
>>> Do you expect any issues with this approach?
>> AFAIK, any callbacks the NSApplicationAWT class gets from AppKit will require calling into the AWT or the eAWT classes. It would not be wise to defer swapping in the NSApplicationAWT class after you have already created a window, since the NSApp is the arbiter of all of the top-level UI elements.
>
> The NSApplicationAWT itself doesn't call AWT directly. It only reads a bunch of Java system properties (which are specified before program starts, obviously). Are those the delegate callbacks that you're referring to? The NSApplication setDelegate: specification doesn't prohibit from setting a delegate at any moment of time. So I suppose theoretically we could install it after AWT has been loaded, while displaying the splash screen window before setting the delegate. Would we just have to invoke a few startup-related callbacks manually then?
The problem is that the moment you show a window, the NSApplicationAWT needs to be installed (if it should be, which it shouldn't in the embedded case). The window won't become visible until the Dock icon has fully materialized. By the time the Dock icon has shown up, your application name is locked in stone, so -registerProcessManager has to be the one controlling that experience or the Java app will look wrong.
Also, if the shared delegate is not set in -finishLaunching, you will miss all openFile events that should get delegated to the eAWT listeners.
>> I think you might be able to pull off the splash screen without even doing any IPC, if you just pass arguments to it's main and use the exit code of the helper for any feedback.
>
> This won't work. The SplashScreen isn't a static entity, the java.awt.SpalshScreen class allows user code to communicate and update it as the application's startup progresses. And the current architecture of the splash screen (e.g. the fact that a pointer to a native structure is stored in the java class, and the structure is used by both shared and platform-specific code) makes it somewhat inconvenient to share the structure between processes.
Ugh. Yeah, that struct is obnoxious.
It might be possible to push AppKit startup logic below AWT, and in the end, the design may be more flexible to accommodate SWT or JavaFX to control the main menubar and the runloop, but it is a fair amount of work. I'd recommend pushing it (as well as the eAWT native functions) into libosxui.dylib (which will change the load library commands in the corresponding Java static initializers).
Mike Swingler
Apple Inc.
More information about the macosx-port-dev
mailing list