Q. The left and right arrows in an XmSpinBox are mapped to the spinbox up and down arrows. How can I change this so that they move the cursor left and right in SpinBox text fields instead? A. This can be done by overriding the translations and accelerators for the SpinBox and SimpleSpinBox widgets. This can most easily be achieved by including the following in the X resources for your application: *XmSpinBox.translations: \ : SpinBArm()\n\ : SpinBDisarm()\n\ : SpinBEnter()\n\ : SpinBLeave()\n\ :osfUp: SpinBNext()\n\ :osfDown: SpinBPrior()\n\ :osfUp: SpinBDisarm()\n\ :osfDown: SpinBDisarm()\n\ :osfLeft: SpinBDisarm()\n\ :osfRight: SpinBDisarm()\n\ :osfBeginLine: SpinBFirst()\n\ :osfEndLine: SpinBLast() *XmSpinBox.accelerators: \ #override\n\ osfUp: SpinBNext()\n\ osfDown: SpinBPrior()\n\ osfUp: SpinBDisarm()\n\ osfDown: SpinBDisarm()\n\ osfLeft: SpinBDisarm()\n\ osfRight: SpinBDisarm()\n\ osfBeginLine: SpinBFirst()\n\ osfEndLine: SpinBLast() *XmSimpleSpinBox.translations: \ : SpinBArm()\n\ : SpinBDisarm()\n\ : SpinBEnter()\n\ : SpinBLeave()\n\ :osfUp: SpinBNext()\n\ :osfDown: SpinBPrior()\n\ :osfUp: SpinBDisarm()\n\ :osfDown: SpinBDisarm()\n\ :osfLeft: SpinBDisarm()\n\ :osfRight: SpinBDisarm()\n\ :osfBeginLine: SpinBFirst()\n\ :osfEndLine: SpinBLast() *XmSimpleSpinBox.accelerators: \ #override\n\ osfUp: SpinBNext()\n\ osfDown: SpinBPrior()\n\ osfUp: SpinBDisarm()\n\ osfDown: SpinBDisarm()\n\ osfLeft: SpinBDisarm()\n\ osfRight: SpinBDisarm()\n\ osfBeginLine: SpinBFirst()\n\ osfEndLine: SpinBLast() Alternatively this can be done programmatically. First we need to construct the translation and accelerator tables that will be applied to the SpinBox or SimpleSpinBox widgets. The following routines (SpinBoxAccelerators and SpinBoxTranslations) can be used to perform this task: #include #include #include static _XmConst char SpinBoxTranslationString[] = "\ : SpinBArm()\n\ : SpinBDisarm()\n\ : SpinBEnter()\n\ : SpinBLeave()\n\ :osfUp: SpinBNext()\n\ :osfDown: SpinBPrior()\n\ :osfUp: SpinBDisarm()\n\ :osfDown: SpinBDisarm()\n\ :osfBeginLine: SpinBFirst()\n\ :osfEndLine: SpinBLast()"; static _XmConst char SpinBoxAcceleratorString[] = "#override\n\ osfUp: SpinBNext()\n\ osfDown: SpinBPrior()\n\ osfUp: SpinBDisarm()\n\ osfDown: SpinBDisarm()\n\ osfBeginLine: SpinBFirst()\n\ osfEndLine: SpinBLast()"; #ifndef _NO_PROTO XtAccelerators SpinBoxAccelerators(void) #else /* _NO_PROTO */ XtAccelerators SpinBoxAccelerators() #endif /* _NO_PROTO */ { static XtAccelerators accelerators = (XtAccelerators) 0 ; if (accelerators == (XtAccelerators) 0) { accelerators = XtParseAcceleratorTable(SpinBoxAcceleratorString) ; } return accelerators ; } #ifndef _NO_PROTO XtTranslations SpinBoxTranslations(void) #else /* _NO_PROTO */ XtTranslations SpinBoxTranslations() #endif /* _NO_PROTO */ { static XtTranslations translations = (XtTranslations) 0 ; if (translations == (XtTranslations) 0) { translations = XtParseTranslationTable(SpinBoxTranslationString) ; } return translations ; } Having created the tables we need to set the appropriate widget resources. In terms of the SpinBox (as opposed to SimpleSpinBox) widget, it does not matter if the accelerators and translations are applied before or after the widget is created so either of the following code fragments could be used to set these on the widget: XtTranslations t = SpinBoxTranslations() ; XtAccelerators a = SpinBoxAccelerators() ; XtSetArg(al[ac], XmNaccelerators, a) ; ac++ ; XtSetArg(al[ac], XmNtranslations, t) ; ac++ ; spinBox = XmCreateSpinBox(parent, name, al, ac) ; or spinBox = XmCreateSpinBox(parent, name, NULL, 0) ; XtVaSetValues(spinBox, XmNtranslations, t, XmNaccelerators, a, NULL) ; For the SimpleSpinBox widget the rules are a little different in that the accelerators at least have to be applied at widget creation time: XtAccelerators a = SpinBoxAccelerators() ; XtSetArg(al[ac], XmNaccelerators, a) ; ac++ ; simpleSpinBox = XmCreateSimpleSpinBox(parent, name, al, ac) ; For safety we recommend applying both translations and accelerators in the create method for SimpleSpinBox widgets. Using the above methods you should find that the left and right arrow keys will move the cursor through the text in the SpinBox TextField widgets instead of triggering the SpinBox up and down arrows. Note that the above example includes translations to correct a problem on Solaris systems whereby the up and down SpinBox arrows are reversed. You can read more about this Solaris Motif bug in an earlier Motifdeveloper.com technical tip. It is not necessary to include these translations for other platforms.