















        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 iinnppuutt 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



        May 9, 1992                                             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 via
                  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 via 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 via 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                                             May 9, 1992








                               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 via 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 the section
                  "Controlling Keyboard Navigation" 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 pop-up menu if available.  When the
                  user posts a menu via KKMMeennuu or via 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



        May 9, 1992                                             13-3








        OSF/Motif Programmer's Guide


             focus model is determined by the value of the mmwwmm
             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a uu tt oo KK ee yy FF oo cc uu s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r aa ii ss ee KK ee yy FF oo cc uu s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
                  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.




        13-4                                             May 9, 1992








                               Input, Focus, and Keyboard Navigation


                +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:

                +o 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)

                +o 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

                +o 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



        May 9, 1992                                             13-5








        OSF/Motif Programmer's Guide


             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 the section "Traversing to Obscured Widgets"
             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.

             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.



        13-6                                             May 9, 1992








                               Input, Focus, and Keyboard Navigation


             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
                  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



        May 9, 1992                                             13-7








        OSF/Motif Programmer's Guide


        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 the section "Controlling
             Keyboard Navigation" above, 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 the section
             "Controlling Keyboard Navigation" 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
             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



        13-8                                             May 9, 1992








                               Input, Focus, and Keyboard Navigation


             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 via 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
             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 via 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



        May 9, 1992                                             13-9








        OSF/Motif Programmer's Guide


             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
             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.





        13-10                                            May 9, 1992








                               Input, Focus, and Keyboard Navigation


                +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:

                +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





        May 9, 1992                                            13-11








        OSF/Motif Programmer's Guide


                +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, via 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 XmEXCLUSIVE_TAB_GROUP.  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
                  (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.




        13-12                                            May 9, 1992








                               Input, Focus, and Keyboard Navigation


                +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 via 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
             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.







        May 9, 1992                                            13-13








        OSF/Motif Programmer's Guide


        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 the section
                  "Controlling Keyboard Focus" above.

             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
             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-14                                            May 9, 1992








                               Input, Focus, and Keyboard Navigation


        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 the section "Controlling Keyboard
             Navigation" above.  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
                  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



        May 9, 1992                                            13-15








        OSF/Motif Programmer's Guide


                       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 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.




        13-16                                            May 9, 1992








                               Input, Focus, and Keyboard Navigation


                       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 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.



        May 9, 1992                                            13-17








        OSF/Motif Programmer's Guide


                       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 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,
                       focus goes to the 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 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, 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 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,
                       focus goes to the next traversable tab group



        13-18                                            May 9, 1992








                               Input, Focus, and Keyboard Navigation


                       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 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 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, 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 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



        May 9, 1992                                            13-19








        OSF/Motif Programmer's Guide


             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
             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-20                                            May 9, 1992








                               Input, Focus, and Keyboard Navigation


        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
             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()





        May 9, 1992                                            13-21








        OSF/Motif Programmer's Guide


                +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 example, uupp__aaccttiioonn(()) below
                  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:

                  <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:

             #replace  The new translation table should completely
                       replace any existing table.  This is the
                       default if no directive is specified.

             #augment  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.

             #override 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.



        13-22                                            May 9, 1992








                               Input, Focus, and Keyboard Navigation


             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:

                     - 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
                  "#augment" 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
                  "#override" mode





        May 9, 1992                                            13-23








        OSF/Motif Programmer's Guide


                +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 via resource files.  For
             example, for some widgets it may not be possible to
             change traversal translations in this way.



        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
             via 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



        13-24                                            May 9, 1992








                               Input, Focus, and Keyboard Navigation


             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

                +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.  The purpose of this
             mapping is to allow Motif widgets and applications to
             use a single set of keysyms in translation tables but
             also make it possible for applications or 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



        May 9, 1992                                            13-25








        OSF/Motif Programmer's Guide


             referred to as "osf" keysyms.  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
             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, or 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, or in the directory specified by
                  the environment variable XXMMBBIINNDDDDIIRR, or in 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 translations string.  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: \



        13-26                                            May 9, 1992








                               Input, Focus, and Keyboard Navigation


                 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

             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.



        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



        May 9, 1992                                            13-27








        OSF/Motif Programmer's Guide


             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.

             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, such as "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



        13-28                                            May 9, 1992








                               Input, Focus, and Keyboard Navigation


             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 "#augment" mode,  the default, or "#override"
             mode.  An accelerator table may begin with an
             "#augment" directive or a "#override" directive.  The
             "#replace" directive is ignored.

             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



        May 9, 1992                                            13-29








        OSF/Motif Programmer's Guide


             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
             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.

























        13-30                                            May 9, 1992






 o
