Created
January 5, 2017 05:05
-
-
Save torbiak/3ef0082a1aba63169912913a37896a46 to your computer and use it in GitHub Desktop.
Reproduce X11 bug where the second KeyRelease event is missing if two grabbed keys are released in quick succession.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// grabtest tries to reproduce an X11 bug where, when two keys grabbed using | |
// XGrabKey are held down and then quickly released, the second KeyRelease | |
// event never makes it to the event queue. | |
// | |
// make LDFLAGS=-lX11\ -lXtst grabtest | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <assert.h> | |
#include <X11/Xlib.h> | |
#include <X11/keysym.h> | |
#include <X11/extensions/XTest.h> | |
#define LEN(X) (sizeof(X) / sizeof(X[0])) | |
#define PRESS 1 | |
#define RELEASE 0 | |
Display *dpy; | |
Window root; | |
int screen; | |
void | |
read_n_key_events(int n) | |
{ | |
for (int i = 0; i < n; i++) { | |
XEvent ev; | |
XMaskEvent(dpy, KeyPressMask|KeyReleaseMask, &ev); | |
KeySym keysym = XLookupKeysym(&ev.xkey, 0); | |
int ispress = ev.type == KeyPress; | |
printf("%s %s\n", ispress ? "press" : "release", XKeysymToString(keysym)); | |
} | |
} | |
int | |
main() | |
{ | |
dpy = XOpenDisplay(NULL); | |
assert(dpy); | |
root = DefaultRootWindow(dpy); | |
screen = DefaultScreen(dpy); | |
XSelectInput(dpy, root, KeyPressMask|KeyReleaseMask); | |
KeySym keysyms[] = {XK_d, XK_f}; | |
// Grab keys. | |
unsigned modifiers = 0; | |
for (int i = 0; i < LEN(keysyms); i++) { | |
KeyCode keycode = XKeysymToKeycode(dpy, keysyms[i]); | |
int ok = XGrabKey(dpy, keycode, modifiers, root, True, GrabModeAsync, GrabModeAsync); | |
assert(ok); | |
XKeyboardControl ctrl = {.key=keycode, .auto_repeat_mode=AutoRepeatModeOff}; | |
XChangeKeyboardControl(dpy, KBKey|KBAutoRepeatMode, &ctrl); | |
} | |
// Hold keys d and f, then quickly release them. | |
KeyCode d = XKeysymToKeycode(dpy, XK_d); | |
KeyCode f = XKeysymToKeycode(dpy, XK_f); | |
XTestFakeKeyEvent(dpy, d, PRESS, CurrentTime); | |
XTestFakeKeyEvent(dpy, f, PRESS, CurrentTime); | |
XTestFakeKeyEvent(dpy, d, RELEASE, CurrentTime); | |
XFlush(dpy); | |
read_n_key_events(3); | |
XTestFakeKeyEvent(dpy, f, RELEASE, CurrentTime); | |
XFlush(dpy); | |
read_n_key_events(1); | |
// Clean up. | |
for (int i = 0; i < LEN(keysyms); i++) { | |
KeyCode keycode = XKeysymToKeycode(dpy, keysyms[i]); | |
XKeyboardControl ctrl = {.key=keycode, .auto_repeat_mode=AutoRepeatModeDefault}; | |
XChangeKeyboardControl(dpy, KBKey|KBAutoRepeatMode, &ctrl); | |
XUngrabKey(dpy, keycode, modifiers, root); | |
} | |
XFlush(dpy); | |
} |
No, sadly. I think this GNOME mailing list post is also referring to the same issue, and that's the only other reference to it that I've seen. I looked through my notes for torbiak/ptrkeys but don't see much else about it except for this commit message. I guess I didn't file a bug or anything.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Did you ever find a solution to this issue? im currently having this with an app im developing, and i cannot find a solution