















        Chapter 13.  IInnppuutt,, FFooccuuss,, aanndd KKeeyybbooaarrdd NNaavviiggaattiioonn








             The X server communicates with clients by means of
             various classes of eevveennttss.  Among these are events
             denoting input from the keyboard and mouse (and, in
             some X extensions, input from other devices).  Each
             event is associated with a window, and the X server
             sends the event to any client that has expressed
             interest in events of that type on that window.

             In the simplest case, when a keyboard or pointer event
             occurs, the X server sends the event to the client that
             has expressed interest in events of that type on the
             window that contains the pointer.  If no such client
             exists, the server searches up the window's hierarchy
             until it finds a client that has expressed interest in
             events of that type on an ancestor window.  In many
             cases, however, event processing is more complex:

                +o A client can ggrraabb a pointer button or key, the
                  pointer or keyboard, or the entire server.  The
                  grabbing client then receives the relevant events
                  for the duration of the grab.

                +o A client can set the kkeeyybbooaarrdd ffooccuuss to some
                  window.  Keyboard events that would normally be
                  reported to this window or one of its inferiors
                  are reported as usual, but other events are
                  reported with respect to the focus window.  Window
                  managers typically use this technique to implement
                  a "click-to-type" interaction style, in which the
                  user clicks the pointer on some window, and that
                  window retains the keyboard focus regardless of




        August 26, 1994                                         13-1







        OSF/Motif Programmer's Guide


                  the position of the pointer.  Other clients, often
                  in cooperation with the window manager, can set
                  the focus to a particular window within the
                  application hierarchy.

             To insulate applications from the complexities of X
             event handling, Xt and Motif have developed higher-
             level facilities based on widgets:

                +o Motif supplies a VendorShell resource,
                  XXmmNNkkeeyybbooaarrddFFooccuussPPoolliiccyy, to allow a user or
                  application to control the model of keyboard focus
                  in the VendorShell and its descendants.  Keyboard
                  focus can be with the widget the contains the
                  pointer or with the widget in which the user
                  presses BBSSeelleecctt.

                +o In the click-to-type model, the user can also use
                  keys to navigate from widget to widget.  Motif
                  provides a model of ttaabb ggrroouuppss, which are widgets
                  or sets of widgets to which the user moves using
                  KKNNeexxttFFiieelldd and KKPPrreevvFFiieelldd.  Within a tab group,
                  the user traverses between widgets using KKUUpp,
                  KKDDoowwnn, KKLLeefftt, and KKRRiigghhtt.  Motif supplies
                  resources to control whether or not a widget
                  constitutes a tab group and whether or not the
                  user can traverse to it using the keyboard.  Motif
                  also has a general routine, XXmmPPrroocceessssTTrraavveerrssaall,
                  for use by the application in moving keyboard
                  focus to a widget or tab group.  The Motif menu
                  system has a specialized traversal mechanism.

                +o Xt provides the basic event-dispatching loop used
                  by most applications.  Xt takes events out of the
                  application's queue and dispatches them to the
                  appropriate widget, usually the widget that has
                  input focus.  Xt usually invokes an aaccttiioonn
                  associated with the particular event through a
                  table of ttrraannssllaattiioonnss from event specifications to
                  action routines.  The action, in turn, often
                  invokes a callback list.  An application primarily
                  responds to events by means of its callback
                  routines.  At a lower level, it can also provide
                  its own eevveenntt hhaannddlleerr, a routine invoked by the Xt
                  dispatching loop when the widget receives events
                  of the specified type.

                +o Motif and Xt provide mmnneemmoonniiccss and aacccceelleerraattoorrss,
                  which are shortcuts for taking actions associated
                  with a widget when the widget does not have input
                  focus.  A mmnneemmoonniicc is a keysym for a key that




        13-2                                         August 26, 1994







                               Input, Focus, and Keyboard Navigation


                  activates a visible button in a menu.  An
                  aacccceelleerraattoorr is a description for an event that
                  invokes an action routine through a translation.



        13.1  FFooccuuss MMooddeellss



             Motif provides two models for determining which widget
             within an application receives keyboard events.  The
             focus model is determined for all descendants of a
             VendorShell by the value of the VendorShell resource
             XXmmNNkkeeyybbooaarrddFFooccuussPPoolliiccyy:

                +o When the value is XXmmEEXXPPLLIICCIITT, the widget under the
                  pointer does not necessarily receive keyboard
                  events.  The user must take an action other than
                  moving the pointer to transfer keyboard focus to a
                  widget.  The user can usually transfer focus to a
                  widget by pressing BBSSeelleecctt on that widget or by
                  using a keyboard navigation action to traverse to
                  the widget.

                  When the value is XXmmEEXXPPLLIICCIITT, a widget must be
                  ttrraavveerrssaabbllee to receive keyboard events.  In
                  general, a widget is traversable when its
                  XXmmNNsseennssiittiivvee, XXmmNNaanncceessttoorrSSeennssiittiivvee, and
                  XXmmNNttrraavveerrssaallOOnn resources are True and when the
                  widget and its ancestors are managed, realized,
                  mapped, and viewable.  See Section 13.2 for more
                  information.

                +o When the value is XXmmPPOOIINNTTEERR, the widget under the
                  pointer receives keyboard events, unless that
                  widget is insensitive.  Keyboard navigation
                  operations are not available.  However, the user
                  can still use the keyboard to traverse a menu
                  system.  KKMMeennuuBBaarr moves focus to the MenuBar, and
                  KKMMeennuu posts a PopupMenu if available.  When the
                  user posts a menu using KKMMeennuu or BBSSeelleecctt RReelleeaassee,
                  KKAAccttiivvaattee, or KKSSeelleecctt in a CascadeButton, keyboard
                  navigation operations are available in the menu
                  until the menu is unposted.  When the user exits
                  the menu system, keyboard focus returns to the
                  widget under the pointer.

             MWM provides two parallel focus models for determining
             which top-level window receives keyboard events.  The
             focus model is determined by the value of the mmwwmm




        August 26, 1994                                         13-3







        OSF/Motif Programmer's Guide


             resource kkeeyybbooaarrddFFooccuussPPoolliiccyy:

                +o When the value is "explicit", the window under the
                  pointer does not necessarily receive keyboard
                  events.  The user must take an action other than
                  moving the pointer to transfer keyboard focus to a
                  window.  The user can usually transfer focus to a
                  window by pressing BBSSeelleecctt on that window or by
                  using KKNNeexxttFFaammiillyyWWiinnddooww, KKPPrreevvFFaammiillyyWWiinnddooww,
                  KKNNeexxttWWiinnddooww, or KKPPrreevvWWiinnddooww to traverse to the
                  window.

                +o When the value is "pointer", the widget under the
                  pointer receives keyboard events.  Keyboard window
                  navigation operations are not available.

             When the focus policy is "explicit", four Boolean mmwwmm
             resources can be set to True to allow a window to
             receive keyboard focus automatically at specified
             times:

             aauuttooKKeeyyFFooccuuss
                       When the window with focus is iconified or
                       unmapped (gives focus to the window that last
                       had it)

             ddeeiiccoonniiffyyKKeeyyFFooccuuss
                       When the window is iconified

             rraaiisseeKKeeyyFFooccuuss
                       When the window is raised to the top of the
                       stack

             ssttaarrttuuppKKeeyyFFooccuuss
                       When the window is mapped



        13.2  CCoonnttrroolllliinngg KKeeyybbooaarrdd NNaavviiggaattiioonn



             In order to receive keyboard focus when the shell's
             XXmmNNkkeeyybbooaarrddFFooccuussPPoolliiccyy is XXmmEEXXPPLLIICCIITT, a widget or
             gadget must meet the following conditions:

                +o The widget and its ancestors must not be in the
                  process of being destroyed.

                +o The widget and its ancestors must be sseennssiittiivvee.  A
                  widget is sensitive when its XXmmNNsseennssiittiivvee and




        13-4                                         August 26, 1994







                               Input, Focus, and Keyboard Navigation


                  XXmmNNaanncceessttoorrSSeennssiittiivvee resources are both True.

                +o The XXmmNNttrraavveerrssaallOOnn resource for the widget and its
                  ancestors must be True.

                +o The widget must be viewable.  This means that the
                  widget and its ancestors must be managed,
                  realized, and (except for gadgets) mapped.
                  Furthermore, in general, some part of the widget's
                  rectangular area must be unobscured by the
                  widget's ancestors.

                  In a ScrolledWindow with an XXmmNNssccrroolllliinnggPPoolliiccyy of
                  XXmmAAUUTTOOMMAATTIICC, a widget that is obscured because it
                  is not within the clip window may be traversable
                  if some part of the widget is within the work area
                  and if an XXmmNNttrraavveerrsseeOObbssccuurreeddCCaallllbbaacckk routine can
                  make the widget unobscured by scrolling the
                  window.

             Most managers cannot receive focus even if they meet
             all these conditions.  In general only primitives and
             gadgets are eligible to receive focus.  A DrawingArea
             can receive focus if it meets the conditions above and
             if, in addition, it has no child whose XXmmNNttrraavveerrssaallOOnn
             resource is True.

             XXmmGGeettFFooccuussWWiiddggeett takes a widget argument that
             identifies a widget hierarchy, up to the nearest shell
             ancestor.  It returns the widget in that hierarchy that
             has keyboard focus or that last had focus when the user
             navigated away from that hierarchy.

             An application can use XXmmIIssTTrraavveerrssaabbllee and
             XXmmGGeettVViissiibbiilliittyy to determine whether a widget is
             eligible to receive focus.  XXmmIIssTTrraavveerrssaabbllee returns
             True if the widget argument meets all the conditions
             described in this section.  Otherwise, it returns
             False.  This routine generally returns False if the
             widget argument is a composite, even if it has
             traversable children.

             XXmmGGeettVViissiibbiilliittyy returns a value indicating the
             visibility of the widget argument:

             XXmmVVIISSIIBBIILLIITTYY__FFUULLLLYY__OOBBSSCCUURREEDD
                       The widget is completely obscured by its
                       ancestors or is not visible for some other
                       reason (such as being unmapped or
                       unrealized).





        August 26, 1994                                         13-5







        OSF/Motif Programmer's Guide


             XXmmVVIISSIIBBIILLIITTYY__PPAARRTTIIAALLLLYY__OOBBSSCCUURREEDD
                       Some part of the widget's rectangular area is
                       obscured by its ancestors.

             XXmmVVIISSIIBBIILLIITTYY__UUNNOOBBSSCCUURREEDD
                       None of the widget's rectangular area is
                       obscured by its ancestors.

             Note that a fully obscured widget may be traversable if
             it is inside the work area of an automatic
             ScrolledWindow with an XXmmNNttrraavveerrsseeOObbssccuurreeddCCaallllbbaacckk
             list.  See Section 13.2.5 for more information.



        13.2.1  SSeennssiittiivviittyy



             Unless a widget is sensitive, Xt does not dispatch
             keyboard or pointer events to the widget.  An
             insensitive widget, therefore, cannot receive keyboard
             focus.

             A widget can be sensitive only when all its ancestors
             are sensitive.  Two Boolean resources determine
             sensitivity: XXmmNNsseennssiittiivvee and XXmmNNaanncceessttoorrSSeennssiittiivvee.
             XXmmNNsseennssiittiivvee indicates whether the widget itself is
             sensitive, and XXmmNNaanncceessttoorrSSeennssiittiivvee indicates whether
             all ancestors are sensitive.

             An application uses the function XXttIIssSSeennssiittiivvee to find
             out whether a widget is sensitive.  This function
             returns True when XXmmNNsseennssiittiivvee and XXmmNNaanncceessttoorrSSeennssiittiivvee
             are both True; otherwise, it returns False.

             The function XXttSSeettSSeennssiittiivvee changes the sensitivity of
             a widget.  With an argument of False, this function
             sets XXmmNNsseennssiittiivvee to False and sets each child's
             XXmmNNaanncceessttoorrSSeennssiittiivvee to False.  With an argument of
             True, this function sets XXmmNNsseennssiittiivvee to True and, if
             the widget's XXmmNNaanncceessttoorrSSeennssiittiivvee is also True, it sets
             each child's XXmmNNaanncceessttoorrSSeennssiittiivvee to True.  The
             function then recursively descends the widget tree.
             For each descendant whose XXmmNNsseennssiittiivvee and
             XXmmNNaanncceessttoorrSSeennssiittiivvee are both True, it sets
             XXmmNNaanncceessttoorrSSeennssiittiivvee to True for that widget's
             children.  Otherwise, it sets XXmmNNaanncceessttoorrSSeennssiittiivvee to
             False for the descendant widget's children.






        13-6                                         August 26, 1994







                               Input, Focus, and Keyboard Navigation


             In this way, XXttSSeettSSeennssiittiivvee ensures that each widget's
             XXmmNNaanncceessttoorrSSeennssiittiivvee is True only when the parent's
             XXmmNNsseennssiittiivvee and XXmmNNaanncceessttoorrSSeennssiittiivvee are both True.
             In other words, the widget is sensitive only when it
             and all its ancestors are sensitive.  To maintain this
             relation, an application should always use
             XXttSSeettSSeennssiittiivvee to change a widget's sensitivity instead
             of calling XXttSSeettVVaalluueess on the widget's resources.

             Note that XXttSSeettSSeennssiittiivvee does not modify any resources
             for pop-up children.  If the parent widget is
             insensitive when a pop-up child is created, the child's
             XXmmNNaanncceessttoorrSSeennssiittiivvee will be False.  XXttSSeettSSeennssiittiivvee on
             the parent widget will not change this value, and the
             child will remain insensitive.  To avoid this problem,
             an application that creates a DialogShell or a
             MenuShell should either ensure that the parent is
             sensitive when the child is created, or specify a value
             of True for the child's XXmmNNaanncceessttoorrSSeennssiittiivvee.  One way
             to do this is in a resource file:

             *XmMenuShell.ancestorSensitive:   True
             *XmDialogShell.ancestorSensitive: True

             When a widget or gadget is insensitive, Motif indicates
             the insensitivity to the user by stippling or graying
             the widget.



        13.2.2  XXmmNNttrraavveerrssaallOOnn



             XXmmNNttrraavveerrssaallOOnn determines whether or not a widget is
             eligible to receive keyboard focus when
             XXmmNNkkeeyybbooaarrddFFooccuussPPoolliiccyy is XXmmEEXXPPLLIICCIITT.  When
             XXmmNNttrraavveerrssaallOOnn is False and XXmmNNkkeeyybbooaarrddFFooccuussPPoolliiccyy is
             XXmmEEXXPPLLIICCIITT, it is not possible for the user to give
             keyboard focus to the widget, even if the widget is
             sensitive and viewable.  XXmmNNttrraavveerrssaallOOnn has no effect
             when XXmmNNkkeeyybbooaarrddFFooccuussPPoolliiccyy is XXmmPPOOIINNTTEERR.

             The default value for XXmmNNttrraavveerrssaallOOnn is True for most
             Motif widgets.  Following are the exceptions:

                +o Separator and SeparatorGadget, where
                  XXmmNNttrraavveerrssaallOOnn is forced to False

                +o ScrollBar, where XXmmNNttrraavveerrssaallOOnn defaults to True
                  when it is the child of a ScrolledWindow whose




        August 26, 1994                                         13-7







        OSF/Motif Programmer's Guide


                  XXmmNNssccrroolllliinnggPPoolliiccyy is XXmmAAUUTTOOMMAATTIICC and to False
                  otherwise

                +o Label and LabelGadget, where XXmmNNttrraavveerrssaallOOnn is
                  forced to False inside menus and defaults to False
                  otherwise

                +o RowColumn, where XXmmNNttrraavveerrssaallOOnn defaults to True
                  in a WorkArea and is not applicable otherwise



        13.2.3  TTaabb GGrroouuppss



             A tab group is a collection of traversable widgets or a
             single widget that contains a collection of traversable
             elements.  When the shell's XXmmNNkkeeyybbooaarrddFFooccuussPPoolliiccyy is
             XXmmEEXXPPLLIICCIITT, the user traverses to a tab group using
             KKNNeexxttFFiieelldd and KKPPrreevvFFiieelldd.  Within a tab group, when
             the focus is on a non-tab-group widget or an element,
             the user traverses to another non-tab-group widget or
             another element using KKUUpp, KKDDoowwnn, KKLLeefftt, and KKRRiigghhtt.

             A tab group is always represented by a widget or
             gadget.  When the group is a collection of widgets, the
             tab group is typically the manager that is the parent
             of the widgets.  When the group is a single widget like
             List or Text, the tab group is that widget itself.

             The arrow keys do not traverse to tab groups or to
             non-tab-group widgets or elements outside the current
             tab group.  To traverse to another tab group using the
             keyboard, the user must press KKNNeexxttFFiieelldd or KKPPrreevvFFiieelldd.

             To be eligible for traversal, a tab group must meet all
             the conditions discussed in Section 13.2, except that a
             manager that is a tab group and meets the other
             conditions is eligible for traversal as long as it
             contains a descendant that can receive focus.  If the
             tab group does not meet these conditions, the
             KKNNeexxttFFiieelldd and KKPPrreevvFFiieelldd actions ignore the tab group.

             Within a tab group, non-tab-group widgets must also
             meet all the conditions discussed in Section 13.2 to be
             eligible for traversal.  If they do not meet these
             conditions, the arrow key actions ignore the widgets.

             Whether or not a widget is a tab group is determined by
             the value of the XXmmNNnnaavviiggaattiioonnTTyyppee resource.  The two




        13-8                                         August 26, 1994







                               Input, Focus, and Keyboard Navigation


             primary values for this resource are XXmmTTAABB__GGRROOUUPP, which
             indicates that the widget is a tab group, and XXmmNNOONNEE,
             which indicates that it is not.

             When the user traverses to the next or previous tab
             group, the direction of the traversal is usually
             determined by the relative locations of the current and
             target groups.  In a left-to-right language
             environment, traversal to each subsequent tab group
             proceeds from left to right and top to bottom.  At the
             bottom right, traversal wraps to the tab group at the
             top left.  Traversal to previous tab groups proceeds in
             the opposite direction.

             The application can control the order of traversal by
             specifying an XXmmNNnnaavviiggaattiioonnTTyyppee of
             XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP for a widget in the hierarchy.
             When any widget in a hierarchy has an XXmmNNnnaavviiggaattiioonnTTyyppee
             of XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, KKNNeexxttFFiieelldd and KKPPrreevvFFiieelldd do
             not move to any widgets in that hierarchy that have
             been designated tab groups by means of an
             XXmmNNnnaavviiggaattiioonnTTyyppee of XXmmTTAABB__GGRROOUUPP.  But KKNNeexxttFFiieelldd and
             KKPPrreevvFFiieelldd do move to widgets whose XXmmNNnnaavviiggaattiioonnTTyyppee
             is XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP, even if some widgets are
             exclusive tab groups.  Thus, an application that uses
             XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP to control traversal must be sure
             that all tab groups have an XXmmNNnnaavviiggaattiioonnTTyyppee of either
             XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP or XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP.

             When any widget in a hierarchy has an XXmmNNnnaavviiggaattiioonnTTyyppee
             of XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, traversal to subsequent tab
             groups does not depend on the relative locations of the
             groups.  Instead, it proceeds to widgets in the order
             in which their XXmmNNnnaavviiggaattiioonnTTyyppee resources were
             specified as XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP or
             XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP, either by creating the widgets with
             that value or by calling XXttSSeettVVaalluueess.  That is,
             traversal proceeds to the widget whose
             XXmmNNnnaavviiggaattiioonnTTyyppee was next specified to be
             XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP or XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP.  Traversal
             to previous tab groups proceeds in the opposite
             direction.

             Within a tab group whose XXmmNNnnaavviiggaattiioonnTTyyppee is
             XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, the arrow keys do not behave the
             same way as they would if the XXmmNNnnaavviiggaattiioonnTTyyppee were
             either XXmmTTAABB__GGRROOUUPP or XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP.  With
             XXmmTTAABB__GGRROOUUPP or XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP, the direction of
             traversal using the arrow keys depends on the relative
             locations of the tab group's children.  KKRRiigghhtt moves to
             the next traversable child to the right of the child




        August 26, 1994                                         13-9







        OSF/Motif Programmer's Guide


             with the focus; KKDDoowwnn moves to the next traversable
             child below the child with the focus; and so on.

             With XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, traversal using the arrow
             keys depends on the order of the tab group's list of
             children, not on the relative locations of the
             children.  KKRRiigghhtt has the same effect as KKDDoowwnn: both
             move to the next traversable child in the tab group's
             list of children.  KKLLeefftt has the same effect as KKUUpp:
             both move to the previous traversable child in the tab
             group's list of children.

             There are three principal differences between
             XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP and XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP:

                +o XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP has the effect of disabling
                  traversal to tab groups that have an
                  XXmmNNnnaavviiggaattiioonnTTyyppee of XXmmTTAABB__GGRROOUUPP.
                  XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP does not; it simply ensures
                  that traversal to that tab group is possible, even
                  when some widget in the hierarchy has an
                  XXmmNNnnaavviiggaattiioonnTTyyppee of XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP.

                +o XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP changes the order of
                  traversal of tab groups within the widget
                  hierarchy.  XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP does not.

                +o XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP changes the order of
                  traversal of widgets inside the tab group.
                  XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP does not.

             The function XXmmAAddddTTaabbGGrroouupp has the same effect as
             calling XXttSSeettVVaalluueess with an XXmmNNnnaavviiggaattiioonnTTyyppee of
             XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP.  The function XXmmRReemmoovveeTTaabbGGrroouupp
             has the same effect as calling XXttSSeettVVaalluueess with an
             XXmmNNnnaavviiggaattiioonnTTyyppee of XXmmNNOONNEE.  XXmmAAddddTTaabbGGrroouupp and
             XXmmRReemmoovveeTTaabbGGrroouupp are obsolete and exist for
             compatibility with earlier releases of OSF/Motif.

             All Motif managers except RowColumn have a default
             XXmmNNnnaavviiggaattiioonnTTyyppee of XXmmTTAABB__GGRROOUUPP.  In RowColumn,
             XXmmNNnnaavviiggaattiioonnTTyyppee is not applicable for MenuBars,
             PulldownMenus, and PopupMenus.  For a WorkArea the
             default is XXmmTTAABB__GGRROOUUPP, and for an OptionMenu the
             default is XXmmNNOONNEE.

             All Motif primitives except List, ScrollBar, Text, and
             TextField have a default XXmmNNnnaavviiggaattiioonnTTyyppee of XXmmNNOONNEE.
             The default for List, Text, and TextField is
             XXmmTTAABB__GGRROOUUPP, and the default for ScrollBar is
             XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP.  These are all controls that have




        13-10                                        August 26, 1994







                               Input, Focus, and Keyboard Navigation


             their own internal navigation.

             Motif sets the navigation type of widgets in some
             situations.  In particular:

                +o The child of a shell always behaves as a tab
                  group, no matter what the value of its
                  XXmmNNnnaavviiggaattiioonnTTyyppee.

                +o Panes and sashes inside PanedWindows have a
                  default XXmmNNnnaavviiggaattiioonnTTyyppee of XXmmTTAABB__GGRROOUUPP.  If the
                  XXmmNNnnaavviiggaattiioonnTTyyppee of a pane is XXmmNNOONNEE when the
                  pane is created, Motif sets the value of that
                  resource to XXmmTTAABB__GGRROOUUPP.

                +o SelectionBox and its subclasses set the
                  XXmmNNnnaavviiggaattiioonnTTyyppee of their automatically created
                  List and Text children to XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP.

             The function XXmmGGeettTTaabbGGrroouupp returns the tab group that
             contains a widget.  If the widget itself is a tab group
             or a shell, it returns that widget.  If neither the
             widget nor any ancestor up to the nearest shell is a
             tab group, it returns the nearest ancestor that is a
             shell.  Otherwise, it returns the nearest ancestor that
             is a tab group.



        13.2.3.1  CCoonnttrroolllliinngg TTaabb GGrroouupp TTrraavveerrssaall OOrrddeerr



             By default, KKNNeexxttFFiieelldd and KKPPrreevvFFiieelldd traverse to
             successive tab groups in order of layout, from left to
             right and top to bottom, within a parent tab group,
             before proceeding in layout order to the next tab group
             that is a sibling of the parent.  Traversal order
             changes when any widget in a shell hierarchy has an
             XXmmNNnnaavviiggaattiioonnTTyyppee of XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP.  In this
             case, KKNNeexxttFFiieelldd and KKPPrreevvFFiieelldd traverse only to
             widgets in the hierarchy whose XXmmNNnnaavviiggaattiioonnTTyyppee is
             either XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP or XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP.
             The traversal order is the order in which the widgets'
             XXmmNNnnaavviiggaattiioonnTTyyppee was specified to be either
             XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP or XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP.

             This mechanism gives an application the means to
             control tab group traversal order.  An application must
             do the following:





        August 26, 1994                                        13-11







        OSF/Motif Programmer's Guide


                +o Ensure that at least one widget in the shell
                  hierarchy has an XXmmNNnnaavviiggaattiioonnTTyyppee of
                  XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP

                +o Ensure that all widgets that the application wants
                  to be tab groups have an XXmmNNnnaavviiggaattiioonnTTyyppee of
                  either XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP or XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP

                +o Specify values for the tab groups'
                  XXmmNNnnaavviiggaattiioonnTTyyppee, using either creation argument
                  lists or XXttSSeettVVaalluueess, in the order in which the
                  tab groups are to be traversed

             Note that, when a tab group has an XXmmNNnnaavviiggaattiioonnTTyyppee of
             XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, traversal to non-tab-group
             widgets inside that tab group proceeds in the order in
             which the children appear in their parents' XXmmNNcchhiillddrreenn
             lists.  If the application wants to specify the order
             of tab group traversal but still wants traversal of
             non-tab-group widgets to proceed according to layout,
             it should select one widget in the hierarchy to have an
             XXmmNNnnaavviiggaattiioonnTTyyppee of XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP.  This tab
             group should contain no non-tab-group widgets.  For
             example, it could be the MainWindow if the MainWindow
             contains only tab groups, or it could be a primitive
             tab group, such as List or Text.  The application
             should then specify an XXmmNNnnaavviiggaattiioonnTTyyppee of
             XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP for all other tab groups in the
             hierarchy.



        13.2.4  IInniittiiaall FFooccuuss



             A tab group may contain any combination of tab group
             and non-tab-group widgets.  A tab group that contains
             other widgets cannot receive focus itself.  When the
             user traverses to a composite tab group, Motif gives
             focus to some widget within the tab group.

             Motif uses the Manager resource XXmmNNiinniittiiaallFFooccuuss in
             determining which widget receives focus.  The value of
             XXmmNNiinniittiiaallFFooccuuss is a widget that meets the following
             conditions:

                +o The widget must be either a tab group or a non-
                  tab-group widget that can receive keyboard focus.
                  In general, a widget can receive keyboard focus
                  when it is a primitive, a gadget, or a manager




        13-12                                        August 26, 1994







                               Input, Focus, and Keyboard Navigation


                  (such as a DrawingArea with no traversable
                  children) that acts as a primitive.

                +o The widget must not be a descendant of a tab group
                  that is itself a descendant of the manager.  That
                  is, the widget cannot be contained within a tab
                  group that is nested inside the manager.

                +o The widget and its ancestors must have a value of
                  True for their XXmmNNttrraavveerrssaallOOnn resources.

             If the widget does not meet these conditions,
             XXmmNNiinniittiiaallFFooccuuss is treated as if the value were NULL.

             Motif uses XXmmNNiinniittiiaallFFooccuuss to determine which widget
             receives focus in these situations:

                +o When the manager is the child of a shell and the
                  shell hierarchy receives focus for the first time

                +o When focus is inside the shell hierarchy, the
                  manager is a composite tab group, and the user
                  traverses to the manager using the keyboard

             Motif then determines focus as follows:

                +o If XXmmNNiinniittiiaallFFooccuuss is a traversable non-tab-group
                  widget, that widget receives focus.

                +o If XXmmNNiinniittiiaallFFooccuuss is a traversable tab group,
                  that tab group receives focus.  If that tab group
                  is a composite with descendant tab groups or
                  traversable non-tab-group widgets, these
                  procedures are used recursively to assign focus to
                  a descendant of that tab group.

                +o If XXmmNNiinniittiiaallFFooccuuss is NULL, the first traversable
                  non-tab-group widget that is not contained within
                  a nested tab group receives focus.

                +o If XXmmNNiinniittiiaallFFooccuuss is NULL and no traversable
                  non-tab-group widget exists, the first traversable
                  tab group that is not contained within a nested
                  tab group receives focus.  If that tab group is a
                  composite with descendant tab groups or
                  traversable non-tab-group widgets, these
                  procedures are used recursively to assign focus to
                  a descendant of that tab group.

             If a shell hierarchy regains focus after losing it,
             focus returns to the widget that had the focus at the




        August 26, 1994                                        13-13







        OSF/Motif Programmer's Guide


             time it left the hierarchy.

             The use of XXmmNNiinniittiiaallFFooccuuss is undefined if the manager
             is a MenuBar, PulldownMenu, PopupMenu, or OptionMenu.



        13.2.5  TTrraavveerrssiinngg ttoo OObbssccuurreedd WWiiddggeettss



             In general, a widget is not eligible to receive focus
             unless some part of its rectangular area is unobscured
             by its ancestors.  However, it may be possible to
             traverse to a widget that is a descendant of a
             ScrolledWindow whose XXmmNNssccrroolllliinnggPPoolliiccyy is XXmmAAUUTTOOMMAATTIICC,
             even if that widget is not within the ScrolledWindow's
             clip window.  Traversal to such a widget is possible
             under the following conditions:

                +o Some part of the widget's rectangular area is
                  within the bounds of the ScrolledWindow's work
                  window.

                +o The ScrolledWindow's clip window is completely
                  unobscured by its ancestors.  If the
                  ScrolledWindow is a descendant of another
                  ScrolledWindow, it must be unobscured by the
                  ancestor's work window but may be outside the
                  ancestor's clip window.

                +o The ScrolledWindow has a procedure on its
                  XXmmNNttrraavveerrsseeOObbssccuurreeddCCaallllbbaacckk list that can bring
                  some part of the widget's rectangular area into
                  the clip window.

                +o The widget meets the other conditions for
                  receiving focus described in Section 13.2.

             Whenever the user attempts to traverse to such a widget
             and the widget is partially or fully obscured by the
             clip window, Motif calls the ScrolledWindow's
             XXmmNNttrraavveerrsseeOObbssccuurreeddCCaallllbbaacckk procedures.  If the
             ScrolledWindow has one or more ancestor
             ScrolledWindows, Motif calls the
             XXmmNNttrraavveerrsseeOObbssccuurreeddCCaallllbbaacckk list for each
             ScrolledWindow whose clip window obscures the traversal
             target, from the lowest level of the hierarchy to the
             highest.  The XXmmNNttrraavveerrsseeOObbssccuurreeddCCaallllbbaacckk procedure can
             try to bring the widget into the clip window if
             necessary, usually by calling XXmmSSccrroollllVViissiibbllee.  If the




        13-14                                        August 26, 1994







                               Input, Focus, and Keyboard Navigation


             target widget is traversable after the
             XXmmNNttrraavveerrsseeOObbssccuurreeddCCaallllbbaacckk procedures are invoked,
             that widget receives focus.

             A procedure can determine the visibility of a widget by
             calling XXmmGGeettVViissiibbiilliittyy.



        13.2.6  XXmmPPrroocceessssTTrraavveerrssaall



             The principal routine for traversing to a widget is
             XXmmPPrroocceessssTTrraavveerrssaall.  Motif uses this routine to effect
             traversal when the user presses an arrow key,
             KKNNeexxttFFiieelldd, or KKPPrreevvFFiieelldd.  An application can use
             XXmmPPrroocceessssTTrraavveerrssaall to implement its own traversal
             actions.

             XXmmPPrroocceessssTTrraavveerrssaall takes two arguments, a widget and a
             constant specifying a traversal action.  The routine
             uses the widget argument to identify the hierarchy that
             contains the widget and that has its root at the
             nearest shell.  If that shell does not currently have
             the focus, any changes to the element with focus within
             that shell will not occur until the next time the shell
             receives focus.

             The traversal action argument identifies one of three
             kinds of action to take.  The following descriptions of
             these actions refer to traversable non-tab-group
             widgets and traversable tab groups.  A traversable
             non-tab-group widget is a widget that is not a tab
             group and that meets all the conditions for receiving
             focus discussed in Section 13.2.  A traversable tab
             group is a tab group widget that meets the same
             conditions, except that a manager that is a tab group
             and meets the other conditions is also traversable as
             long as it contains a descendant that can receive
             focus.

             The routine begins the traversal action from the widget
             in the hierarchy that currently has keyboard focus or
             that last had focus when the user traversed away from
             the shell hierarchy.

                +o Traversal to a non-tab-group widget.  This kind of
                  traversal is possible only when the widget that
                  currently has focus is not a tab group.  Also,
                  these actions do not move focus from one tab group




        August 26, 1994                                        13-15







        OSF/Motif Programmer's Guide


                  to another.  The actions first determine the
                  containing tab group.  This is the tab group
                  containing the widget that currently has focus.
                  The actions traverse only to a non-tab-group
                  widget within the containing tab group.

                  XXmmTTRRAAVVEERRSSEE__RRIIGGHHTT
                            If the XXmmNNnnaavviiggaattiioonnTTyyppee of the
                            containing tab group is not
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, focus moves to
                            the next traversable non-tab-group
                            widget to the right of the widget that
                            currently has focus.  At the right side
                            of the tab group, this action wraps to
                            the non-tab-group widget at the left
                            side and next toward the bottom.  At the
                            lower right corner of the tab group,
                            this action wraps to the non-tab-group
                            widget at the upper left.

                            If the XXmmNNnnaavviiggaattiioonnTTyyppee of the
                            containing tab group is
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, focus moves to
                            the next traversable non-tab-group
                            widget in the tab group, proceeding in
                            the order in which the widgets appear in
                            their parents' XXmmNNcchhiillddrreenn lists.  After
                            the last widget in the tab group, this
                            action wraps to the first non-tab-group
                            widget.

                  XXmmTTRRAAVVEERRSSEE__LLEEFFTT
                            If the XXmmNNnnaavviiggaattiioonnTTyyppee of the
                            containing tab group is not
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, focus moves to
                            the next traversable non-tab-group
                            widget to the left of the widget that
                            currently has focus.  At the left side
                            of the tab group, this action wraps to
                            the non-tab-group widget at the right
                            side and next toward the top.  At the
                            upper left corner of the tab group, this
                            action wraps to the non-tab-group widget
                            at the lower right.

                            If the XXmmNNnnaavviiggaattiioonnTTyyppee of the
                            containing tab group is
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, focus moves to
                            the previous traversable non-tab-group
                            widget in the tab group, proceeding in
                            the reverse order in which the widgets




        13-16                                        August 26, 1994







                               Input, Focus, and Keyboard Navigation


                            appear in their parents' XXmmNNcchhiillddrreenn
                            lists.  After the first widget in the
                            tab group, this action wraps to the last
                            non-tab-group widget.

                  XXmmTTRRAAVVEERRSSEE__DDOOWWNN
                            If the XXmmNNnnaavviiggaattiioonnTTyyppee of the
                            containing tab group is not
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, focus moves to
                            the next traversable non-tab-group
                            widget below the widget that currently
                            has focus.  At the bottom of the tab
                            group, this action wraps to the non-
                            tab-group widget at the top and next
                            toward the right.  At the lower right
                            corner of the tab group, this action
                            wraps to the non-tab-group widget at the
                            upper left.

                            If the XXmmNNnnaavviiggaattiioonnTTyyppee of the
                            containing tab group is
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, focus moves to
                            the next traversable non-tab-group
                            widget in the tab group, proceeding in
                            the order in which the widgets appear in
                            their parents' XXmmNNcchhiillddrreenn lists.  After
                            the last widget in the tab group, this
                            action wraps to the first non-tab-group
                            widget.

                  XXmmTTRRAAVVEERRSSEE__UUPP
                            If the XXmmNNnnaavviiggaattiioonnTTyyppee of the
                            containing tab group is not
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, focus moves to
                            the next traversable non-tab-group
                            widget above the widget that currently
                            has focus.  At the top of the tab group,
                            this action wraps to the non-tab-group
                            widget at the bottom and next toward the
                            left.  At the upper left corner of the
                            tab group, this action wraps to the
                            non-tab-group widget at the lower right.

                            If the XXmmNNnnaavviiggaattiioonnTTyyppee of the
                            containing tab group is
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, focus moves to
                            the previous traversable non-tab-group
                            widget in the tab group, proceeding in
                            the reverse order in which the widgets
                            appear in their parents' XXmmNNcchhiillddrreenn
                            lists.  After the first widget in the




        August 26, 1994                                        13-17







        OSF/Motif Programmer's Guide


                            tab group, this action wraps to the last
                            non-tab-group widget.

                  XXmmTTRRAAVVEERRSSEE__NNEEXXTT
                            Focus moves to the next traversable
                            non-tab-group widget in the tab group,
                            proceeding in the order in which the
                            widgets appear in their parents'
                            XXmmNNcchhiillddrreenn lists.  After the last
                            widget in the tab group, this action
                            wraps to the first non-tab-group widget.

                  XXmmTTRRAAVVEERRSSEE__PPRREEVV
                            Focus moves to the previous traversable
                            non-tab-group widget in the tab group,
                            proceeding in the reverse order in which
                            the widgets appear in their parents'
                            XXmmNNcchhiillddrreenn lists.  After the first
                            widget in the tab group, this action
                            wraps to the last non-tab-group widget.

                  XXmmTTRRAAVVEERRSSEE__HHOOMMEE
                            If the XXmmNNnnaavviiggaattiioonnTTyyppee of the
                            containing tab group is not
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, focus moves to
                            the first traversable non-tab-group
                            widget at the top left corner of the tab
                            group.

                            If the XXmmNNnnaavviiggaattiioonnTTyyppee of the
                            containing tab group is
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP, focus moves to
                            the first traversable non-tab-group
                            widget in the tab group, according to
                            the order in which the widgets appear in
                            their parents' XXmmNNcchhiillddrreenn lists.

                +o Traversal to a tab group.  These actions first
                  determine the current widget hierarchy and the
                  containing tab group.  The current widget
                  hierarchy is the widget hierarchy whose root is
                  the nearest shell ancestor of the widget that
                  currently has focus.  The containing tab group is
                  is the tab group containing the widget that
                  currently has focus.

                  XXmmTTRRAAVVEERRSSEE__NNEEXXTT__TTAABB__GGRROOUUPP
                            If no tab group in the current widget
                            hierarchy has a value of
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP for
                            XXmmNNnnaavviiggaattiioonnTTyyppee, focus goes to the




        13-18                                        August 26, 1994







                               Input, Focus, and Keyboard Navigation


                            next traversable tab group that is to
                            the right of the widget with current
                            focus and is within the containing tab
                            group.  At the right side of the
                            containing tab group, this action wraps
                            to the tab group at the left side and
                            next toward the bottom.  At the lower
                            right corner of the containing tab
                            group, this action recursively moves up
                            one level in the hierarchy.  Focus then
                            goes to the next traversable tab group
                            that is to the right of the original
                            containing tab group and is within the
                            tab group that contains that one.  At
                            the lower right corner of the topmost
                            tab group in the hierarchy, this action
                            wraps to the first traversable tab group
                            at the upper left corner of the topmost
                            tab group.

                            If any tab group in the current widget
                            hierarchy has a value of
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP for
                            XXmmNNnnaavviiggaattiioonnTTyyppee, focus goes to the
                            next traversable tab group in the
                            hierarchy, in the order in which the
                            XXmmNNnnaavviiggaattiioonnTTyyppee resources of the tab
                            groups were set to XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP
                            or XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP.  After the last
                            tab group in the hierarchy, this action
                            wraps to the first tab group.

                  XXmmTTRRAAVVEERRSSEE__PPRREEVV__TTAABB__GGRROOUUPP
                            If no tab group in the current widget
                            hierarchy has a value of
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP for
                            XXmmNNnnaavviiggaattiioonnTTyyppee, focus goes to the
                            next traversable tab group that is to
                            the left of the widget with current
                            focus and is within the containing tab
                            group.  At the left side of the
                            containing tab group, this action wraps
                            to the tab group at the right side and
                            next toward the top.  At the upper left
                            corner of the containing tab group, this
                            action recursively moves up one level in
                            the hierarchy.  Focus then goes to the
                            next traversable tab group that is to
                            the left of the original containing tab
                            group and is within the tab group that
                            contains that one.  At the upper left




        August 26, 1994                                        13-19







        OSF/Motif Programmer's Guide


                            corner of the topmost tab group in the
                            hierarchy, this action wraps to the
                            first traversable tab group at the lower
                            right corner of the topmost tab group.

                            If any tab group in the current widget
                            hierarchy has a value of
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP for
                            XXmmNNnnaavviiggaattiioonnTTyyppee, focus goes to the
                            previous traversable tab group in the
                            hierarchy, in the reverse order in which
                            the XXmmNNnnaavviiggaattiioonnTTyyppee resources of the
                            tab groups were set to either
                            XXmmEEXXCCLLUUSSIIVVEE__TTAABB__GGRROOUUPP or
                            XXmmSSTTIICCKKYY__TTAABB__GGRROOUUPP.  After the first tab
                            group in the hierarchy, this action
                            wraps to the last tab group.

                +o Traversal to any widget.  In this case, the widget
                  argument is the widget to which XXmmPPrroocceessssTTrraavveerrssaall
                  tries to give focus.

                  XXmmTTRRAAVVEERRSSEE__CCUURRRREENNTT
                            Focus goes to the widget argument if
                            that widget is a traversable non-tab-
                            group widget or tab group.

             Note that XXmmPPrroocceessssTTrraavveerrssaall cannot be called
             recursively.  In particular, an application cannot call
             this routine from an XXmmNNffooccuussCCaallllbbaacckk or
             XXmmNNlloossiinnggFFooccuussCCaallllbbaacckk procedure.



        13.2.7  FFooccuuss CCaallllbbaacckkss



             BulletinBoard, Text, and TextField have
             XXmmNNffooccuussMMoovveeddCCaallllbbaacckk callback lists.  Motif invokes
             the procedures on these lists when these widgets
             receive keyboard focus.  A callback procedure may
             change the widget's state to reflect the new focus, but
             it should not try to change the focus and, in
             particular, must not call XXmmPPrroocceessssTTrraavveerrssaall.

             Text and TextField also have XXmmNNlloossiinnggFFooccuussCCaallllbbaacckk
             callback lists.  The Text and TextField traversal
             actions invoke these procedures before traversing to
             another widget.  The third argument to each procedure
             is a pointer to an XXmmTTeexxttVVeerriiffyyCCaallllbbaacckkSSttrruucctt structure




        13-20                                        August 26, 1994







                               Input, Focus, and Keyboard Navigation


             whose rreeaassoonn member is XXmmCCRR__LLOOSSIINNGG__FFOOCCUUSS.  If a
             callback procedure sets the ddooiitt member of this
             structure to False, the traversal action does not carry
             out the traversal.  In this way the application can
             prevent a user from traversing out of the widget by
             means of these actions.

             Motif also invokes the XXmmNNlloossiinnggFFooccuussCCaallllbbaacckk
             procedures when the widget loses focus by some other
             means.  For example, the user might click BBSSeelleecctt in
             another traversable widget, or when the shell's
             XXmmNNkkeeyybbooaarrddFFooccuussPPoolliiccyy is XXmmPPOOIINNTTEERR the user might move
             the pointer into another widget.  In such cases,
             setting the ddooiitt member of the callback structure has
             no effect.



        13.3  TTrraannssllaattiioonnss aanndd AAccttiioonnss



             In Xt, the primary means of associating an input event
             with a widget-specific procedure is the combination of
             translations and actions.  Each widget (but not gadget)
             instance contains a table of translations that maps
             event descriptions to procedure names.  Each widget
             instance also has a table of actions that maps these
             procedure names to actual procedures.  When a widget
             receives an input event, the Xt event-dispatching
             facility looks up the event in the translation table,
             looks up the associated procedure in the action table,
             and invokes the action procedure itself.  This
             procedure usually takes some action to change the
             widget state and often invokes callback procedures.



        13.3.1  TTrraannssllaattiioonn TTaabbllee FFoorrmmaatt



             An application or user specifies a translation table as
             a string whose format is defined in _X _T_o_o_l_k_i_t
             _I_n_t_r_i_n_s_i_c_s-_C _L_a_n_g_u_a_g_e _I_n_t_e_r_f_a_c_e.  In general, the table
             consists of individual translations separated by "\n".
             Each translation consists of an event description
             sequence, a colon, and one or more associated procedure
             names.  Each procedure name also has a list of
             parameters within parentheses to be passed to the
             procedure when it is invoked as a result of that




        August 26, 1994                                        13-21







        OSF/Motif Programmer's Guide


             translation.

             An event description in general consists of an optional
             list of modifiers, an event type within angle brackets
             (< and >), an optional repeat count within parentheses,
             and an optional event detail.  Modifiers apply only to
             key, button, motion, enter, and leave events.  If an
             exclamation point (!) precedes the modifiers, then the
             modifiers in the list and no others must be asserted
             for the action to be invoked.  Otherwise, the modifiers
             in the list must be asserted, but others may be as
             well.  A tilde (~) before any modifier means that that
             modifier must not be asserted.  If the modifier list is
             empty, any modifiers may be asserted.

             The detail field varies depending on the event type.
             The most common use is to identify the keysym for a
             KKeeyyPPrreessss or KKeeyyRReelleeaassee event.

             Event descriptions in a sequence are separated by
             commas.  Mouse motion is discarded if it occurs between
             events in a sequence that does not include explicit
             motion events.  This allows the following sort of
             translation to invoke an action even if the mouse moves
             between button press and release:

             <Btn1Down>,<Btn1Up> : action()

             Following are some important considerations in using
             translations:

                +o More specific events should always precede less
                  specific events in the table:

                  Ctrl<Key>space : action_1()
                  <Key>space     : action_2()

                +o Translations with event sequences that are
                  noninitial subsequences of other translations are
                  not invoked when the events occur as part of the
                  longer sequence.  For instance, uupp__aaccttiioonn(()) in the
                  following example would not be invoked on a button
                  release that followed a button press:

                  <Btn1Down>,<Btn1Up> : click_action()
                  <Btn1Up>            : up_action()

                +o Event descriptions that use a repeat count expand
                  into longer sequences.  For example, the following
                  descriptions are more or less equivalent:





        13-22                                        August 26, 1994







                               Input, Focus, and Keyboard Navigation


                  <Btn1Up>(2)                  : double_click()
                  <Btn1Up>,<Btn1Down>,<Btn1Up> : double_click()

                  This result, combined with the implicit insertion
                  of motion events between any two other events,
                  means that motion translations cannot exist in a
                  table with multiclick translations.

             See _X _T_o_o_l_k_i_t _I_n_t_r_i_n_s_i_c_s-_C _L_a_n_g_u_a_g_e _I_n_t_e_r_f_a_c_e for more
             information on the format of translation tables.



        13.3.2  UUssiinngg TTrraannssllaattiioonnss



             One translation table frequently needs to be merged
             with another.  For example, a user may want to add one
             or more translations to a widget's default
             translations.  A translation table may begin with one
             of three directives that specifies how the table is to
             be merged with an existing table:

             ##rreeppllaaccee  The new translation table should completely
                       replace any existing table.  This is the
                       default if no directive is specified.

             ##aauuggmmeenntt  The new translation table should be added to
                       any existing table.  If the two tables
                       contain duplicate event descriptions, the
                       translations in the existing table are used.

             ##oovveerrrriiddee The new translation table should be added to
                       any existing table.  If the two tables
                       contain duplicate event descriptions, the
                       translations in the new table are used.

             A widget's translation table is the value of the Core
             XXmmNNttrraannssllaattiioonnss resource.  The initial value is
             determined in the following way:

                +o If a non-NULL value is specified for
                  XXmmNNttrraannssllaattiioonnss in the widget creation argument
                  list, the widget class translations are merged
                  with that value, in order, and the resulting table
                  is used.

                +o Otherwise, the following tables are merged, in
                  order, and the resulting table is used:





        August 26, 1994                                        13-23







        OSF/Motif Programmer's Guide


                     - The widget class translations

                     - The value of the bbaasseeTTrraannssllaattiioonnss resource
                       from the resource database

                     - The value of the XXmmNNttrraannssllaattiioonnss resource
                       from the resource database or, if no value
                       was specified, the default value for the
                       widget's XXmmNNttrraannssllaattiioonnss

             To take advantage of this initialization ordering, an
             application should usually provide any translations of
             its own by specifying a value for bbaasseeTTrraannssllaattiioonnss
             rather than XXmmNNttrraannssllaattiioonnss in an application class
             defaults file or a fallback resource list.  This
             essentially reserves XXmmNNttrraannssllaattiioonnss to the user.  The
             application can change the widget class translations by
             specifying bbaasseeTTrraannssllaattiioonnss, and the user can change
             the application's translations by specifying
             XXmmNNttrraannssllaattiioonnss.

             As the value of a widget's XXmmNNttrraannssllaattiioonnss, a
             translation table must be in a parsed format rather
             than a string.  The string-to-translation-table
             converter parses a resource string into a translation
             table.  An application can also use
             XXttPPaarrsseeTTrraannssllaattiioonnTTaabbllee to compile a translation table
             string into the parsed format.  The application can
             then merge the parsed table with a widget's
             XXmmNNttrraannssllaattiioonnss in three ways:

                +o XXttAAuuggmmeennttTTrraannssllaattiioonnss merges the parsed table in
                  ##aauuggmmeenntt mode

                +o XXttOOvveerrrriiddeeTTrraannssllaattiioonnss merges the parsed table in
                  ##oovveerrrriiddee mode

                +o XXttSSeettVVaalluueess of XXmmNNttrraannssllaattiioonnss replaces the
                  existing value with the parsed table

             Some Motif widgets merge additional translations in
             their iinniittiiaalliizzee and sseett__vvaalluueess methods.  This process
             may make it impossible for an application or user to
             override some translations by means of resource files.
             For example, for some widgets it may not be possible to
             change traversal translations in this way.









        13-24                                        August 26, 1994







                               Input, Focus, and Keyboard Navigation


        13.3.3  AAccttiioonnss



             Each widget instance has a table that maps action
             procedure names, as they appear in translation tables,
             to actual action procedures.  When an action is invoked
             through a translation, Xt looks up the action procedure
             name in this table and calls the associated procedure.

             Each widget class may have its own action table.  In
             addition, an application can use XXttAAppppAAddddAAccttiioonnss to add
             entries to an action table associated with the
             application context.  Only one such table exists per
             application context.  If a call to XXttAAppppAAddddAAccttiioonnss
             contains an action name that is already in the table,
             the action name becomes associated with the action
             procedure supplied in the call to XXttAAppppAAddddAAccttiioonnss,
             overriding the existing action.

             Xt creates a widget's action table when the widget is
             realized.  It uses actions from the following action
             tables, those listed first having highest precedence:

                +o The action tables for the widget's class and its
                  superclasses, in subclass-to-superclass order

                +o The action tables for the parent's class and its
                  superclasses, in subclass-to-superclass order, and
                  so on up the widget hierarchy

                +o The application context action table (created by
                  calls to XXttAAppppAAddddAAccttiioonnss)

             This ordering means that an application cannot use
             XXttAAppppAAddddAAccttiioonnss to provide a new action procedure for
             an action name that is already registered by a widget
             class.  To do that, the application must supply a
             translation that maps the event to an action name that
             is not registered by the class.  The application must
             then call XXttAAppppAAddddAAccttiioonnss to supply a procedure for the
             action name.

             An action procedure is a function of type XXttAAccttiioonnPPrroocc.
             This function receives four arguments:

                +o The widget

                +o The event, or the last event of a sequence, that
                  caused the procedure to be invoked





        August 26, 1994                                        13-25







        OSF/Motif Programmer's Guide


                +o A list of strings representing the parameters
                  specified for this action in the translation table

                +o An integer representing the number of parameters
                  in the parameter list

             An application can use the parameter list to perform a
             number of related actions in a single action routine.
             For example, a widget might have the following
             translations:

             c <Key> osfLeft  : move-object(left) \n\
             c <Key> osfRight : move-object(right) \n\
             c <Key> osfUp    : move-object(up) \n\
             c <Key> osfDown  : move-object(down)

             The routine implementing the mmoovvee--oobbjjeecctt(()) action is
             passed one of the strings "left", "right", "up", and
             "down" as the only item in the parameter list,
             depending on which key event invoked the action.  The
             routine performs the action appropriate for this
             parameter.



        13.3.4  BBiinnddiinnggss ffoorr oossff KKeeyyssyymmss



             Motif maintains a client-side mechanism for mapping one
             set of keysyms to another set.  This mapping allows
             Motif widgets and applications to use a single set of
             keysyms in translation tables and also allows
             applications and users to customize the keysyms used in
             the translations for the particular keyboard used with
             the display.

             The names of keysyms eligible for use in translations
             in this way begin with the prefix "osf" and are
             referred to as _o_s_f _k_e_y_s_y_m_s.  Motif maintains a mapping
             between these "virtual" keysyms and the "actual"
             keysyms that correspond to keys on a particular
             keyboard.  When Xt receives a keyboard event, the
             function XXmmTTrraannssllaatteeKKeeyy translates the keycode of the
             event to the appropriate osf keysym if a mapping exists
             for that keysym.  Xt then dispatches the event to the
             appropriate action routine if a translation exists for
             that osf keysym.

             The mapping between osf and actual keysyms is
             determined at application startup based on information




        13-26                                        August 26, 1994







                               Input, Focus, and Keyboard Navigation


             obtained from one of the following sources, listed in
             order of precedence:

                +o A ddeeffaauullttVViirrttuuaallBBiinnddiinnggss application resource in
                  the resource database.

                +o A property on the root window, which can be set by
                  mmwwmm on startup, by the xxmmbbiinndd client, or on prior
                  startup of a Motif application.

                +o A ..mmoottiiffbbiinndd file in the user's home directory.

                +o A default binding based on the vendor string and
                  optionally the vendor release of the X server.
                  Motif searches the file xxmmbbiinndd..aalliiaass in the user's
                  home directory, the directory specified by the
                  environment variable XXMMBBIINNDDDDIIRR, or the directory
                  //uussrr//lliibb//XXmm//bbiinnddiinnggss.

             The file xxmmbbiinndd..aalliiaass maps combinations of vendor
             strings and vendor release numbers to pathnames.  Each
             pathname represents a file that contains keysym
             bindings for a particular vendor string and optional
             vendor release number.  If Motif fails to find a
             bindings file for the current display, it uses a set of
             hard-coded fallback bindings.

             The format of the ddeeffaauullttVViirrttuuaallBBiinnddiinnggss resource is
             similar to that of a string specifying translations.
             Each binding consists of an osf keysym, a colon, a key
             event description (with optional modifiers) for the
             actual keysym, and "\n".  The format of a ..mmoottiiffbbiinndd
             file or a file containing vendor bindings is the same,
             except that each binding is on a separate line.

             Following is an example of a specification for the
             ddeeffaauullttVViirrttuuaallBBiinnddiinnggss resource in a resource file:

             *defaultVirtualBindings: \
                  osfBackSpace   :    <Key>BackSpace\n\
                  osfInsert      :    <Key>InsertChar\n\
             ...
                  osfDelete      :    <Key>DeleteChar

             The example specification above appears as follows in a
             ..mmoottiiffbbiinndd or vendor bindings file:

             osfBackSpace   :    <Key>BackSpace
             osfInsert      :    <Key>InsertChar
             ...
             osfDelete      :    <Key>DeleteChar




        August 26, 1994                                        13-27







        OSF/Motif Programmer's Guide


             For more information, see the VViirrttuuaallBBiinnddiinnggss((33XX)) and
             xxmmbbiinndd((11XX)) reference pages in the _O_S_F/_M_o_t_i_f
             _P_r_o_g_r_a_m_m_e_r'_s _R_e_f_e_r_e_n_c_e.



        13.4  MMnneemmoonniiccss aanndd AAcccceelleerraattoorrss



             Sometimes it is desirable for an event received by one
             widget to activate an action in another.  For example,
             the application may establish a shortcut for activating
             a button in a menu; the user can activate the menu item
             even when focus is not in the menu.  Motif has two
             facilities, mnemonics and accelerators, for allowing
             events in one widget to invoke actions in another.

             A mnemonic is a keysym that identifies a key the user
             can press to activate a menu item when the menu is
             posted.  A button in a MenuBar, PulldownMenu, or
             PopupMenu can have a mnemonic.  When the button is in a
             PulldownMenu or PopupMenu that is the most recently
             posted menu, the user activates the button by pressing
             the key associated with the mnemonic.  When the button
             is in a MenuBar, the MenuBar must have focus for the
             mnemonic to activate the button.  However, the user can
             activate the button from within the hierarchy that
             contains the MenuBar, even if the MenuBar does not have
             focus, by pressing the key while holding the MMAAlltt
             modifier.

             An application or user supplies a mnemonic for a button
             by specifying a value for the Label or LabelGadget
             resource XXmmNNmmnneemmoonniicc.  When the button is displayed,
             Motif underlines the first character in the label
             string that exactly matches the mnemonic in the
             character set specified by XXmmNNmmnneemmoonniiccCChhaarrSSeett.
             Although the mnemonic must match a character in the
             label string exactly in order to be underlined, the
             user can activate the mnemonic by pressing either the
             shifted or the unshifted key.

             An accelerator allows the user to activate a menu item
             when focus is anywhere in the hierarchy containing the
             menu, even if the menu is not posted.  Accelerators are
             supported only for PushButtons and ToggleButtons (or
             their gadget equivalents) in PulldownMenus and
             PopupMenus.






        13-28                                        August 26, 1994







                               Input, Focus, and Keyboard Navigation


             An application or user supplies an accelerator for a
             button by specifying a value for the Label or
             LabelGadget resource XXmmNNaacccceelleerraattoorr.  The value is a
             string in the same format as an event description in a
             translation table, except that only KKeeyyPPrreessss events are
             allowed.  Thus, an accelerator can have a modifier like
             MMCCttrrll or MMAAlltt.  XXmmNNaacccceelleerraattoorrTTeexxtt is a compound string
             that describes the accelerator event, for example,
             "Ctrl+A".  Motif displays the accelerator text to the
             side of the button's label string or pixmap.

             The following example creates a button with a mnemonic
             and an accelerator:

             n = 0;
             XtSetArg(args[n], XmNmnemonic, XStringToKeysym("A"); n++;
             XtSetArg(args[n], XmNaccelerator, "Ctrl<Key>A"); n++;
             XtSetArg(args[n], XmNacceleratorText,
                      XmStringCreateLocalized("Ctrl+A"); n++;
             button1 = XmCreatePushButton(file_pane, "Answer", args, n);

             Motif's button accelerators and mnemonics are supported
             only for buttons in certain menus.  Xt has a more
             general facility, also called accelerators, for
             allowing events in one widget to invoke actions in
             another.

             Xt accelerators are mappings of event descriptions to
             actions, in the same format as a translation table.  An
             application or user supplies accelerators for a widget
             as the value of the Core resource XXmmNNaacccceelleerraattoorrss.  The
             accelerators map events to actions of this widget,
             called the source widget.  The application must then
             install the accelerators on a destination widget, using
             XXttIInnssttaallllAAcccceelleerraattoorrss.  This routine takes two
             arguments: the source widget, whose XXmmNNaacccceelleerraattoorrss
             resource contains the accelerator table; and the
             destination widget, where the accelerators are to be
             installed.  When the user produces an event in the
             destination widget that maps to an accelerator in the
             table, the event invokes the corresponding action _i_n
             _t_h_e _s_o_u_r_c_e _w_i_d_g_e_t.

             XXttIInnssttaallllAAcccceelleerraattoorrss merges the accelerators with the
             destination widget's existing translations (the value
             of XXmmNNttrraannssllaattiioonnss).  Accelerators can be merged in
             either ##aauuggmmeenntt mode, the default, or ##oovveerrrriiddee mode.
             An accelerator table may begin with an ##aauuggmmeenntt
             directive or a ##oovveerrrriiddee directive.  The ##rreeppllaaccee
             directive is ignored.





        August 26, 1994                                        13-29







        OSF/Motif Programmer's Guide


             As with translations, accelerators must be in an
             internal format when they are the value of
             XXmmNNaacccceelleerraattoorrss.  A string-to-accelerator-table
             converter parses an accelerator table string from a
             resource file.  An application can use
             XXttPPaarrsseeAAcccceelleerraattoorrTTaabbllee to compile an acclerator table
             string explicitly.

             Accelerators are often defined for a parent source
             widget and installed on one or more child destination
             widgets.  The SelectionBox and FileSelectionBox widgets
             install accelerators, the value of XXmmNNtteexxttAAcccceelleerraattoorrss,
             on their text children.  The default accelerators bind
             KKUUpp, KKDDoowwnn, KKBBeeggiinnLLiinnee, KKEEnnddLLiinnee, and KKRReessttoorree events
             in the Text widget to SelectionBox or FileSelectionBox
             actions that select an item in the List and replace the
             Text widget value with that List item.



        13.5  EEvveenntt HHaannddlleerrss



             Many applications can implement their entire input
             processing by adding procedures to widget callback
             lists and by adding mnemonics and accelerators for menu
             buttons.  Some applications change translations,
             accelerators, or actions.  More rarely, an application
             needs finer control over event processing.  Such an
             application can register an event handler with the Xt
             event dispatcher.

             An event handler is a procedure that the Xt event
             dispatcher calls when the application receives events
             of one or more types.  An event handler procedure is of
             type XXttEEvveennttHHaannddlleerr.  It receives four arguments: the
             widget for which the event arrived; any client data
             registered with the event handler; a pointer to the
             event; and a Boolean return argument telling the Xt
             dispatch facility whether or not to call the remaining
             event handlers registered for this event.  This
             argument is initialized to True and should rarely be
             changed.

             An application usually registers an event handler using
             the function XXttAAddddEEvveennttHHaannddlleerr.  The arguments are the
             widget, an event mask, an indication whether or not the
             hander should be called for nonmaskable events, the
             procedure itself, and any client data to be passed to
             the event handler when it is called.  The order in




        13-30                                        August 26, 1994







                               Input, Focus, and Keyboard Navigation


             which event handlers are called is undefined when more
             than one handler exists for a given widget and event
             type.  However, if the application registers the event
             handler using XXttIInnsseerrttEEvveennttHHaannddlleerr, it can specify that
             the procedure is to be called either before or after
             all currently registered event handlers.

             Motif requires an application to provide an event
             handler if it wants to post a PopupMenu on a button
             press.  The call to XXttAAddddEEvveennttHHaannddlleerr should specify
             BBuuttttoonnPPrreessssMMaasskk as the event mask and the popup
             RowColumn as the client data.  The event handler should
             use XXmmMMeennuuPPoossiittiioonn to position the menu at the x and y
             location of the button press event.  It should then
             manage the RowColumn.  If the button press matches the
             event specified by the RowColumn's XXmmNNmmeennuuPPoosstt
             resource, Motif posts the PopupMenu. See Chapter 6 for
             more information.





































        August 26, 1994                                        13-31





 t
