Creating a splash screen with no window manager borders
|
01-Jul-03 08:00 GMT
|
Question: How do I create a splash screen with no window manager borders?
While my Motif application is initializing I'd like to display a splash
screen that shows a product logo and related information. In particular,
I'd like this splash screen to have no window manager borders around it.
This can be achieved using two different approaches.
One option is to use the "XmNmwmDecorations" resource to turn off the Motif
Window Manager decorations on the shell that you have assigned as the
splash screen. For example:
XtVaSetValues(shell_widget, XmNmwmDecorations,
MWM_DECOR_ALL |
MWM_DECOR_BORDER |
MWM_DECOR_RESIZEH |
MWM_DECOR_TITLE |
MWM_DECOR_MENU |
MWM_DECOR_MINIMIZE |
MWM_DECOR_MAXIMIZE,
NULL );
The above will only work if your application is running with the Motif
Window Manager (mwm) or CDE. Given that there are now many other popular
window managers it is no longer safe to assume your users will be running
mwm. Consequently a more general solution is required.
A window manager neutral solution to this problem is to use the
"XmNoverrideRedirect" resource on the shell containing your splash
screen. The purpose of this resource is to instruct the window manager to
ignore this particular shell. If this resource is set on the shell the
window manager will not set its size or position and will not add window
decorations to it.
Since the window manager is ignoring this window you will likely find that
it appears in the top left hand corner of your screen. If this not what you
want you will need to explicitly set X and Y co-ordinates for the
shell. For example:
XtVaSetValues(shell_widget, XmNoverrideRedirect, TRUE, NULL);
XtVaSetValues(shell_widget, XmNx, 502, XmNy, 65, NULL);
If displaying the splash in the center of the screen regardless of the type
and size of the display is important to you, consider adding some code to
find out the dimensions of the display and calculate the X and Y
co-ordinates based on this. Details on how to get the display dimensions as
the basis for these calculations are available
here.
You may also find that your initialization sequence is so fast
that the splash
screen isn't displayed long enough for the user to see it. If this is the
case you may want to call a timeout procedure after the splash screen is
displayed that unmanages your splash screen and manages your main dialog
after a suitable delay.
Other Issues
There are a number of residual issues to do with
splash screens that need consideration
in addition to the problem, answered above, of removing
window manager decorations.
Firstly, a splash screen needs to be visible and operative
even though the rest of the interface (the real front end)
may not exist at this point in the application.
In order to get the screen to work, we require two things:
- the screen will have to be realized, even though the main
front end isn't.
- there needs to be an X event loop to process
expose (etc.)
events for the screen, but at this point we are outside the control of
the main application X event loop.
The classical solution to the first issue involves a slight
adjustment to the widget class hierarchy. Typically, an application
has one application (or session) shell for the main front end,
with subsidiary top level/dialog shells created as required.
Here, in order to display the splash screen, we will need the
application shell to be realized, but we don't want it visible.
The solution is to create an empty application shell, and use
top level shells throughout for front end screens. In other words,
the application shell no longer contains a visible widget hierarchy.
The second problem will only be solved by using a temporary X event
loop. The splash screen will simply fail to expose itself otherwise.
The logic will read along the lines of:
Boolean splash_screen_required = True;
XtAppContext app_context = ... ;
while (splash_screen_required) {
XEvent event ;
XtAppNextEvent(app_context, &event);
XtDispatchEvent(&event);
}
Where splash_screen_required will need to be set
programmatically as required. This however will block
the application from performing whatever initialization
the splash screen is supposedly masking. There are
various ways of threading the initialization process through
the temporary loop, for example, a work or timer procedure
can be added onto the application context, and this procedure
can perform the application initialization without interfering with
events to the splash screen interface. Typically, the initialization
process would be phased, otherwise a large single initialization
step would potentially block X event processing. An ideal solution may
well involve real multi-threading.
The last piece of the picture is related to keeping the interface
concurrent. Typically, a splash screen will contain a progress
bar of some description, whether a true third party component
such as the XRT/Gear ProgressBar widget, or a suitably configured
Motif 2.1 Thermometer Scale. Changing the value of the scale or
progress indicator needs to display immediately, and not when an
X event is next processed. The solution to this problem is
straightforward: a call to XmUpdateDisplay(Widget) will
force all components with pending expose events to expose
themselves immediately,
even though the program logic may not be processing X events
at the point of call.
Sponsored
by X-Designer - The Leading X/Motif GUI Builder
- Click to download a FREE evaluation
Goto top of page
|