Is there any downside of calling XkbSetDetectableAutoRepeat? It's commented out. What happens on those X servers where it's broken? I've attached a patch. It uncomments that, and also does a slightly better job in cases where detectable auto-repeat isn't enabled.

Trent

On 15-08-15 11:57 PM, Trent Gamblin wrote:
Appears to be this 4ms value in xkeyboard.c... I will play around with this.

-----Original Message-----
From: Allegro-developers [mailto:[email protected]] On Behalf 
Of Trent Gamblin
Sent: August 15, 2015 11:49 PM
To: [email protected]
Subject: [AD] Possibly major bug on Linux

Got a bug report about some weird behaviour of my game, got to investigating...

Running ex_keyboard_events, if I hold down a key, I get random KEY_UP followed 
by KEY_DOWN events admidst the stream of KEY_CHAR events. In my case, this is 
very bad... This happens between somewhat frequently to somewhat infrequently. 
In some cases it takes a minute between these errors and sometimes it's every 
few seconds. It seems to happen with different keys, I tested LEFT, RIGHT and 
SPACE. Can anyone confirm this or give a reason for it?

_______________________________________________
Allegro-developers mailing list
[email protected]
https://mail.gna.org/listinfo/allegro-developers


_______________________________________________
Allegro-developers mailing list
[email protected]
https://mail.gna.org/listinfo/allegro-developers

diff --git a/src/x/xkeyboard.c b/src/x/xkeyboard.c
index 7dd46dd..92f2fd8 100644
--- a/src/x/xkeyboard.c
+++ b/src/x/xkeyboard.c
@@ -62,6 +62,11 @@ typedef struct ALLEGRO_KEYBOARD_XWIN
 } ALLEGRO_KEYBOARD_XWIN;
 
 
+typedef struct ALLEGRO_KEY_REPEAT_DATA {
+   XKeyEvent *event;
+   bool found;
+} ALLEGRO_KEY_REPEAT_DATA;
+
 
 /* the one and only keyboard object */
 static ALLEGRO_KEYBOARD_XWIN the_keyboard;
@@ -275,8 +280,6 @@ static int modifier_flags[8][3] = {
 /* Table of key names. */
 static char const *key_names[ALLEGRO_KEY_MAX];
 
-
-
 /* update_shifts
  *  Update Allegro's key_shifts variable, directly from the corresponding
  *  X11 modifiers state.
@@ -362,6 +365,22 @@ static int find_unknown_key_assignment(int i)
 }
 
 
+/* XCheckIfAny predicate that checks if this event may be a key repeat event */
+static Bool check_for_repeat(Display *display, XEvent *event, XPointer arg)
+{
+   ALLEGRO_KEY_REPEAT_DATA *d = (ALLEGRO_KEY_REPEAT_DATA *)arg;
+
+   (void)display;
+
+   if (event->type == KeyPress &&
+      event->xkey.keycode == d->event->keycode &&
+      (event->xkey.time - d->event->time) < 4) {
+      d->found = true;
+   }
+
+   return False;
+}
+
 
 /* _al_xwin_keyboard_handler:
  *  Keyboard "interrupt" handler.
@@ -426,22 +445,21 @@ void _al_xwin_keyboard_handler(XKeyEvent *event, ALLEGRO_DISPLAY *display)
    }
    else { /* Key release. */
      /* HACK:
-      * Detect key repeat by looking forward to see if this release
-      * is followed directly by a press event, in which case we assume
-      * that this release event was generated in response to that key
-      * press event. Events are simultaneous if they are separated by
-      * less than 4 ms (a value that worked well on one machine where
-      * this hack was needed).
+      * Detect key repeat by looking forward to see if this release is
+      * followed by a press event, in which case we assume that this release
+      * event was generated in response to that key press event. Events are
+      * simultaneous if they are separated by less than 4 ms (a value that
+      * worked well on one machine where this hack was needed).
       * 
-      * This is unnecessary on systems where XkbSetDetectableAutorepeat
-      * works.
+      * This is unnecessary on systems where XkbSetDetectableAutorepeat works.
       */
       if (XPending(event->display) > 0) {
-         XEvent next_event;
-         XPeekEvent(event->display, &next_event);
-         if ((next_event.type == KeyPress) &&
-             (next_event.xkey.keycode == event->keycode) &&
-             (next_event.xkey.time - event->time) < 4) {
+         ALLEGRO_KEY_REPEAT_DATA d;
+         XEvent dummy;
+         d.event = event;
+         d.found = false;
+         XCheckIfEvent(event->display, &dummy, check_for_repeat, (XPointer)&d);
+         if (d.found) {
             return;
          }
       }
@@ -708,13 +726,13 @@ static int x_keyboard_init(void)
 
    _al_mutex_lock(&s->lock);
    
-/* HACK: XkbSetDetectableAutoRepeat is broken in some versions of X.Org
+   /* HACK: XkbSetDetectableAutoRepeat is broken in some versions of X.Org */
    Bool supported;
    XkbSetDetectableAutoRepeat(s->x11display, True, &supported);
    if (!supported) {
       ALLEGRO_WARN("XkbSetDetectableAutoRepeat failed.\n");
    }
-*/
+
 #ifdef ALLEGRO_XWINDOWS_WITH_XIM
    ALLEGRO_INFO("Using X Input Method.\n");
 
_______________________________________________
Allegro-developers mailing list
[email protected]
https://mail.gna.org/listinfo/allegro-developers

Reply via email to