X Application Software Engineering:
"Indirect" Motif Widget Resources
Published in The X Journal March, 1995.
Copyright © 1994 Kenton Lee. All rights reserved.
Key words: X Window System, X11, Motif widget, X Toolkit widget resources, programming.
Many Motif features are controlled by "indirect" widget
resources, i.e., a resource of one widget that controls the behavior
of another widget. These resources are well documented, though
perhaps not where you might normally look. In this issue's column,
I will discuss places in the Motif documentation to look for resources
such as these. I will also give examples of some of the most confusing
indirect resources.
CONTENTS
- INTRODUCTION
- MOTIF RESOURCES
- RESOURCE DOCUMENTATION
- Superclass Resources
- Parent Class Resources
- Combination and Convenience Widgets
- SOME USEFUL INDIRECT RESOURCES
- XmRowColumn Parent Widget
- XmBulletinBoard Parent Widget
- Shell Parent Widget Resources
- XmManager Superclass Resources
- XmLabel Superclass Resources
- XmForm Constraint Widget Resources
- XmPanedWindow Constraint Widget
Resources
- XmScrolledWindow Combination Widget
Resources
- XmMessageBox Combination Widget
Resources
- CONCLUSION
- REFERENCES
- THE AUTHOR
As a professional X consultant, I frequently help application
developers with Motif programming problems. Many of these problems
seem to occur because the programmer did not realize that Motif had a
certain feature. Most of these features deal with look and feel
configuration options that can be set via Motif widget resources.
Sometimes the resources are "indirect", that is, a resource
of one widget controls the behavior of another widget. These resources
are well documented, though perhaps not where you might normally
look. In this issue's column, I will discuss places in the Motif
documentation to look for resources such as these. I will also give
examples of some of the most confusing indirect resources.
As you should already know, the primary programming interface to Motif
widgets is the setting of widget resources. Most static Motif-based
user interface builder tools provide visual tools for setting
resources. Dynamic tools such as editres[1]
also focus on widget resources.
Whenever you have a problem with a widget's configuration, the first
place you should look for help is, of course, the documentation for the
particular widget on which you are working. I prefer the official
Motif reference manual pages, which are available in both
book[2] and on-line UNIX
man page[3] versions.
Motif tutorial books usually present incomplete lists of resources,
though they usually provide useful example code or screen dumps to
explain techniques.
Many times the configuration of a particular widget is controlled by
resources other than those directly defined in that widget's
documentation. In the next three sections, I'll describe three other
places you should look for resources that control a widget:
- superclasses
- parent widget
- combination widgets and convenience creation functions
In some cases, an important resource may be inherited from one of the
superclasses of the widget in question. (In this paper, I will use the
term "superclasses" to mean the immediate superclass as well
as all recursive superclasses.) To help you find these, the Motif
reference manual lists the widget's chain of superclasses, and also
lists the resources and default resource values for the superclasses.
Many superclass resources are popular and widely used. For example,
the XmLabel widget is the superclass of XmPushButton
and XmToggleButton widgets, so all of the XmLabel's
alignment and spacing resources also apply to the XmPushButton and
XmToggleButton.
Other superclasses are not as obvious. For example, the
XmBulletinBoard is the superclass for the XmForm.
All of the XmBulletinBoard's default button, popup menu, and
dialog handling resources also apply to the XmForm.
Another place to look for resources that affect a widget is the
documentation for the parent widget. The parent widget is the composite
(manager) widget that controls the layout, size, and position of its child
widgets. Parent widget resources can affect their children in three
main ways:
- layout policy resources
- override resources
- constraint resources
While all widgets have size and position resources, these are really
only hints to the parent widget. A composite widget is free to ignore
them and instead use its own layout policy. In fact, most Motif
composite widgets ignore at least some of their childrens' size and
position hints. If your child widget is not laid out as you expected,
look at the parent widgets layout policy and related resources. You
may also need to check each ancestor in the widget instance hierarchy.
You should also check for override resources in the parent widget.
Some composite widgets contain resources that override resources set in
their children. The parent can override the child even when the parent
resources are set via resource files and the child resources are set
programatically.
Finally, you should check for constraint resources. These are
resources implemented by the parent widget but that the programmer
specifies on the child widget. The most common examples of constraint
resources are XmForm attachment resources, which you must set
on the children of the XmForm. Several other Motif composite
classes also implement constraint resources.
The Motif reference manual documents all composite widget class
resources, including constraint resources. The constraint resources
are defined immediately following the composite widgets' normal resources.
Motif defines several "combination" widgets, where one
application call to XtCreateWidget() actually
creates several widgets. Examples of combination widgets are the
XmScrolledWindow (in automatic mode, it automatically creates
XmScrollBar and XmDrawingArea widgets) and
XmMessageBox (automatically creates XmLabel
and XmPushButton gadgets). Most combination widgets
provide resources that allow the programmer to retrieve the subwidgets,
allowing you to set resource values on them. You should study the
combination widget's documentation to determine the subwidgets' classes,
then study the classes' documentation to determine which resources are
available for them. Note, however, that some combination widgets
forbid the setting of certain resources on their subwidgets. These
restrictions are specified in the combination widget's documentation.
Related to combination widgets are convenience functions that create
several widgets, for example, XmCreatePopupMenu() (creates
XmRowColumn and XmMenuShell widgets) or
XmCreateScrolledText() (creates XmScrolledWindow
and XmText widgets). The documentation for the convenience
function should specify which widgets are created and how you can
retrieve the identifiers for the separate widgets. You can use
this information to set resources on all the created widgets.
In the previous sections, we discussed where a Motif programmer could
look for documentation on all of the resources that control a particular
widget.
In the following sections, we will look at some examples of these
indirect resources. I can't cover all of them in this column, so
I'll focus on those that are very useful, but are not very obvious
and may not be well covered in many of the Motif tutorial books.
Hopefully, you'll learn from these examples and also learn where to
look for other interesting cases.
Possibly the most confusing of Motif's indirect resources come from
the XmRowColumn parent widget. XmRowColumn
is the workhorse of Motif widgets, being used in menu bars, menu panes,
and radio buttons. XmRowColumn implements a number of
resources especially for these specialty situations, but these
resources can be confusing for application programmers using
XmRowColumn in their applications. Some important menu-oriented
resources are:
- XmNadjustLast and XmNadjustMargin
override some of the margin resources of label and button child widgets.
- XmNisAligned and XmNentryAlignment override
the XmNalignment resources of any label or button child
widgets.
- XmNentryCallback overrides the
XmNactivateCallback of any child widget supporting this
resource.
- XmNradioBehavior, XmNradioAlwaysOne, and
XmNmenuHistory control the behavior of radio buttons.
- XmNmenuHistory also controls the behavior of option menu
items.
XmRowColumn also implements resources that control the ability
of child widgets to dynamically change their sizes. If your widgets do
not seem to grow or shrink when you expect, check these XmRowColumn
resources:
- XmNadjustLast changes the outside margin of widgets in
the XmRowColumn's last column.
- When XmNpacking is XmPACK_COLUMN, all of
the child widgets are resized to be the same size.
- If XmNresizeHeight and/or XmNresizeWidth are
set, the XmRowColumn refuses child requests for resizing in
that/those directions.
In addition, most other XmRowColumn resources control its
layout behavior, including packing style, borders, spacing, columns,
and orientation.
Another confusing widget is the XmBulletinBoard. While
application programmers rarely use XmBulletinBoard directly,
it is the superclass of the popular XmForm.
XmBulletinBoard is also the superclass of XmMessageBox,
XmSelectionBox, and XmFileSelectionBox. All of
XmBulletinBoard's its resources are inherited by these subclasses.
Motif uses XmBulletinBoard as the manager widget for most of its
predefined dialog combination widgets. Many of XmBulletinBoard's
more confusing features are designed for dialogs.
For example, these resources change the behavior of children of the
XmBulletinBoard:
- XmNcancelButton and XmNdefaultButton
add translations to the XmBulletinBoard. When keyboard focus is
anywhere in the XmBulletinBoard, the specified child widgets are
activated by certain key presses.
- XmNautoUnmanage adds callbacks to all button children
so that their activation automatically unmanages the parent
XmBulletinBoard.
- XmNtextTranslations augments the translations of any
text widget children.
These resources override the fonts defined by children of the
XmBulletinBoard:
- XmNbuttonFontList
- XmNlabelFontList
- XmNtextFontList
If the parent of the XmBulletinBoard is a shell widget (as it is in
the standard Motif dialogs), these resources override their corresponding
shell widget resources:
- XmNdefaultPosition
- XmNdialogStyle
- XmNdialogTitle
- XmNnoResize
Other resources control the layout of the XmBulletinBoard.
While most programmers consider the XmBulletinBoard to have
no layout policy, this is not really true. Resources control three important
exceptions:
- XmNresizePolicy controls whether or not the
XmBulletinBoard ignores geometry change requests from its
child widgets.
- If XmNallowOverlap is set to False,
XmBulletinBoard will ignore changes to a child widget's
geometry if the new geometry would overlap that of a sibling widget.
- If XmNmarginHeight and/or XmNmarginWidth is
set (as they are by default), XmBulletinBoard will ignore
child geometry changes if the new geometry would overlap the border.
All shell widgets support the XmNvisual resource to specify
the visual type of the shell. While Xlib supports setting different visual
types for different windows in a window hierarchy, Motif widgets generally
do not expose this programming interface. Instead, Motif widgets generally
copy the visual type of their parent widget. If you want to set the visual
type of a child widget, you should generally change the visual type of its
shell widget.
While XmManager is never directly used by application programmers,
it is the base class for all of Motif's composite widgets, so its resources
are frequently useful. If you cannot find a feature in your composite
widget's documentation, you should also look in XmManager.
Some basic XmManager resources are:
- XmNforeground
- XmNhelpCallback
- XmNhighlightColor
- XmNshadowThickness
- XmNstringDirection
- XmNtraversalOn
- XmNunitType
XmLabel is the superclass to all of Motif's button widgets.
As you probably already know, XmLabel provides a large number
of resources that control the appearance of the string or pixmap in
these widgets.
The XmForm is an example of a constraint widget. The
XmForm defines many resources that you programatically apply
to children of the XmForm, not to the XmForm itself.
You are probably already familiar with the XmForm's attachment and
offset constraint resources. Another important constraint resource to
remember is XmNresizable, which controls whether or not
XmForm accepts size change requests from its child widgets.
Many programmers do not realize that the XmPanedWindow
also implements constraint resources. Its XmNallowResize
resource works the same way as the XmForm's
XmNresizable resource. The XmPanedWindow also
implements several resources that control how the XmPanedWindow
resizes its children when it itself is resized. If child widgets of
your XmPanedWindow are not resizing properly, look at these
XmPanedWindow constraint resources:
- XmNpaneMaximum
- XmNpaneMinimum
- XmNskipAdjust
XmScrolledWindow is an example of a combination widget. When you
create an XmScrolledWindow in automatic mode, you automatically
create XmScrollBar widgets and an XmDrawingArea
widget for the clip window.
In some applications, you may want to manipulate the resources of these
widgets. The XmScrolledWindow provides these resources to
retrieve the identifiers of the child widgets: XmNclipWindow,
XmNhorizontalScrollBar, and XmNverticalScrollBar.
You can use these identifiers to change the colors and spacing of the
scrollbars. The XmScrolledWindow documentation prohibits
changing any of the scrollbars' scrolling parameters, but you can simply
unmanage one of the XmScrollBar's for some one sided effects.
Since the XmNclipWindow is really a XmDrawingArea
widget, you can manipulate some of its resources, too. Two interesting
resources are the XmNresizeCallback and
XmNresizePolicy, which can be used to manipulate your
scrolling region when the XmScrolledWindow is resized.
XmMessageBox is another combination widget. XmMessageBox
automatically creates several label and button children. Unlike the
XmScrolledWindow widget, it provides a convenience function
for retrieving its child widgets: XmMessageBoxGetChild().
If you do not want all the default buttons, you can unmanage some of
the retrieved widget identifiers.
You need not retrieve the children to change their most common resources,
however. Most of XmMessageBox's resources override common
child widget resources, including strings, fonts, pixmaps, and alignment.
Resources are the most important programming interface to Motif widgets,
but resource documentation is often indirect and can be hard to find if
you do not know where to look. Many important resources work
indirectly: resources for one widget control other widgets.
In this month's column, I have discussed the important types of
indirect widget resources and have given several examples. Hopefully,
this material will help you get the most out of Motif's documentation
and improve your user interfaces.
This column focuses on potential problems you might have with widget
resource semantics. A companion paper that may also interest you
focuses on common resource syntax problems.[4]
- Kenton Lee,
"X Application Software Engineering:
Editres," The X Journal, November, 1994.
- Open Software Foundation, OSF/Motif Reference Manual,
Prentice-Hall, 1993.
- Motif man pages are part of OSF's Motif source code distribution
and most commercial Motif binary distributions.
- Kenton Lee,
"Widget Resource Syntax Errors,"
The X Journal, May, 1995.
Kenton Lee is an
independent software consultant specializing in X Window System and
OSF/Motif software development.
He has been developing UNIX graphical user interface software since 1981.
Ken has published over two dozen technical papers on the X Window System.
Most are available over the World Wide Web at
http://www.rahul.net/kenton/bib.html.
Ken may be reached by Internet electronic mail to
kenton @ rahul.net or the World Wide Web at
http://www.rahul.net/kenton/.
For more information on the X Window System, please visit my home page..