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