Key continue repeating if setting global autorepeat off while the key was already repeating.
Octavio Alvarez
alvarezp at alvarezp.ods.org
Sun Nov 22 20:27:47 PST 2009
Hi.
If I turn global autorepeat off while a key is already being repeated,
the key doesn't stop repeating. It continues on and on.
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'm running X.org version 1.6.5 under Debian Sid. I think (but not sure)
I'm using the evdev driver.
A friend tried test D for me under 1.7.1.901 and happens too.
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.
This problem happens also under Ubuntu Jaunty box (X 7.4, 1.6.0) but
I remember previous distros not failing. Say Ubuntu Hardy or Gutsy and
before.
Is it a bug, or am I missing something? Thanks.
/*
* 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 at 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
More information about the xorg
mailing list