Repository navigation
fix: Keyboard lost key-up bug - #2436
Merged
Merged
Conversation
maximilien-noal
force-pushed
the
fix/keyboard_focus
branch
from
October 22, 2026 20:00
fffb8eb to
e56f7e7
Compare
kevinferrare
approved these changes
Oct 22, 2026
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.
Description of Changes
PS2Keyboard.cs (the core fix)
Added _pressedKeys — a HashSet tracking which keys the device believes are held.
EnqueueKeyEvent now adds/removes from the set (excluding the non-trackable None, Pause, PrintScreen).
Added ReleaseAllKeys() — emits a deterministic BREAK frame for each held key (sorted by enum order), then clears the set and resets the in-flight typematic repeat.
Wired _pressedKeys.Clear() + repeat reset into the buffer-overflow path in EnqueueScanCodeFrame, so a dropped key-up can't latch.
InputEventQueue.cs — added KeyboardDevice property and ReleaseAllKeys(), marshalled onto the emulator thread.
EmulatorMcpServices.cs — on pause (PauseHandler.Pausing), calls inputEventHub.ReleaseAllKeys().
MainWindowViewModel.cs / MainWindow.axaml.cs / Spice86DependencyInjection.cs — on window deactivation, calls inputEventHub.ReleaseAllKeys().
Rationale behind Changes
I fixed the lost-key-up bug by implementing a device-side release-all mechanism in the PS/2 keyboard, wired it to all three loss routes (window deactivation, pause, buffer overflow), and added tests. All new tests pass;
fixes #2407
Suggested Testing Steps
New file tests/Spice86.Tests/Emulator/Devices/Keyboard/PS2KeyboardReleaseAllKeysTests.cs (6 tests, all passing). The key engineering part was a controllable IEmulatedClock plus a drain helper that mimics what the guest does in INT9 (read 0x64, then 0x60), since the 8042's 0.3ms inter-byte delay and _waitingBytesFromKbd gating must be driven to observe the emitted scancodes.