glfw: glfwSetKeyCallback triggers multiple key events after holding a key down
I just implemented camera movements and noticed that the camera moved forward for a bit after releasing W. After some investigation I noticed that glfwSetKeyCallback triggered another shorter sequence of GLFW_PRESS, GLFW_REPEAT and GLFW_RELEASE after I’ve release the key. The longer I hold the key the longer the second sequence is.
To make sure it wasn’t something in my code I downloaded the getting started example and added a simple printf("%i ", action);
The output looked like this:
1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 1 2 2 2 2 0
Where the first 0 is when I actually released the key and the rest of the sequence are phantom key events.
I’m running GLFW 3.1.2 using the offical package on ArchLinux x64
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 3
- Comments: 18 (4 by maintainers)
Calling glfwPollEvents() at 2fps (aka add a 500ms sleep to the main loop) seems to trigger it reliably on X.Org X Server 1.18.4, running on Ubuntu 16.10 with GLFW 3.2.0.
The solution is literally starring us in the face.
Sure enough, if you disable
window->x11.icby disablingimglobally (if (XSupportsLocale())->if (XSupportsLocale() && 0)inx11_init.c), then there are no phantom keypresses. You can also see that each phantom keypress has an old timestamp exactly identical to that of a keypress that was already received and processed, validating that HACK comment.My guess is ibus doesn’t send the keypress until the previous event is actually removed from the queue/forwarded/whatever, so it takes N processing loops to clear N keypress repeats. When FPS > key repeat rate, there is no issue, but otherwise they pile up and it takes many event loops to clear the backlog.
The solution is rather simple. Rather than filtering based on the last received timestamp, instead discard any events older by more than say 10ms than the most recent key event received, to account for noisy timestamps. The current code assumes the duplicate keypresses are adjacent in the event stream, which is false at low FPS. I’ll make a PR soonish.
I have the same problem with glfwSetKeyCallback function. Used GLFW version: 3.1.2 under Ubuntu 16.04, but problem exists on Debian too. Code with bug: http://pastebin.com/PBTjhN6y Example bugged output (W was pressed ~3 secs): http://pastebin.com/jEqYAqwi Propably this can be solved by using some state machine, but is quite annoying when using controls in camera in OpenGL, and i don’t want to write bug-specific code.
Thanks in advance 😃
I’m not sure it matters at this point, but I can confirm that this is a bug on Ubuntu 16.04 and the fix did work for me, using 3.2.1