Inject synthetic keyup events to recover from macOS swallowing them while a Meta key is held#7
Open
lxpollitt wants to merge 1 commit into
Open
Conversation
…hile a Meta key is held macOS suppresses keyUp events for non-modifier keys whose keyUp would occur while a Meta (CMD) key is held - an OS-level behaviour inherited by Chrome, Safari and Firefox. GwtKeyboardMatrix's UI-thread constructor now installs a DOM-level keydown/keyup listener (capture phase, so it runs before libGDX's own document-level bubble-phase listener). The listener tracks which non- Meta keys have unreleased keydowns and, on Meta release, dispatches a synthetic keyup event for each. The synthetic events flow through libGDX's normal keyup handler and clear its internal pressedKeys[] state.
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR addresses macOS swallowing keyup events while a Meta (CMD) key is held.
Problem
On macOS, the OS swallows keyup events for non-modifier keys whose keyup would land while a Meta (CMD) key is held. This is a long-standing macOS behaviour is inherited by Safari, Chrome, and Firefox. This results in the key becoming "stuck" down, until it is next pressed and released. So for example, if the user types CMD-X into the Oric BASIC command line, then X becomes stuck held down, generating auto-repeat X characters indefinitely until the user next presses and releases X. (And because of Oric's keyboard scanning behaviour, pressing any other key does not cancel the auto-repeat / stuck key. You have to press the X itself.)
Fix
Added a DOM-level keydown/keyup listener via JSNI to
GwtKeyboardMatrix. It tracks which non-Meta keycodes have received a keydown but not yet a keyup. On the transition from CMD-held → CMD-released, it dispatches synthetic DOM keyup events for those tracked keys. The synthetic events flow through libGDX's normal listener path (it doesn't know they're synthetic) and clear the stuckpressedKeys[]entries.Scope
GLFW_KEY_LEFT/RIGHT_SUPERtoKeys.SYM, so I think it doesn't have the samepressedKeys[]gate problem. But note I've not been able to test this first hand because the desktop version doesn't currently run for me on my Mac. (I may investigate this problem another time.)useCapture=trueso it runs before libGDX's own listener (which usesuseCapture=false).Testing
I've confirmed the fix behaves as expected for me using both Safari and Chrome on macOS. I haven't been able to verity Windows and Linux behaves as expected as I don't have easy access to a Windows or Linux desktops. I think the code is pretty safe but it would be good to verify on at least one other OS to be sure before merging.