Splash Screen Improvements
I suspect that this page should really be merged with Equinox Launcher
Improving the launcher is one plan item (bug 154088) for Eclipse 3.3. One aspect of this is the splash screen. Currently the splash screen is handled natively by the launcher in a separate process. Being able to handle the splash screen from java would simplify the launcher code and make it easier to add functionality without bothering the SWT team.
We shall consider 3 "components" in this discussion:
- The Launcher executable. Native C code, responsible for starting java and displaying the splash screen.
- Startup.jar. Java Code, the entry point for starting eclipse. Creates a classloader for the EclipseStarter which starts the framework.
- Framework. Loading & Starting bundles, running the application.
The splash screen must be displayed early. For large products with thousands of bundles, the framework could take noticeable time to start up. This means the splash screen should be first shown before starting the framework, ie either in the Launcher or in the startup.jar.
The Launcher starts java and runs the startup.jar. The startup.jar execs a new instance of the launcher which displays the splash screen. The Framework communicates with this splash process by writing to its standard input stream.
Early Classloader Proposal
Startup.jar creates a special classloader containing the SWT fragment plus some splashscreen.jar. A new thread is created while the splash screen is displayed on the main thread. The framework is started in this new thread. Framework adaptor hooks are used to create a special bundle classloader for SWT that delegates to the existing classloader.
When the framework is finished starting, the application run on the main thread by doing a Display.syncExec.
- The application must dispatch messages periodically during its startup. This can be done whenever the progress monitor is updated. The application also must take over and run the even loop when it is finished loading.
- The application must know not to create a display, but instead get the existing one from the splash.
- The special wrapping bundle classloader for SWT must do the following:
- The native libraries must be extracted out of the swt jar and placed on disk.
- The bundle class loader must delegate to the original classloader that was used for the splash screen
- The bundle class loader must ensure that a ProtectionDomain is set up properly for security.
There are several use cases we would like to handle with the splash that would become reasonable if we had an SWT splash screen. Although the uses differ it seems possible to cover all cases with a single pluggable splash framework.
There is a certain class of Eclipse product that is explicitly an amalgam of other products from multiple vendors. Branding such products is a challenge because each component vendor wants some piece of the splash visiblity. One solution is to provide a hand-crafted splash screen incorporating design elements from all vendors but this solution falls down when the set of components is dynamic. To handle this case the platform could provide an extension point that would allow the augmentation of the splash screen with supplemental icons. Using this each vendor would provide images that would be shown at some specific place in the splash and these icons would be shown as soon as the framework is loaded (and the extensions parsed).
Some applications have very complicated and time consuming startup procedures. For instance, databases are loaded, servers are started, cows are milked, etc. These applications often have a splash screen that shows the progression of startup via icons. This is common in OS or windowing system startup routines. It's conceivable that an RCP application may want to do this style of splash screen. This differs from the above scenario in that the icons do not simply just appear with the framework - they appear as the application does meaningful work. The platform could provide an API that could be called by startup clients to update the splash in this way.
Ohhh Pretty Colors
Some vendors have very elaborate splash screens in their product, be they irregular shaped shells or shells with particular alpha blending or whatnot. It should be possible for these vendors to reproduce the splash they use in other products within the Eclipse framework. For this scenario the splash needs not only be extensible but entirely replaceable. The code that generates the shell needs to be pluggable.
All use cases above could be covered by the following solution. This assume that we can indeed a) get SWT running before the framework early in the life-cycle b) we can reuse the SAME SWT instance for the workbench.
The splash would be need to be pluggable at two layers. The first layer of pluggability would exist in the startup jar level. Here we would have code that creates the SWT display and creates the splash shell. The code that creates the shell (and populates it with initial bitmap content) should be pluggable so that custom shell shapes can be made. This plugability might be accomplished in a rudimentary way by adding custom classes to startup jar and specifying the class to use as a system property. This kind of customization isn't likely to occur too frequently so it needn't be terribly easy to accomplish.
The second layer of plugability comes into play once the workbench has started initialization. At this stage we'd plug in a splash controller - some single extension that is capable of owning and controlling the splash content from this time forward. The platform would provide a default implementation of this controller that provides the current progress reporting (including color, placement, font, etc). Other application developers (RCP or otherwise) could provide implementations that hook in vendor images or elaborate progress or etc. This might be plugged in via the workbench advisor directly or the extension could be bound to a product (much like intro)
In order for this to work across all second-layer implementations the workbench would have to change its startup routine. The first change is trivial - instead of creating its own display it simply finds the one that already exists. The other changes are more interesting. The startup code would need to spin the event loop at wellknown milestones in the startup so that the splash can update appropriately. For instance, wherever we're pushing content to the launcher process now would need to spin the event loop. There are likely other places where the loop needs spinning as well in order for the splash to remain responsive (and interesting).
- Splash screen is displayed by separate launcher process as a basic bitmap. This is displayed until the framework can load SWT and start the application, at which time:
- Given the handle of the splash window/shell can SWT somehow draw into the other process' display ? Doubtful.
- Given the coordinates of the basic splash screen, the application draws its own splash screen on top and tears down the old one. How noticeable would this transition be ? This would be incredibly tricky. Not only do we have to get the location right (which cannot be guaranteed as I understand it) but we need to ensure that there is no weirdness in the system tray/task bar/dock/whatever. It would also preclude the irregular shell/alpha scenario.
- Current launcher functionality is expanded to display bitmaps within the splashscreen. Bitmaps are streamed across from java. This has been investigated in 3.2 and while technically possible it would be a good deal of work to adequately update the launcher on each platform.
- Do nothing, things stay as they are.