Set the XmNdialogType resource for the dialog.
Install a callback routine for the XmNdestroyCallback resource of the MessageBox, so that it
automatically destroys its DialogShell parent.
The XmNdialogType resource can be set to one of the following values:
XmDIALOG_ERROR
XmDIALOG_INFORMATION
XmDIALOG_MESSAGE
XmDIALOG_QUESTION
XmDIALOG_TEMPLATE
XmDIALOG_WARNING
XmDIALOG_WORKING
The type of the dialog does not affect the kind of widget that is created. The only thing the type affects is the graphical
symbol that is displayed in the control area of the dialog. The convenience routines set the resource based on the
routine that is called (e.g. XmCreateErrorDialog() sets the resource to XmDIALOG_ERROR). The widget
automatically sets the graphical symbol based on the dialog type. You can change the type of a dialog after it is
created using XtVaSetValues(); modifying the type also changes the dialog symbol that is displayed.
The Motif dialog convenience routines create DialogShells internally to support the single−object dialog abstraction.
With these routines, the toolkit is responsible for the DialogShell, so the dialog widget uses its
XmNdestroyCallback to destroy its parent upon its own destruction. If the dialog is unmapped or unmanaged, so
is its DialogShell parent. The convenience routines do not add any resources or call any functions to support the
special relationship between the dialog widget and the DialogShell, since most of the code that handles the interaction
is written into the internals of the BulletinBoard.
6.6.2 The DialogShell
As your programs become more complex, you may eventually have to access the DialogShell parent of a dialog
widget in order to get certain things done. This section examines DialogShells as independent widgets and describes
how they are different from other shell widgets. There are three main features of a DialogShell that differentiate it
from an ApplicationShell and a TopLevelShell.
A DialogShell cannot be iconified by the user or by the application.
When the parent of a DialogShell is iconified, withdrawn, unmapped, or destroyed, the DialogShell children
of that window are withdrawn or destroyed.
A DialogShell is always placed on top of the shell widget that owns the parent of the DialogShell.
The DialogShell is subclassed from the TransientShell and VendorShell classes. A shell that is subclassed from
TransientShell cannot be iconified independently of its parent. However, if the parent of a DialogShell is iconified or
unmapped, the DialogShell is unmapped as well. If the parent is destroyed, so is the DialogShell and the dialog within
it. Remember, the parent of the DialogShell is another widget somewhere in the application, such as a Label, a
PushButton, as ApplicationShell, or even another DialogShell. For example, if the callback for PushButton creates a
dialog, the PushButton might be designated as the owner of the dialog. If the shell that contains the PushButton is
iconified, the dialog is also withdrawn from the screen. If the PushButton's shell or the PushButton itself is destroyed,
the dialog is destroyed as well.
The parent−child relationship between a DialogShell and its parent is different from the classic case, where the parent
actually contains the child within its geometrical bounds. The DialogShell widget is a popup child of its parent, which
means that the usual geometry−management relationship does not apply. Nonetheless, the parent widget must be
managed in order for the child to be displayed. If a widget has popup children, those children are not mapped to the
6 Introduction to Dialogs 6.6.2 The DialogShell
128
screen if the parent is not managed, which means that you must never make a menu item the parent of a DialogShell.
Assuming that the parent is displayed, the window manager attempts to place the DialogShell based on the value of
the XmNdefaultPosition BulletinBoard resource. The default value of this resource is True, which means that
the window manager positions the DialogShell so that it is centered on top of its parent. If the resource is set to
False, the application and the window manager negotiate about where the dialog is placed. This resource is only
relevant when the BulletinBoard is the immediate child of a DialogShell, which is always the case for Motif dialogs. If
you want, you can position the dialog by setting the XmNx and XmNy resources for the dialog widget. Positioning the
dialog on the screen must be done through a XmNmapCallback routine, which is called whenever the application
calls XtManageChild(). See Chapter 7, Custom Dialogs, for a discussion about dialog positioning.
The Motif Window Manager imposes an additional constraint on the stacking order of the DialogShell and its parent.
mwm always forces the DialogShell to be directly on top of its parent in the stacking order. The result is that the shell
that contains the widget acting as the parent of the DialogShell cannot be placed on top of the dialog. This behavior is
defined by the Motif Style Guide and is enforced by the Motif Window Manager and the Motif toolkit. Many
end−users have been known to report the behavior as an application−design bug, so you may want to describe this
behavior explicitly in the documentation for your application, in order to prepare the user ahead of time.
Internally, DialogShell widgets communicate frequently with dialog widgets in order to support the single−entity
abstraction promoted by the Motif toolkit. However, you may find that you need to access the DialogShell part of a
Motif dialog in order to query information from the shell or to perform certain actions on it. The include file
<Xm/DialogS.h> provides a convenient macro for identifying whether or not a particular widget is a DialogShell:
#define XmIsDialogShell(w) XtIsSubclass(w, xmDialogShellWidgetClass)
If you need to use this macro, or you want to create a DialogShell using XmCreateDialogShell(), you need to
include <Xm/DialogS.h>.
The macro is useful if you want to determine whether or not a dialog widget is the direct child of a DialogShell. For
example, earlier in this chapter, we mentioned that the Motif Style Guide suggests that if the user activates the OK
button in a MessageDialog, the entire dialog should be popped down. If you have created a MessageDialog without
using XmCreateMessageDialog() and you want to be sure that the same thing happens when the user presses
the OK button in that dialog, you need to test whether or not the parent is a DialogShell before you pop down the
dialog. The following code fragment shows the use of the macro in this type of situation:
/* traverse up widget tree till we find a window manager shell */
Widget
GetTopShell(widget)
Widget widget;
{
while (widget && !XmIsWMShell (widget))
widget = XtParent (widget));
return widget;
}
void
ok_callback(dialog, client_data, call_data)
Widget dialog;
XtPointer client_data;
XtPointer call_data;
{
/* do whatever the callback needs to do ... */
6 Introduction to Dialogs 6.6.2 The DialogShell
129

Get Volume 6A: Motif Programming Manual now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.