Re: Issue 154:

http://code.google.com/p/pyglet/issues/detail?id=154&can=4&colspec=ID%20Status%20Type%20Milestone%20OpSys%20Summary

I took a look at the code that handles KeyPress/KeyRelease events
(XLibWindow._event_key; at line 1079). Although the comment

            # Look in the queue for a matching KeyPress with same timestamp,
            # indicating an auto-repeat rather than actual key event.

talks about comparing timestamps, actually that's never done in the
code. Only keycodes are checked.

I wondered whether it was true that autorepeat-generated
KeyRelease/KeyPress pairs had the same timestamp. It only made sense.
If true, it would be a reliable way to detect autorepeat in X(*).

I did a quick test in C, since I'm not good at ctypes and I'm not
using Python anymore. The following seems to work pretty well:

/*
 * Predicate to use with is_autorepeating.
 */
Bool is_corresponding_press(Display* dpy, XEvent* evt, XPointer arg) {
    XEvent* release_evt;

    release_evt = (XEvent*)arg;
    return (evt->type == KeyPress
            && evt->xkey.keycode == release_evt->xkey.keycode
            && evt->xkey.time == release_evt->xkey.time);
}

/*
 * pre: event is a KeyRelease event.
 *
 * post: If event was originated in an autorepeat event, remove the
 * corresponding KeyPress event from the queue and return true. Otherwise,
 * return false.
 */
Bool is_autorepeat(Display* dpy, XEvent* event) {
    XEvent whatever;
    return XCheckIfEvent(dpy, &whatever, is_corresponding_press,
(XPointer)event);
}

I don't even need to save an event list to push back into the event
queue. XCheckIfEvent removes the event for me iff it checks as an
autorepeat event. If you want to detect it and still handle it
somehow, I guess you need something more complicated than this.

So, in my main event handler I only have to call is_autorepeat for
KeyRelease event, and ignore the event if it returns true. I don't
have to do anything special for KeyPress events: autorepeat-generated
ones are removed before my event handler can see them.

I don't know if the exact test for time is robust across X server
implementations. Maybe a small tolerance will be needed for some? I'll
care about that when it bites me.

Since your comment talks about comparing timestamps, I wonder whether
you considered doing that, then rejected the idea. If so, could you
please share why?

Otherwise, I hope this is of help to you.


(*) It seems safe to assume you can't physically release and press a
key at the same millisecond, unless maybe you're using two keyboards
and are very (un)lucky. Robust enough for me.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pyglet-users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/pyglet-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to