carl@quad1.quad.com (Carl Priddy) (10/11/90)
Hey out there: I am having difficulty in coming up with a method of recognizing double clicks of mouse buttons. Currently, when I see one, I then enter a timeout value (via select()) and use XCheckIfEvent() to see if the button of interest was pressed. This works, sometimes. I am very interested in how anyone else has accomplished this. Thanks a heap, carl.
kieron@root.co.uk (Kieron Drake) (10/11/90)
In <15395@gouda.quad.com> carl@quad1.quad.com (Carl Priddy) writes: >Hey out there: > I am having difficulty in coming up with a method of recognizing > double clicks of mouse buttons. Currently, when I see one, I > then enter a timeout value (via select()) and use XCheckIfEvent() > to see if the button of interest was pressed. This works, sometimes. > I am very interested in how anyone else has accomplished this. >Thanks a heap, >carl. The normal Xt intrinsics provide an easy way to handle this via a count field in translation table entries. You can always do your own timing and stuff if you wish but why bother to reinvent the wheel? DIGRESSION: In fact the X protocol makes it impossible to reliably handle double clicks with arbitrary time envelopes. Basically the problem is that events which are "close" in server time (and are reliably time-stamped as such) may arrive at the client with arbitrary temporal separation (but in order) due to the various latencies of the intervening layers. One cannot, without an extension, make the server recognise such sequences and return a special event for them, or a ClientMessage event, or somesuch. Of course, in real life, the delays that are likely are sufficiently small that waiting for a "suitable time" for an event with a timestamp in the required range is OK. Some may be missed, of course, but most dialogues use double-clicks to indicate operations that are "more powerful" than those for single-clicks so the late-arrivals can be dealt with. This does restrict the styles of interaction available though, so that one could not have have single-click meaning delete and double-click meaning execute, say, as a belatedly recognised execute would find the object deleted already. This may or may not be a good thing but it is worth recognising the restriction even if it isn't onerous. END DIGRESSION Meanwhile, back at the ranch.........in translation tables..... The optional count field follows an event type and is enclosed in parentheses. So double-click on Button 1 up would be: <Btn1Up>(2): something()\n which is equivalent to: <Btn1Down>,<Btn1Up>,<Btn1Down>,<Btn1Up>: something()\n with appropriate timers (default 200mS) retriggered by each event if things are fast enough or expiring, and not matching, if too slow. The timers can be set from resources or with XtSetMultiClickTime with the values being integers and the default being 200, in units of mS. Thus one could have: Xbozo.MultiClickTime: 619 *multiClickTime: 450 as lines in a resource file, or use the following code: XtSetMultiClickTime( XtDisplay(toplevel), 619); in xbozo.c, say. The names are important :-) XtSetMultiClickTime is defined as: void XtSetMultiClickTime( dpy, time ) Display *dpy; int time; Once can specify "n or more" events to match, if they all have a maximum separation within the multi-click-time bound, by following the count with a plus ('+'), e.g.: <Btn1Up>(2+): clicketyclick()\n in a translation entry means match two or more button 1 realeases, each separated by no more than multi-click-time. One final caveat: (a) motion events can occur between repeated events and a match will still occur and, also, (b) sequences that match two specifications will only be taken once if one specification is a non-initial subset of the other and the matching events have occurred in the context of the longer one. This means that: <Key>A,<Key>B: ab()\n\ <Key>B: b() works as expected, action b is only taken if a B-Key press is not immediately preceeded by an A-Key press. If one had replaced "<Key>A" by "<Btn1Down>" and "<Key>B" by "<Btn1Up>" then the equivalent would occur: b would only be called if the button release is not immediately preceeded by a press. This means, in the context of repeated button or key events, that motion events will always be matched as a subset of them, between the button or key events, so one cannot then have a separate translation for the pointer motion events and expect a match. Pointer motion and double-clicks don't mix in the same translation table. Hope this helps. kieron -- Kieron Drake MAIL: kieron@root.co.uk SNAIL: UniSoft Ltd, Saunderson House, Hayne Street, London EC1A 9HH PHONE: +44 71 315 6637 (direct) +44 71 315 6600 (switchboard)