Hi everyone. I'm learning some Tcl and Tk basics, enjoying what I'm
learning it so far.
I just found out an oddity about the classic Tk buttons: if you focus a button and hold down spacebar (so that it's depressed continuously) for a
few seconds and then release spacebar, then it seems to remain stuck in
the depressed state.
Nice catch. It's a bad interleaving of events then.Perhaps ButtonInvoke should be stopped from touching anything (or running at all) if the button is still depressed. Then these two procs would run in strict pairs without allowing a second ButtonInvoke messing things in between...
Let me see if I get this right...
If a second ButtonInvoke runs before the first ButtonInvokeEnd restablishes the button back to normal/raised, then the oldState/oldRelief variables get overwritten wrongly with active/sunken values, so then ButtonInvokeEnd does not reset them correctly.
But perhaps this could be fixed at a lower (and more general) level,
instead of hardcoding it using specific widget states or tracking state
with external variables. More precisely, the button binding script could
just ignore repeated keypresses, so tk::ButtonInvoke doesn't even get to
run until the next physical keypress. This way you don't need to manually track state changes.
For comparison, with the mouse, it is impossible to get a "repeated" click while the mousebutton is depressed, so the bad interleaving is impossible
for mouseclicks on Tk buttons, and so that obviates any need for extra
ad-hoc state tracking.
So, is it possible to (easily, reliably) detect an auto-repeated keypress
in Tk? Perhaps `bind` could provide a percent-substitution with a boolean value? Or perhaps some trick using <Double-Keypress-*> bindings ? I'm
really envying SDL's SDL_KeyboardEvent and Winapi's WM_KEYDOWN message,
both carry an explicit boolean indication for repeated keypresses.
Also, I notice the mouse-click logic and the spacebar-down logic use different code paths in button.tcl, perhaps they could share behavior?
i.e., holding down click vs holding down spacebar, does the difference matter? In win32, a native button gets depressed while click/space is down (repeats ignored) but the command fires only at last when click/space is released (both cases produce a WM_COMMAND message). I've been wondering
about this...
Last but not least, the <KeyRelease> event does not work properly on my
X11 desktops with autorepeat on (Tk 8.6.12 on i3wm, xfce, etc), for
instance with this code :
bind . <KeyPress> {puts "%# KeyPress %K"}
bind . <KeyRelease> {puts "%# KeyRelease %K"}
On X11 while I hold down some key, that prints a stream of alternated KeyPress and KeyRelease lines, but the proper behaviour should be a unique <KeyRelease> after each <KeyPress> repeated sequence, for each physical
key down/up pair. There was a similar bug reported for MacOSX some years
ago. It works correctly on Win32.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 495 |
Nodes: | 16 (2 / 14) |
Uptime: | 39:51:22 |
Calls: | 9,743 |
Calls today: | 3 |
Files: | 13,742 |
Messages: | 6,183,734 |