The ring held a keycode and dropped the rest of the event, so a line editor built on akgl_controller_poll_key() could not reach a single shifted character: no double quote, no colon, no parenthesis, and no lower case. The modifier state was discarded two layers below the caller, and polling SDL_GetModState() at read time cannot recover it -- the key is long released by then, which is the point of a ring. akgl_Keystroke carries the keycode, the modifiers and the UTF-8 text SDL composed, and akgl_controller_poll_keystroke() hands back all three. akgl_controller_poll_key() is unchanged for its callers: a game asking whether the up arrow was pressed already gets what it wants. The text comes from SDL_EVENT_TEXT_INPUT, which is the only correct way to get a character out of SDL, and is attached to the press still waiting for it -- tracked with a flag rather than by "whatever entry is newest", so a press dropped by a full buffer cannot hand its text to an older key. Text with no press behind it (an IME commit, a dead key) is buffered on its own with keycode 0, and the keycode-only poller discards those on the way past. Oversized text is cut on a code point boundary, and a sequence the string ends in the middle of is dropped rather than read past its terminator. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
17 KiB
17 KiB