As reported in http://bugs.winehq.org/show_bug.cgi?id=11195 https://bugs.launchpad.net/ubuntu/+source/wine/+bug/178817 and https://bugs.edge.launchpad.net/ubuntu/+source/xorg/+bug/190615 while playing some games, occasionally a key will get stuck and repeat forever, until the X server is restarted. This was originally thought to be a wine bug, but it continues after wine exits and also happens with Frets on Fire (written in Python). In my case, unplugging and replugging the keyboard has no effect.
I'm running Xorg 7.3 from Debian unstable, with nvidia 100.14.19-1, others have reported it under Ubuntu hardy.
More info is available in https://bugs.edge.launchpad.net/ubuntu/+source/xorg-server/+bug/194214 . In particular, it seems that this bug is triggered by simultaneous keyboard and mouse press activity, and is not restricted to OpenGL applications (but is more easily reproducible under Compiz).
An easy way to reproduce is to hold down a key (say page_down) and then scroll madly with the mousewheel in (for example) firefox - trying this one or more times should result in page_down being stuck. Repeating this procedure a couple of times can unstick the key, but input handling is still broken - some modifier (alt, super) keys don't work.
I tried to git-bisect this problem, and ended up with the following git revisions as candidates:
I couldn't do any better, because these all fail to build.
I have tried to reproduce on git head, but the nvidia binary blob doesn't work there, and I find it hard to reproduce without compiz.
A little bit of additional information: The bug is definitely not in xf86-input-kbd (or in the kernel), keys get "stuck" despite the input module properly calling xf86PostKeyboardEvent.
I guess everybody has their own way of reproducing the issue, here's how I do it:
* Press any key
* Wait a moment to trigger auto-repeat (this seems necessary)
* Open a bunch of tabs in firefox.
* Release the key while pages are still being loaded
I can only reproduce the issue under compiz as well, but there are reports on the ubuntu bug-tracker of people running a 2d window managers.
Unfortunately, I couldn't get git master to run either (I always end up with unresolved symbols in the intel driver).
Okay, so the bug starts happening when FreezeThaw is called with frozen = true inside an UNWRAP/COND_WRAP pair. I can't see a problem with that right now, but I guess it means that the server will be thawed inside such a pair as well, which allows the the processInputProc that FreezeThaw set (EnqueueEvent) to escape, resulting in an endless loop of events being bounced around (I can't see where the repeating would come from, and in fact I don't see any repeats when compiling from git). It seems that this patch would solve the issue.
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 167dbec..0352006 100644
@@ -263,7 +263,7 @@ typedef struct
device->unwrapProc = unwrapproc;
#define UNWRAP_PROCESS_INPUT_PROC(device, oldprocs, backupproc) \
- backupproc = device->public.processInputProc; \
+ backupproc = device->public.realInputProc; \
device->public.processInputProc = oldprocs->processInputProc; \
device->public.realInputProc = oldprocs->realInputProc; \
device->unwrapProc = oldprocs->unwrapProc;
It's not well-tested by any means, and considering that I only started looking at the code today (and that this (un)wrapping stuff very complex), it's possible that it might introduce new bugs. In particular, I haven't checked how well it jibes with Xevie. My head hurts already.
Created attachment 15433 [details] [review]
XevIE gets this right, saving and conditionally restoring realInputProc as opposed to processInputProc.
Also, a similar thing is happening in xkbUnwrapProc, not sure if this creates a problem, but the attached patch addresses this issue as well.
Marking this as a duplicate of bug #13511, since they have the same cause. Of course, I didn't realize that the other bug existed until I searched git commits for realInputProc...
*** This bug has been marked as a duplicate of bug 13511 ***
*** Bug 14811 has been marked as a duplicate of this bug. ***