[comp.windows.x] Accelerator improvments wanted

salevin%drlc1@CONVEX.COM (S. A. Levin[Stewart]) (05/30/90)

==
Some time back, I worked with an X10 application that took keystroke
input as an alternative to popping up menus.  To convert it to X11,
I decided to use widgets with the X Toolkit (-lXt) accelerator mechanism
instead of raw Xlib event handling.  This turned out to be a mistake.
The difficulty is that there is no facility designed into the event
translation mechanism for distinguishing temporal space between
keystrokes, i.e.  "ST" is indistinguishable from "S"-wait-days-"T".
Similarly, there is no way to define an action for "S" alone if
an "ST" action is defined, e.g. to pop up a prompting menu if "T"
is not forthcoming.

For translations, one can overcome this problem by using the XtGetValues/
XtSetValues to retrieve, replace, and restore the translations appropriate
to each keystroke (event) in the prefix sequence.  Timeouts would be
handled using the normal XtAppAddTimeOut timer mechanism.  Insuring that
the toplevel translations get restored under all circumstances can be tricky.
System dependencies might also get in the way if XtUninstallTranslations
is called and happens to free up storage.

For accelerators, the situation is much less clear.  While there is no
problem saving or restoring accelerator tables with the XtNaccelerator
resource, this is not what we need.  Instead we want to save, replace
and restore state of any or all accelerators installed on the widget.
This is probably installation dependent as no explicit state is defined
for the installed accelerators.  I believe that saving and restoring
the translations after the accelerators have been installed will
accomplish the job.  For example,

	XtSetArg(arg[0],XtNtranslations,translations);
	XtSetValues(w,arg,1);
	XtSetArg(arg[0],XtNaccelerators,accelerators);
	XtSetValues(wsub,arg,1);
	XtInstallAccelerators(w,wsub);
	XtSetArg(arg[0],XtNtranslations,translations);
	XtGetValues(w,arg,1);
	savestate = (XtTranslations) arg[0].value;

would install successively translations and accelerators on the widget
and produce state that could be reinstalled in the future.

Differentiating between the widget's own translations and any installed
accelerators is not possible, however, and this leads to problems. If the
initial translations are defined in a resource file, there is no separate
parsed translation table which the program can save in order to reuse it
with different accelerators.

So problems remain.  Here are possible changes to X or the toolkit that
would solve them.

1) Enhance the X server (and protocol) to define an optional "timeout"
   event after each keystroke and button press.  An X call would set
   the timeout interval for a given window.  In this way, time sensitive
   interpretation of key or button sequences (e.g. double clicks) could
   be handled using ordinary translations:

	:<Key>A,<Timeout>:  PromptMenu("help")\n
	:<Key>A,:<Key>B:    Myaction("B")\n

   The advantage of this is that the time-critical measurements are made
   on the server side, where the user is, not on the client side, potentially
   halfway around the world.

2) Enhance the Toolkit Intrinsics to explicitly provide retrieval and
   restoration of translations and accelerators guaranteed not to be
   corrupted by subsequent toolkit internal actions or side effects.
   The advantage of this is that the underlying X protocol is unaffected
   and applications will be backward compatible, by and large, with
   existing X releases.

--- stew@hanauma.stanford.edu

mouse@SHAMASH.MCRCIM.MCGILL.EDU (der Mouse) (06/04/90)

> [is having problems with Xt accelerators]
> The difficulty is that there is no facility designed into the event
> translation mechanism for distinguishing temporal space between
> keystrokes, i.e.  "ST" is indistinguishable from "S"-wait-days-"T".

Or elsewhere, such as with pointer motion or button events.

> So problems remain.  Here are possible changes to X or the toolkit
> that would solve them.

> 1) Enhance the X server (and protocol) to define an optional
>    "timeout" event after each keystroke and button press.

I'd like to see it available after button releases and pointer motions
as well.  To handle double clicks properly, it must be available after
button releases, in fact; otherwise  push-release-wait-push-release
(two single clicks) will be indistinguishable from
push-release-push-release (a double click), since neither one will
generate any timeout events.

>    An X call would set the timeout interval for a given window.

Are you sure the window is the right thing to use as the handle for
setting the timeout?  I think it should be the (window,client) pair,
the way event masks already are.

Ideally, it should be possible to set different timeout times for each
event which is set to generate a timeout, but that's probably more than
is necessary.

>    The advantage of this is that the time-critical measurements are
>    made on the server side, where the user is, not on the client
>    side, potentially halfway around the world.

Precisely.

I've been annoyed for some time because it is not currently possible to
handle multiple mouse clicks correctly.  I'm glad someone else sees the
need for timeout events....

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu