fix(input): Prevent modified key releases from firing plain hotkeys - #3233
fix(input): Prevent modified key releases from firing plain hotkeys#3233CryoTheRenegade wants to merge 4 commits into
Conversation
… out of order Signed-off-by: Jacob Ledbetter <jledbetter460@gmail.com>
PR Summary by QodoPrevent stuck modifier combos on out-of-order key releases
AI Description
Diagram
High-Level Assessment
Files changed (6)
|
Code Review by Qodo🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)
Great, no issues found!Qodo reviewed your code and found no material issues that require reviewTip of the day💡 Did you know, you can reply 'qodo' on any finding to push back, ask questions, or dig deeper |
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Source/GameClient/Input/Keyboard.cpp | Tracks modifier provenance per key and synthesizes modifier releases during keyboard resets. |
| Core/GameEngine/Source/GameClient/MessageStream/HotKey.cpp | Prevents key releases associated with modifier combinations from executing plain GUI hotkeys. |
| Core/GameEngine/Include/GameClient/Keyboard.h | Adds per-key modifier provenance storage and declares generalized modifier-release handling. |
| Generals/Code/GameEngine/Include/GameClient/KeyDefs.h | Adds the modifier-on-down event-state flag for the Generals variant. |
| GeneralsMD/Code/GameEngine/Include/GameClient/KeyDefs.h | Adds the matching modifier-on-down event-state flag for the Zero Hour variant. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
Down[Key-down event] --> Capture[Capture current modifier state]
Capture --> Store[Store modifier-on-down by key]
Store --> Repeat[Apply provenance to autorepeat]
Store --> Up[Matching key-up event]
Up --> Carry[Attach stored modifier provenance]
Carry --> Hotkey{Modifier-associated release?}
Hotkey -- Yes --> Ignore[Skip plain GUI hotkey]
Hotkey -- No --> Execute[Evaluate plain GUI hotkey]
Focus[Focus loss or device reset] --> Synthetic[Synthesize held modifier key-ups]
Synthetic --> Modes[End modifier-controlled modes]
Reviews (4): Last reviewed commit: "Fix modifier state tracking for hotkey r..." | Re-trigger Greptile
HotKey.h referenced KeyDefType/KEY_COUNT without the key header, and MetaEvent.cpp called a reset helper that was never declared. Co-authored-by: Cursor <cursoragent@cursor.com>
xezon
left a comment
There was a problem hiding this comment.
I assume this was entirely generated by LLM? It looks like slop the way the new logic is laid out. It is incomprehensible and unmaintainable. It needs to be unsloppified.
Keep the GUI-hotkey and focus-loss behavior, but store the modifier-down flag on HotKeyTranslator itself and reuse the existing alt-tab key-up path for CTRL and SHIFT. Co-authored-by: Cursor <cursoragent@cursor.com>
|
How do we know the new generated revision is no slop? |
|
Fair criticism. I used LLM assistance on the first pass, and I should have reviewed and simplified the result before asking you to review it. I own that. I’ve since rewritten the fix. The hotkey translator is stateless now. Modifier press state lives in |
|
I tried to understand this change but I was unable to. It is lacking context. What was the issue and how was it reproduced, how was it fixed and why is it fixed the way it was fixed. |
|
I've reworded the PR description with a simple example and an explanation of the cause, the fix, and why the state is stored in |
Thanks to DrGoldFish, who reported this issue and tested the fix.
The bug can happen in this order using Legi's keybinds:
The game can treat the last step as a normal F key press and run the F command. It should remember that F was pressed with Ctrl.
There is also a focus problem. If Ctrl or Shift is released while the game is not focused, the game may miss the release. This can leave force-attack or selection mode active.
The keyboard code reads several events at once. It previously gave every event the modifier state from the end of that group. This could give an event the wrong Ctrl, Shift, or Alt state.
The keyboard code now saves the modifier state when each event is handled. It remembers which modifier was held when a key was pressed. It passes that information to the matching key release.
HotKeyTranslatorthen knows that the release is part of a modified key press and does not run the normal hotkey.This state is stored in
Keyboardbecause another message handler may remove the key-down event beforeHotKeyTranslatorreceives it.The reset code now sends key-up events for Ctrl, Shift, and Alt. The existing
MetaEventcode is unchanged.