[comp.windows.x] Accelerators

grady@fxgrp (Steven Grady) (11/10/88)

Ater reading and rereading (ad infinitum) the 1-page section (10.4)
on accelerators in the Xt doc, I think I'm finally starting to
understand them.  The documentation is rather opaque, so I'm not
sure about this, but tell me if I have this right.

An accelerator is simply a registered set of translations
which can be exported to other widgets.  For instance, a
menu widget might include a translation like "<Ctrl>X: itemX()"
to indicate that hitting Ctrl-X invokes the itemX() function.

This accelerator can be used after it has been installed in
other widgets, using XtInstallAccelerators().  The destination
widget, after this call, will have all the mappings of the
accelerators of the source widget available.  Thus, if I
say "XtInstallAccelerators(textEditingWidget, menuWidget)",
then all my accelerators for the menu widget will now be available
from within the context of the text-editing widget.

Do I have it right so far?

OK, assuming I do..  What does it mean to "display" an accelerator?
Why would a widget want to display its accelerators?
What exactly does the display_accelerator function do?

There is a variable used by some programs, XtInheritDisplayAccelerator,
which is mentioned in the Xt doc, but not described.
This variable is the only reference to accelerators I've found
in _any_ of the X11 code.  Makes it hard to learn by looking
at examples..  Does anyone actually use accelerators?

My other concern is the design of accelerators in general.
My thought is that it would be better to allow have widgets
make public (within the application) those functions that
can be associated with accelerators.  Then, any widget which
wants to use an accelerator can bind to that action in a way
similar to other translations, ie:
	program*textEditingWidget.translations: #override\
		<Ctrl>X: program*menuWidget*itemX()

This would allow different widgets to use different accelerators
to access a function -- for instance, one widget could use
"<Key>?" to pop up a help widget, whereas another could use
"<Ctrl>H".  To make an accelerator available to all widgets,
you could simply say:
	program*translations: #augment\
		<Ctrl>X: program*menuWidget*itemX()

This method seems to me to be more general, and it also fits within
the structure of normal translations..

	Steven
	...!ucbvax!grady
	grady@postgres.berkeley.edu

asente@decwrl.dec.com (Paul Asente) (11/15/88)

In article <861@fxgrp.UUCP> grady@fxgrp (Steven Grady) writes:
>This accelerator can be used after it has been installed in
>other widgets, using XtInstallAccelerators().  The destination
>widget, after this call, will have all the mappings of the
>accelerators of the source widget available.  Thus, if I
>say "XtInstallAccelerators(textEditingWidget, menuWidget)",
>then all my accelerators for the menu widget will now be available
>from within the context of the text-editing widget.
>
>Do I have it right so far?

So far, so good.

>OK, assuming I do..  What does it mean to "display" an accelerator?
>Why would a widget want to display its accelerators?
>What exactly does the display_accelerator function do?

Often times a widget will want to display in itself some representation of
the accelerator.  For example, if you have a menu item accessible through
the ^C accelerator, you might want to display the string "^C" in your menu
item.  The display_accelerator function gets called when a widget's
accelerator is installed, and gets passed a text representation of the
accelerator.  It can do anything it wants with it, including ignoring it.

>There is a variable used by some programs, XtInheritDisplayAccelerator,
>which is mentioned in the Xt doc, but not described.
>This variable is the only reference to accelerators I've found
>in _any_ of the X11 code.  Makes it hard to learn by looking
>at examples..  Does anyone actually use accelerators?

The built-in widgets (Core, Composite...) are basically prototypes; they
normally have no actions, and thus, no accelerators.  Displaying
accelerators is meaningless for them, so they have NULL
display_accelerator functions.  XtInheritDisplayAccelerator, like other
XtInherit values, specifies that a widget should inherit its parent's
display_accelerator function.

>My other concern is the design of accelerators in general.
>My thought is that it would be better to allow have widgets
>make public (within the application) those functions that
>can be associated with accelerators.  Then, any widget which
>wants to use an accelerator can bind to that action in a way
>similar to other translations, ie:
>	program*textEditingWidget.translations: #override\
>		<Ctrl>X: program*menuWidget*itemX()

What you specify for the toolkit is
	program*menuWidget.accelerator: <Ctrl>X:itemX()
and install the accelerator for menuWidget in some other widget (e.g.
textEditingWidget) in your code.

>This would allow different widgets to use different accelerators
>to access a function -- for instance, one widget could use
>"<Key>?" to pop up a help widget, whereas another could use
>"<Ctrl>H".  To make an accelerator available to all widgets,
>you could simply say:
>	program*translations: #augment\
>		<Ctrl>X: program*menuWidget*itemX()

One design aim was that a particular widget instance should always have
the same accelerator anywhere it is available -- you don't want people to
type one accelerator sequence one place and another one someplace else.
You may disagree with this, but it seems a laudible goal.

	-paul asente

jpool@BBN.COM (Jeremy Pool) (05/05/89)

A few months back Ralph Swick posted an instructional example of how to use
accelerators.  The example was a modification to x11r3/examples/Xaw/xboxes.c,
and showed how to attach Ctrl-c as an accelerator to the "quit" button of
this sample Xaw program.  The modification was real simple:  Just add:

        XtInstallAccelerators(toplevel, q);     /* q = the quit PushButton */

prior to realizing the widget hierarchy, and adding:

        Demo*quit.accelerators: Ctrl<Key>c: set() notify()

to your resources.

I have found two problems in trying to repeat, and modify, this example.

1) I was able to get the accelerator to work only if I installed it on the
   top-most box widget in the widget hierarchy, but not if I installed it
   on toplevel (as shown) or on the viewport which is toplevel's child and
   the box widget's parent.  I can't figure out any obvious reason for
   this, as I would have expected the keyboard event to have been passed
   up the hierarchy, even to toplevel, until it found a widget with a
   translation for this event.  Am I missing something here?

2) An installed accelerator works even when the source widget is
   insensitive.  The Intrinsics documentation doesn't appear to address
   this issue, but the behavior displayed (at least by the MIT Intrinsics
   implementation) seems counterintuitive.  If a button is insensitive,
   and therefore not dispatching to action procedures, wouldn't you expect
   not to be able to dispatch to those same action procedures via an
   accelerator?  Must I put an extra check into all widget action
   procedures, to check for widget sensitivity?

-- Jeremy Pool (jpool@bbn.com)

kochhar@endor.harvard.edu (Sandeep Kochhar) (08/04/89)

hi!
can anyone send me a small example of how to use accelerators?

or can you give me some idea of how to use XtInstallAccelerator etc.
in the following case: I have widgets A and B, and I want a button1down
event on widget A to have the same effect as if button1down occured on
B.

Thanks in advance.





Sandeep Kochhar
(617) 495-9515              mail: kochhar@harvard.harvard.edu
Harvard University                kochhar@harvard.csnet
33 Oxford st,                     kochhar@harvard.uucp
Cambridge, Ma 02138               kochhar@harvard.bitnet

"If you didn't get this message, please let me know."

gtl@stiatl.UUCP (George Li) (12/05/89)

    I'm having problems defining accelerators for widgets and
getting the action procedures to execute. I have been able to 
define accelerators whose procedure name strings are
defined by the particular widget class.  For example, 
"<Key>H: set() notify() unset()" is a valid accelerator for a
command widget. However, if I define my own action procedure and
reference it in an accelerator as in "<Key>H: mutilate()", the 
installed accelerator has no effect (the procedure associated
with the mutilate action isn't called).

    I've added the action (trying both XtAddAction() and 
XtAppAddAction()) with no success.

    Since an accelerator is just a translation table and you can 
define your own action procedures for translation tables, shouldn't
I be able to define my own action procedures for accelerators?

    I'm using X11R3 (Athena widgets) on a Sun 386i with 4.0.2.
    A small sample below:

/******************************************************************/
#include <stdio.h>
#include "Intrinsic.h"
#include "StringDefs.h"
#include "Command.h"
#include "Desk.h"

Widget toplevel;
Widget desk;
   Widget button1;
   Widget button2;

extern void helpproc();

main (argc, argv)
int argc;
char **argv;
{
   int n;
   Arg args[20];

   static Arg deskargs[] = {
      {XtNwidth,(XtArgVal)600},
      {XtNheight,(XtArgVal)400},
   };
   /**********************************************************/
   static XtActionsRec actionsTable[] = {
      {"help_action",helpproc}
   };

   static char defaultAccelerators[]="#override\n <Key>L: help_action()";
   /************************************************************/
   toplevel = XtInitialize(argv[0], "test", NULL, 0, &argc, argv);

   desk = XtCreateManagedWidget("desk", deskWidgetClass,
      toplevel, deskargs, XtNumber(deskargs));

   n = 0;
   XtSetArg(args[n], XtNwidth, 70); n++;
   XtSetArg(args[n], XtNheight, 20); n++;
   XtSetArg(args[n], XtNx, 100);  n++;
   XtSetArg(args[n], XtNy, 280); n++;
   XtSetArg(args[n],XtNaccelerators,XtParseAcceleratorTable(defaultAccelerators));n++;
   button1=XtCreateWidget("button1",commandWidgetClass,desk,args,n);

   n=0;
   XtSetArg(args[n], XtNwidth, 70); n++;
   XtSetArg(args[n], XtNheight, 20); n++;
   XtSetArg(args[n], XtNx, 300);  n++;
   XtSetArg(args[n], XtNy, 280); n++;
   button2=XtCreateWidget("button2",commandWidgetClass,desk,args,n);

   XtAddActions(actionsTable,XtNumber(actionsTable));   

   XtInstallAccelerators(button2,button1);
   XtManageChild(button1);
   XtManageChild(button2);

   XtRealizeWidget(toplevel);

   XtMainLoop();
}

void helpproc(widget, xev, params, num_params)
    Widget widget;
    XEvent *xev;
    String *params;
    Cardinal *num_params;
{
    printf("helpproc\n");
}
-- 
George Li                                             gatech!stiatl!gtl
Sales Technologies, Inc
3399 Peachtree Rd, NE
Atlanta, GA  30306

gates@CSCSUN1.LARC.NASA.GOV (Ray Gates) (09/26/90)

This question concerns the use of accelerators......specifically, it concerns
using accelerators to add a keyboard interface to the R4 SimpleMenu widget.
The goal is to associate the callback routines of the menu entries 
(smeBSB objects) with keyboard entries in another widget.
Attempts to this point have been unsuccessful.....
The R4 docs do not list accelerators as allowable resources for the menu
objects.....Is this the problem?????
If not, can anyone give me an idea on how to associate the accelerators
with the smeBSB objects in the SimpleMenu...........
THANKS.........
-- 
_______________________________________________________________________________
				       |        Ray Gates 
	"Mama, mama, many worlds       |	CSC/NASA-Langley
	 have come since I first       |	gates@cscsun1.larc.nasa.gov
               left home."	       |              (128.155.42.32)
				       |        Phone:  804.865.1725
-------------------------------------------------------------------------------
DISCLAIMER: The comments/opinions contained within are my own and do not
            necessarily represent the opinions of my employer(s).
-------------------------------------------------------------------------------

converse@EXPO.LCS.MIT.EDU (09/26/90)

> This question concerns the use of accelerators
> to add a keyboard interface to the R4 SimpleMenu widget.
> The goal is to associate the callback routines of the menu entries 
> (smeBSB objects) with keyboard entries in another widget.

R4 xmh has accelerators for many menu commands.  It also allows the user 
to create buttons for the same commands, similar to the R3 interface.


> The R4 docs do not list accelerators as allowable resources for the menu
> objects.....Is this the problem?????

No; there is an accelerator resource associated with the Simple Menu widget
that you can use.  The accelerators are associated with the menu, not with
the individual menu entries, because the SmeBSBObjectClass (the Athena 
widget set simple menu entry object class name) is not a subclass of Core.


> If not, can anyone give me an idea on how to associate the accelerators
> with the smeBSB objects in the SimpleMenu...........

Eyeball the accelerator resources in clients/xmh/Xmh.ad.

pete@iris49.UUCP (Pete Ware) (09/27/90)

gates> From: Ray Gates <riscc1!cscsun1.larc.nasa.gov!gates@bioc1.biosym.com>
gates> Date: Wed, 26 Sep 90 10:44:07 EDT

gates> If not, can anyone give me an idea on how to associate the accelerators
gates> with the smeBSB objects in the SimpleMenu...........

Unfortunately, you can't.  smeBSB are objects (gadgets) and do not
have a window associated with them.  Accelerators only work with
window objects (widgets).

--pete
Pete Ware / Biosym / San Diego CA / (619) 546-5532
uucp:	  scripps.edu!bioc1!pete
Internet: bioc1!pete@scripps.edu

ta_k@maths.su.oz.au (Katya Ta) (05/22/91)

Hi again,

If you install an Accelerator for a widget, for example that if
some key is pressed a particular action is done. The widget passed to
the action is it the one where the event occured or the widget which
has the acclerator installed?  thanks a lot

bye Katya

-- 
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-
      /   __    |             Katya Ta                 
   ----  |__| __|__           University of Sydney     
    --   |__|   |             Australia                
    --   |__|  \|             (ta_k@maths.su.oz.au)    
    __     /|   |                                            
   |__|  _/ |   | <-- Chay(Cantonese) == Ta.(Vietnamese) :)  
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-