Jouke has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I'm trying to write my first Tk based perlscript. I want the script to respond to a single mousebutton-click to callback A, and a doubleclick to callback B.

I'm bind-ing these events to the callbacks, but every time I do a doubleclick, it first sees a 'click' and calls callback A, and after that it realizes it was actually a doubleclick and calls B also.

This is -of course- not what I want. What do I do to get a doubleclick only to generate the call of callback B, and not A?

Any ideas?

Jouke Visser, Perl 'Adept'

Replies are listed 'Best First'.
Re: Tk click/doubleclick
by Anonymous Monk on Feb 05, 2001 at 19:49 UTC

    Most GUI systems do exactly this; that's why the single-click action (e.g. 'select a file') is usually implied by the double-click action (e.g. 'open a file').

    I'm not too familiar with Tk, but what you want to do is likely to set some sort of 'timeout callback' that is registered with your main loop (or with Tk?) when a single-click is registered, and then cancel that callback if the double-click is received.

    So, e.g.:

    <pseudocode> sub callback_A { $global{click_timeout} = set_timeout (after=>($config{double_click_time} * 1.5), do=>sub { &callback_A_really(@_); } ); } sub callback_B { cancel_timeout ($global{click_timeout}); # do double-click event } sub callback_A_really { # do single-click event } </pseudocode>

    Of course, callback_A_really could be coded directly into the anonymous sub (closure, da?) in this example, but only if your main loop can handle a timeout like this. The *1.5 is there to ensure that a double-click right on the 'threshold' of being valid doesn't enter a sort of race condition with the timeout.

    If Tk doesn't have a similar timeout feature, you can fall back to using POSIX 'alarm' or similar. (But I don't know if that's portable to Win32 | MacOS ?)

     

    My real suggestion, though, would be to evade the problem by 'using the UI the usual way.' What are you trying to do in a case like this that would benefit from not using the standard UI semantics, i.e. a single-click is implied by the first click in a double-click sequence? I'd expect you to thoroughly confuse your user if you implement something like that...

    A good reference is the Macintosh Human Interface Guidelines (this is for System 8)... there are good reasons they did things the way they did :-)

      (me again... logged in now :-) )

      For the record/from the CB: the input device in use actually has 4 (buttons?): left single, left double, Rx1, Rx2; so there will be a fixed double-click timeout. Since this is for Win32, something of the nature of a main loop timer or Tk timeout like the above (probably invalid/nasty) pseudocode might be The Right Thing...

      The Tk functions you need seem to be $timeout = Tk->after (time, \&sub); and Tk->after(cancel=>$timeout); which I found in libwww-perl archives.

      Hope this helps!