1.2, the query_geometry method has been implemented for all Motif widgets. Setting extents is useful, since
without them, the user can adjust a PanedWindow so that the size of a widget is unreasonable or unaesthetic. If you
are setting the extents for a scrolled object (ScrolledText or ScrolledList), you do not need to be as concerned about
the maximum extent, since these objects handle larger sizes appropriately. Minimum states are certainly legitimate
though. For example, you could use the height of a font as a minimum extent for Text or a List.
The PanedWindow widget can be useful for building your own dialogs because you can control the size of the action
area. The action area is always at the bottom of the dialog and its size should never be changed. See Chapter 7,
Custom Dialogs, for a complete discussion of how a PanedWindow can be used in in this manner.
9.7.2 Sashes
The Sashes in a PanedWindow widget are in fact widgets, even though they are not described or defined publicly.
While the Motif Style Guide says that the Sash is part of the PanedWindow widget, the Motif toolkit defines the object
privately, which means that technically the Sash is not supported and it may change in the future. However, it is
possible to get a handle to a Sash if you absolutely need one. In order to retrieve a Sash, you need to include the
header file <Xm/SashP.h>. The fact that the file ends in an uppercase P indicates that it is a private header file, which
means that an application program should not include it. However, there is no public header file for the Sash widget,
so unless you include the private header file, you cannot access the Sashes in a PanedWindow.
If you retrieve all of the children from a PanedWindow using XtVaGetValues() on the XmNchildren resource,
you can use the XmIsSash() macro to locate the Sash children. This macro is defined as follows:
#define XmIsSash(w) XtIsSubclass(w, xmSashWidgetClass)
Although XtIsSubclass() is a public function, xmSashWidgetClass is not declared publicly. One reason that
you might want to get handles to the Sashes in a PanedWindow is to turn off keyboard traversal to the Sashes, as
described in the next section.
9.8 Keyboard Traversal
The Motif Style Guide specifies methods by which the user can interact with an application without using the mouse.
These methods provide a way for the user to navigate through an application and activate user−interface elements on
the desktop using only the keyboard. Such activity is known as keyboard traversal and is based on the Common User
Access (CUA) interface specifications from Microsoft Windows and Presentation Manager.
These specifications make heavy use of the TAB key to move between elements in a user interface; related interface
controls are grouped into what are called tab groups. Some examples of tab groups are a set of ToggleButtons or a
collection of PushButtons. Just as only one shell on the screen can have the keyboard focus, only one widget at a time
can have the input focus. When keyboard activity occurs in a window, the toolkit knows which tab group is current
and directs the input focus to the active item within that group.
The user can move from one item to the next within a tab group using the arrow keys. The user can move from one tab
group to the next using the TAB key. To traverse the tab groups in the reverse direction, the user can use
SHIFT−TAB. The CTRL key can be used with the TAB key in a Text widget to differentiate between a traversal
operation and the use of the TAB key for input. The SPACEBAR activates the item that has the keyboard focus.
To illustrate the keyboard traversal mechanisms, let's examine tictactoe.c from the source code This program contains
one tab group, the Form widget. Because the PushButtons inside of it are elements in the tab group, the user can move
between the items in the tic−tac−toe board using the arrow keys on the keyboard, as illustrated in the figure.
9 Manager Widgets 9.7.2 Sashes
242
Keyboard traversal for tictactoe.c
Pressing the TAB key causes the input focus to be directed to the next tab group and set to the first item in the group,
which is known as the home element. Since there is only one tab group in this application, the traversal mechanism
moves the input focus to the first element in the same group. Thus, pressing the TAB key in this program always
causes the home item to become the current input item.
The conceptual model of the tab group mechanism corresponds to the user's view of an application. With tab groups,
the widget tree is flattened out into two simple layers: the first layer contains tab groups and the second layer contains
the elements of those groups. In this model, there is no concept of managers and children or any sort of widget
hierarchy. But as you know, an application is based on a very structured widget hierarchy. The implementation of tab
groups is based on lists of widget pointers that refer to existing widgets in the widget tree. These lists, known as
navigation groups, are maintained by the VendorShell and MenuShell widgets and are accessed by the input−handling
mechanisms of the Motif toolkit.
Each widget class in the Motif toolkit is initialized either as a tab group itself or as a member of a tab group. Manager
widgets, Lists, and Text widgets are usually tagged as tab groups, since they typically contain subelements that can be
traversed. For example, the elements in a List can be traversed using the arrow keys on the keyboard; the up arrow
moves the selection to the previous element in the List widget. In a Text widget, the arrow keys move the insertion
cursor. The other primitive widgets, such as PushButtons and ToggleButtons, are usually tagged as tab group
members. Output−only widgets are not tagged at all and are excluded from the tab group mechanism, since you
cannot traverse to an output−only widget. These default settings are not permanent. For example, a PushButton or a
ToggleButton can be a tab group, although this setting is uncommon and should only be done when you have a special
reason for forcing the widget to be recognized as a separate tab group.
When the TAB key is pressed, the next tab group in the list of tab groups becomes the current tab group. Since
manager widgets are normally tab groups, the order of tab group traversal is typically based on the order in which the
manager widgets are created. This entire process is automated by the Motif toolkit, so an application does not have to
do anything unless it wants to use a different system of tab groups for some reason. In order to maintain Motif
compliance, we recommend that you avoid interfering with the default behavior.
We are discussing keyboard traversal in the chapter on manager widgets because managers play the most visible role
in keyboard traversal from the application programmer's perspective. Managers, by their nature, contain other widgets,
9 Manager Widgets 9.7.2 Sashes
243
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.