USING HOTKEYS WITH ALL WIDGETS
 
 
INTRODUCTION

You may already be familiar with Motif's mnemonic mechanism. In case your're not, here's a short description: You can access every pulldown menu by means of only two keystrokes: the META key pressed together with another key. One more keystroke and you'll activate any item within a pull down menu. Although the OSF calls such combinations of the META and another key 'mnemonics' I'll rather use the term 'hotkey' instead of that OSF's tongue-twister. 

If you ever have played with dialog boxes from other GUIs you may have noticed that they often provide a similiar feature like hotkeys. This makes it possible for the user to move quickly within the dialog from one object to another pressing only two keys. But Motif doesn't provide this feature -- even not with Motif 2.0! 

A long time ago I submitted a solution for this problem to the Motif FAQ. In the meantime I've developed a much better solution, which I want to present here in the Motif Corner. The source is available under the terms of the GNU Public Licence. With this new solution you can easily assign a hotkey (mnemonic) to every widget within your application. 

  • For all descendants of the widget class XmLabel you simply set the resource XmNmnemonic. This typically applies to XmButton, XmToggleButton, and XmLabel of course. The XmNmnemonic is nothing new but already there since the dawn of Motif. Or was that the twilight zone...?
  • If you want to assign a hotkey to any other widget which is not a descendant of XmLabel you have to put a (descriptive) label widget right beside the offending widget. That is just either to the left or to the top of that particular widget for which the hotkey should be valid. Whenever the user activates the hotkey the keyboard focus will move to the offending widget. (The focus can't sit on a simple XmLabel.)
 

A little clarification. The picture to the right contains two widgets: a XmLabel displaying the text "file mask:" and a XmComboBox (sorry for the ad... I couldn't resist it... you can find the combo box widget here). The label's XmNmnemonic resource is set to XK_m. If the user presses META m, the keyboard focus will move to the combo box widget. 

My new hotkey support is able to figure out automagically to which widget the keyboard focus shall move after the user presses a hotkey. And it can even handle hotkeys for navigation between groups of controls. A second example to show you this feature. 

The picture to the right is such a typical case of a navigation group: Three toggle buttons in a row grouped visually with a frame surrounding them. The frame is entitled 'switches'. If the user presses META s the keyboard focus shall move to the first widget (which can accept the keyboard focus) within the frame. In our little example this'll be the toggle button entitled "toggle me". 

If the keyboard focus is already located within the frame, then the focus will not move anymore when pressing META s
 
UP AND RUNNING

Adding the Hotkey package to existing Motif applications is easy. In your application's main module (where the events get dispatched) first add a 

 #include <mnemonic.h>
Remember to put this header file (which comes with the Hotkey package) in some suitable place. And don't forget to add its location to the search path for #include's your C (or C++) compiler will look in. 

Next, there are two ways of using the Hotkey package, depending on the way your application receives and dispatches incomming events. 

You're using XtAppMainLoop() so far... 

All you need to do is to replace this call to XtAppMainLoop() by a call to XmAppMainLoop() using the same parameters as before. (Please note the change from Xt to a Xm prefix!) Then compile and link your application with the mnemonic.o module. That's all. And don't forget to update your resource file with the hotkey settings... 

You're using your own message dispatch loop... 

In case you're using your own rewritten event loop, you must call the function XmIsMnemonic(event) for every KeyPress event. If the function returns True, you must not dispatch this event, but instead wait for the next one. You may want to call XmIsMnemonic() with every incomming event, not only with keypress events. XmIsMnemonic() just ignores any event which is not a keypress and returns False

Your old message dispatch loop might look like this: 

 ....
 XEvent NextEvent;

 for (;;) {
     XtAppNextEvent(AppContext, &NextEvent);
     switch ( NextEvent.type ) {
     case xxxx:
         ....
     default:
         XtDispatchEvent(&NextEvent);
     }
 }
 ....
Now take a look at the slightly rewritten event loop which now uses the Hotkey package. After getting a fresh event from XtAppNextEvent() you first have to check for a possible hot key candidate. Do this by calling XmIsMnemonic() and don't dispatch the offending event, if the function returns True
 ....
 XEvent NextEvent;

 for (;;) {
     XtAppNextEvent(AppContext, &NextEvent);

     /* NEW NEW NEW */
     if ( XmIsMnemonic(&NextEvent) ) continue;

     switch ( NextEvent.type ) {
     case xxxx:
         ....
     default:
         XtDispatchEvent(&NextEvent);
     }
 }
 ....
That's all. Once again -- don't forget to update your resource files so your applications take advantage of the hotkeys. 

I hope this shows how to use the HotKey Package with your own X11/Motif applications. I've kept the package as simple and easy as possible. There's only one thing left to say: enjoy it - and hopefully your users find it usefull too! 

  • Motif 1.1 or 1.2, the code can identify which version you're using.
  • An ANSI C compliant C compiler (like gcc).
You can find a much more detailed paper about this package in the german UNIX magazine iX. As you might have already guessed: unfortuneatly it is written in German. Just for the curious: the paper has been published in the following issues: 
  • Harald Albrecht, Griffiges Motif, Tastenkürzel statt Mausbedienung: Teil 1, iX 7/94, Seite 172 ff.
  • Harald Albrecht, Fingerfertigkeit, Tastenkürzel statt Mausbedienung/Teil 2, iX 8/94, Seite 152 ff.
Here's a link to the iX magazine WWW server

Here you can read the online documentation.
Yes, I'm really interested in the Hotkey package, and I want it now!
Back to the Projects page

Contents: Harald Albrecht (albrecht@igpm.rwth-aachen.de) 
Layout: Harald Albrecht 
Last Change: 97/08/10 (ab)