Sponsored by IST Limited
Formerly MW3: Motif on the World Wide Web [MW3 Logo]
Last Updated
December 1, 2003

X-Designer - The Leading X/Motif GUI Builder - Click to download a FREE evaluation
About the site
Bulletin Board
News Archive
OpenGroup News
Frequently Asked Questions
The Motif FAQ
X/Motif FAQs
General FAQs
Ask Antony
Latest Q & A
All Q & As
Submit Question
Tips & Pointers
Code Examples
Widget Sets
GUI Toolkits & Libraries
Motif suppliers
Non-commercial S/W
Commercial Software
Docs & Pubs
X/Motif Newsgroups
Feedback Form

How to get the Up and Down arrows to work correctly with XmSpinBox

01-Dec-03 14:00 GMT

Question: Why do the Up and Down arrows work 'wrongly' with XmSpinBox?

My Solaris application contains a number of XmSpinBox widgets. I've noticed that when I use the keyboard arrow keys cycle the SpinBox values that the Up and Down keys seem to have the opposite effect to what I would expect. What is causing this?

You have stumbled upon a rather obscure problem that appears to be specific to the Solaris CDE Motif release. First, a little history. This problem was originally introduced many years ago with the introduction of Motif 2.0, which had the following translation table for theXmSpinBox widget:

:<Key>osfUp: SpinBPrior()
:<Key>osfDown: SpinBNext()
:<Key>osfLeft: SpinBLeft()
:<Key>osfRight: SpinBRight()
This persisted into early Motif 2.1 variants until it was fixed around the Motif version 2.1.20 stage, and now reads:
:<Key>osfUp: SpinBNext()
:<Key>osfDown: SpinBPrior()
:<Key>osfLeft: SpinBLeft()
:<Key>osfRight: SpinBRight()
This, as you can see, reverses the sense of Up and Down. For some reason Sun's CDE Motif still has the old Motif 2.0 behavior. It should be noted that most other platforms, including Open Motif on Linux, do not exhibit this problem.

When most developers encounter this problem they try to rectify it by using override translations. Unfortunately this alone is insufficient to resolve the problem. It is also necessary to you also need to change the associated Accelerators and install them on all child widgets.

This fix can easily be implement through a create callback on your SpinBox widgets. The following code example from our X-Designer Motif GUI Builder demonstrates this process:

The following code is available as spinbox.c.

** Generated by X-Designer

** X-Designer-generated prelude.
** Do not edit lines before "End of X-Designer generated prelude"
** Lines beginning ** X-Designer Stub indicate a stub
** which will not be output on re-generation

**LIBS: -lXm -lXt -lX11

#include <stdlib.h>
#include <X11/Xatom.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>

#include <Xm/Xm.h>
#include <Xm/SSpinB.h>
#include <Xm/SpinB.h>

#include "SpinBox.h"

/* End of X-Designer generated prelude */

** Patch to CDE SpinBox

#ifdef S_SUNOS5
static _XmConst char spinBoxTranslations[] = "\
<Btn1Down>: SpinBArm()\n\
<Btn1Up>: SpinBDisarm()\n\
<EnterWindow>: SpinBEnter()\n\
<LeaveWindow>: SpinBLeave()\n\
:<Key>osfUp: SpinBNext()\n\
:<Key>osfDown: SpinBPrior()\n\
:<Key>osfLeft: SpinBLeft()\n\
:<Key>osfRight: SpinBRight()\n\
:<KeyUp>osfUp: SpinBDisarm()\n\
:<KeyUp>osfDown: SpinBDisarm()\n\
:<KeyUp>osfLeft: SpinBDisarm()\n\
:<KeyUp>osfRight: SpinBDisarm()\n\
:<Key>osfBeginLine: SpinBFirst()\n\
:<Key>osfEndLine: SpinBLast()" ;

static _XmConst char spinBoxAccelerators[] =
<Key>osfUp: SpinBNext()\n\
<Key>osfDown: SpinBPrior()\n\
<KeyUp>osfUp: SpinBDisarm()\n\
<KeyUp>osfDown: SpinBDisarm()\n\
<Key>osfLeft: SpinBLeft()\n\
<Key>osfRight: SpinBRight()\n\
<KeyUp>osfLeft: SpinBDisarm()\n\
<KeyUp>osfRight: SpinBDisarm()\n\
<Key>osfBeginLine: SpinBFirst()\n\
<Key>osfEndLine: SpinBLast()" ;
#endif /* S_SUNOS5 */

** X-Designer Stub OnCreateSpinBox

void OnCreateSpinBox(Widget w, XtPointer client_data, XtPointer call_data)
#ifdef S_SUNOS5
    static XtTranslations translations = (XtTranslations) 0 ;
    static XtAccelerators accelerators = (XtAccelerators) 0 ;

    WidgetList children = (WidgetList) 0 ;
    Cardinal numChildren = (Cardinal) 0 ;
    int index = 0 ;

    if (translations == (XtTranslations) 0) {
	translations = XtParseTranslationTable(spinBoxTranslations) ;

    if (accelerators == (XtAccelerators) 0) {
	accelerators = XtParseAcceleratorTable(spinBoxAccelerators) ;

    XtOverrideTranslations(w, translations) ;

    XtVaSetValues(w, XmNaccelerators, accelerators, NULL) ;

    XtVaGetValues(w, XmNchildren, &children, XmNnumChildren, &numChildren, NULL) ;

    if (children != (WidgetList) 0) {
	for (index = 0 ; index < numChildren ; index++) {
	    XtInstallAccelerators(children[index], w) ;
#endif /* S_SUNOS5 */


Sponsored by X-Designer - The Leading X/Motif GUI Builder - Click to download a FREE evaluation


Goto top of page


[IST Limited]
IST Limited is the
proud sponsor of

Thanks to all the contributors to these pages.

Privacy Policy

"Motif" is a registered trademark of The Open Group. All other trademarks are the property of their respective owners.

Some articles/papers here have their own copyright notice. All other information is copyright ©1999-2008 IST Limited

[CommerceOne] MW3 site originally by Ken Sall of Commerce One (formerly Century Computing).