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.edumouse@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