Closed matomatical closed 5 months ago
Oh yeah, a program that can reproduce this issue for me is as follows:
import os
# init
import illwill
proc exit_proc() {.noconv.} =
illwillDeinit()
showCursor()
quit(0)
setControlCHook(exit_proc)
illwillInit(fullscreen=false)
hideCursor()
# mwe
while true:
let key = getKey()
echo key
sleep(1000)
# clean up
exit_proc()
Instructions: This program polls getKey once every second. Press two keys in a single interval. The output is Key.None, indicating the key presses have been lost.
Great analysis! I haven't worked on this library for the last three years, so probably right now you have a better understanding of how it works than myself :) PRs are always welcome, right now it's not a priority for me to fix this myself.
I've always used it with very short poll intervals, around 20ms, so I never encountered this issue. So that's a viable workaround, as you don't really want to poll only every 1s in a real world app.
In principle I agree, keypresses shouldn't be lost, ideally.
fixed here https://github.com/johnnovak/illwill/pull/45
I think there might be a bug in the
getKey
implementation for OS X (it appears the same implementation applies for linux).If two (or more) keys are pressed between
getKey
calls, for example pressing "A" and then "B" and then callinggetKey
, thenKey.None
is returned. My expectation was that the first call togetKey
would returnKey.A
and the next subsequent call togetKey
would returnKey.B
. (At the very least, I expected the first keypress not to be lost. Ideally, for my use case, neither keypress would be lost. This latter behaviour also seemed to be suggested by the documentation.)Taking a look at the source, it appears that the approach used on linux and OS X is to (1) read all available key characters into a buffer, and then (2) attempt to parse the whole contents of the buffer with the parseKey. If I'm not mistaken, this approach causes the issue, because in the above situation both keycodes would be read into the buffer and then this would not be parseable if the parseKey function expects to interpret the buffer as a single keycode (this checks out, based on my surface-level understanding of the parseKey function, which appears to apply a linear search for single matching key sequences in case there would be multiple keycodes present in the buffer). It seems like an approach more like the one used for windows (source)---wherein the input characters are read on-demand so that only a single keycode is ever pulled into the program---could be one way to solve the problem. However, I'm personally unfamiliar with keyboard input processing on any OS.
Note: My actual use case involves arrow keys. The same issue applies. So, I expect the individual keycode length is not the issue.