Bug 28326 - Case of autorepetition even with all keys physically up.
Summary: Case of autorepetition even with all keys physically up.
Status: RESOLVED INVALID
Alias: None
Product: xorg
Classification: Unclassified
Component: Input/Keyboard (show other bugs)
Version: unspecified
Hardware: x86 (IA32) Linux (All)
: medium normal
Assignee: Xorg Project Team
QA Contact: Xorg Project Team
URL: http://web.archiveorange.com/archive/...
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-05-30 22:52 UTC by Octavio Alvarez
Modified: 2018-06-12 19:09 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments

Description Octavio Alvarez 2010-05-30 22:52:40 UTC
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
Comment 1 Marius 2011-04-23 18:19:35 UTC
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?
Comment 2 Marius 2011-04-23 18:20:38 UTC
Or does this only happen when you actually turn off autorepeat when a key is pressed? Why would you want to do that?
Comment 3 Octavio Alvarez 2011-04-25 12:29:21 UTC
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.
Comment 4 Octavio Alvarez 2011-04-25 12:30:58 UTC
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
Comment 5 Adam Jackson 2018-06-12 19:09:26 UTC
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.