SplashScreen and NSApplication instance initialization
Mike Swingler
swingler at apple.com
Tue Nov 29 15:14:30 PST 2011
On Nov 28, 2011, at 11:57 AM, Anthony Petrov wrote:
> Hi Mike et al.,
>
> For the SplashScreen we need to initialize an instance of NSApplication before JVM (and hence AWT) are loaded. I'm trying to move the code from the NSApplicationAWT.m into the Java launcher code so that it would be shared by both the splashscreen library and the AWT.
>
> The problem I've encountered is that certain settings are retrieved from the JVM properties:
>
> // needed by registerWithProcessManager:
> apple.awt.application.name
> sun.java.launcher
> apple.awt.UIElement
> apple.awt.BackgroundOnly
>
> // needed by finishLaunching:
> apple.awt.application.nib
> apple.awt.application.icon
>
>
> Since the JVM isn't initialized yet when the splash screen code is launching, the properties aren't available. Some parameters have alternative ways of discovery (e.g. there are more options to retrieve the application name in addition to using apple.awt.application.name, and they are all tried in the code), however, the rest of them have not such alternatives.
>
> I've made a quick test by creating a generic NSApplication instance in the splash screen code. Later, when the AWT has started (in the "embedded" mode, sort of, since the event loop has already been started by the splash screen library), I called the registerWithProcessManager and finishLaunching methods static for the NSApp (I've turned them into static methods before that so that I could apply them to any kind of NSAPplication, not only the NSApplicationAWT). This didn't do much though. The only pieces of code that seem to be useful or did anything at all seem to be a) the "// HACK BEGIN" section that helped make the app foreground and display it in the dock (although with a generic, OS-provided icon only), and b) the menu update loop at finishLaunching (which oddly added the new items rather than updated the default ones; and it didn't change the name of the application menu itself).
>
> Note that the icon in the dock wasn't updated to the Java icon, and neither was the main menu updated automatically - I had to switch to another app, and then back to my test to make the menu show. Note that the app's title was just "java". I realize that in part this is because the registerWithProcessManager should actually happen before the application instance is even constructed, but that was just a quick test. Besides, I don't understand why would the finishLaunching code not do its job properly - it just has to be executed some time after starting the event loop. Did the fact that a window has already been shown on the screen prevent it from updating the dock icon?
The problem is that the wrong NSApplication instance is installed, and it would be a Bad Idea to try to swap in your own after the default one has fully initialized.
> Anyway, to make it all work right we probably need to enhance the JRSAppKitAWT interface so that it could update those values rather than register them just once. We could provide some default values from the splash screen code, and later initiate an update at the time when AWT has finally loaded. Is this possible?
This is not possible due to the underlying implementation in AppKit. I looked into this over the Thanksgiving break.
> Another option is to declare that the mentioned properties are simply not supported in case the app uses a splash screen. After all, the properties don't seem to belong to Java specification anyway. However, it would still be cool to (at least) have a shiny Java icon in the dock and a proper application title in the main menu. How do we do that if we choose this way?
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).
Unfortunately the existing Java SE 6 splash screen code is SPI from top-to-bottom, and we have no way to practically expose the raw WindowServer window primitives it's built out of via JRS (particularly when a pure-Cocoa helper app will do functionally the same thing).
What do you think?
Mike Swingler
Apple Inc.
More information about the macosx-port-dev
mailing list