If I turn global autorepeat off while a key is already being repeated, the key doesn't stop repeating. It continues on and on. To turn autorepeat off I'm using the grab of another key. I'm not sure how this affects. I have prepared the following code for demonstrating the issue: reptest.c After the code, I quote 5 results from tests by running this code. The tests involve pressing a combination of a hotkey (in this code, Super_L) and the letter "k" in different combinations and timing. Tests A and B are OK, but tests C and D are not. Tests A, B, C, and D are under plain X11: startx `which xterm` -- :1 I think (but not sure) I'm using the evdev driver. I tried putting a lot of XFlush(dpy) all over the place, but it still happens. evtest and showkey output look pretty normal to me, but I can attach a sample if needed. I'm not sure what version of X.org is the first one to show the problem. At least, Ubuntu Jaunty (X 7.4, 1.6.0) does it, and Debian Sid, as of today (X server 1.7.7). /* * reptest.c: extract from Superkb to test autorepeat misbehavior. * * Copyright (C) 2005-2009, Octavio Alvarez Piza. * License: GNU General Public License v2. * * Compile with: gcc -Wall -std=gnu99 -pedantic -lX11 -o reptest reptest.c */ #include <X11/Xlib.h> #include <errno.h> #include <stdio.h> #include <stdarg.h> int main() { /* X11 connection setup */ Display *dpy; dpy = XOpenDisplay(NULL); /* Get code for "Super_L", as a sample hotkey. */ KeyCode hotkey; hotkey = XKeysymToKeycode(dpy, XStringToKeysym("Super_L")); Window rootwin; rootwin = DefaultRootWindow(dpy); /* Grab the hotkey */ XGrabKey(dpy, hotkey, AnyModifier, rootwin, True, GrabModeAsync, GrabModeAsync); XKeyboardState xkbs; /* Save hotkey autorepeat state */ int saved_hotkey_autorepeat_mode; XGetKeyboardControl(dpy, &xkbs); saved_hotkey_autorepeat_mode = (xkbs.auto_repeats[(int) hotkey/8] & hotkey % 8) > 0; /* Turn autorepeat off for the hotkey */ XKeyboardControl xkbc; xkbc.key = hotkey; xkbc.auto_repeat_mode = AutoRepeatModeOff; XChangeKeyboardControl(dpy, KBAutoRepeatMode | KBKey, &xkbc); /* This variable holds the autorepeat state for the whole keyboard while the hotkey is NOT pressed. */ int saved_autorepeat_mode = 0; while (1) { XEvent ev; XNextEvent(dpy, &ev); if (ev.xkey.keycode == hotkey && ev.type == KeyPress) { printf("[sk] Hotkey has been pressed, code: %d, name: %s.\n", ev.xkey.keycode, XKeysymToString(XKeycodeToKeysym(dpy, ev.xkey.keycode, 0))); XKeyboardState xkbs; /* Save autorepeat current state state, in order to restore it after hotkey is released. Autorepeat will be turned off in the meanwhile. */ XGetKeyboardControl(dpy, &xkbs); saved_autorepeat_mode = xkbs.global_auto_repeat; printf("[ar] AutoRepeat state has been saved: %d.\n", saved_autorepeat_mode); /* Turn autorepeat off. */ XKeyboardControl xkbc; xkbc.auto_repeat_mode = AutoRepeatModeOff; XChangeKeyboardControl(dpy, KBAutoRepeatMode, &xkbc); printf("[ar] AutoRepeat state has been turned off.\n"); /* Starting the "active mechanism" by grabbing the kb. */ XGrabKeyboard(dpy, rootwin, False, GrabModeAsync, GrabModeAsync, CurrentTime); } else if (ev.xkey.keycode == hotkey && ev.type == KeyRelease) { printf("[sk] Hotkey has been released, code: %d, name: %s.\n", ev.xkey.keycode, XKeysymToString(XKeycodeToKeysym(dpy, ev.xkey.keycode, 0))); /* Restore saved_autorepeat_mode. */ XKeyboardControl xkbc; xkbc.auto_repeat_mode = saved_autorepeat_mode; XChangeKeyboardControl(dpy, KBAutoRepeatMode, &xkbc); printf("[ar] AutoRepeat has been restored to: %d\n", saved_autorepeat_mode); /* End the "active state" by ungrabbing the keyboard. */ XUngrabKeyboard(dpy, CurrentTime); printf("---------------------------------------------\n"); } else if (ev.type == KeyRelease) { /* Released any other key. */ printf("[ac] Due to bound key release, executed action for" " key code = %d, name: %s\n", ev.xkey.keycode, XKeysymToString(XKeycodeToKeysym(dpy, ev.xkey.keycode, 0))); } } } [Sun Nov 22 16:48:20 -0800 -- alvarezp@octavio:~/temp/xorg-repeat-test] $ ./reptest === TEST A: HOLD HOTKEY, HIT K, RELEASE HOTKEY == [sk] Hotkey has been pressed, code: 133, name: Super_L. [ar] AutoRepeat state has been saved: 1. [ar] AutoRepeat state has been turned off. [ac] Due to bound key release, executed action for key code = 45, name: k [sk] Hotkey has been released, code: 133, name: Super_L. [ar] AutoRepeat has been restored to: 1 --------------------------------------------- == TEST B: HOLD HOTKEY, HOLD K, RELEASE K, RELEASE HOTKEY == [sk] Hotkey has been pressed, code: 133, name: Super_L. [ar] AutoRepeat state has been saved: 1. [ar] AutoRepeat state has been turned off. [ac] Due to bound key release, executed action for key code = 45, name: k [sk] Hotkey has been released, code: 133, name: Super_L. [ar] AutoRepeat has been restored to: 1 --------------------------------------------- == TEST C: HOLD K, LET AUTOREPEAT, HOLD HOTKEY, RELEASE HOTKEY, == RELEASE K == kkkkkkkkkkkkkkkk[sk] Hotkey has been pressed, code: 133, name: Super_L. [ar] AutoRepeat state has been saved: 1. [ar] AutoRepeat state has been turned off. [ == AUTOREPEAT IS OFF NOW. REPETITIONS SHOULDN'T HAVE HAPPENED == ] [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [sk] Hotkey has been released, code: 133, name: Super_L. [ar] AutoRepeat has been restored to: 1 --------------------------------------------- kkkkkkkkkkkkkkk [ == K RELEASED == ] == TEST D: HOLD K, LET AUTOREPEAT, HOLD HOTKEY, RELEASE K, == RELEASE HOTKEY, LET RUN AND HIT K AGAIN TO FIX (UNDER PLAIN == X11) == kkkkkkkkkkkk[sk] Hotkey has been pressed, code: 133, name: Super_L. [ar] AutoRepeat state has been saved: 1. [ar] AutoRepeat state has been turned off. [ == AUTOREPEAT IS OFF NOW. REPETITIONS SHOULDN'T HAVE HAPPENED == ] [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ac] Due to bound key release, executed action for key code = 45, name: k [ == K RELEASED == ] [ == HOTKEY RELEASED == ] [sk] Hotkey has been released, code: 133, name: Super_L. [ar] AutoRepeat has been restored to: 1 --------------------------------------------- [ == TESTS DONE == ] ^C
Any news on this one? Octavio, how does the debug statements I got in this comment look like for you?: https://bugzilla.kernel.org/show_bug.cgi?id=9448#c42 Can we out of this conclude if it is a kernel bug or xorg bug?
Or does this only happen when you actually turn off autorepeat when a key is pressed? Why would you want to do that?
Well, no news. We found a way to work around the bug. > https://bugzilla.kernel.org/show_bug.cgi?id=9448#c42 Well, that doesn't seem to be a similar issue, but it does not seems to be the same one. I remember testing the console with "showkey" back then, and everything came out allright. > Can we out of this conclude if it is a kernel bug or xorg bug? No. > Or does this only happen when you actually turn off autorepeat > when a key is pressed? Why would you want to do that? Yes, because the program uses a "magic" key to enable itself and it must be held down for the program to work. Also, the program doesn't want logical presses and releases, only physical presses and releases.
I would also like to link Daniel Stone's response on the mailing list to this bug report: http://www.mail-archive.com/xorg@lists.freedesktop.org/msg11460.html
Mass closure: This bug has been untouched for more than six years, and is not obviously still valid. Please reopen this bug or file a new report if you continue to experience issues with current releases.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.