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