fix(input): Prevent modified key releases from firing plain hotkeys - #3233
CryoTheRenegade wants to merge 7 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 | Captures modifier state per buffered event, tracks matching press state, and synthesizes held-modifier releases during keyboard reset. |
| Core/GameEngine/Source/GameClient/MessageStream/HotKey.cpp | Prevents plain hotkey execution when either the release or its matching press carried modifier state. |
| Core/GameEngine/Source/GameClient/MessageStream/MetaEvent.cpp | Adopts the shared KeyState type without changing MetaEvent behavior. |
| Core/GameEngine/Include/GameClient/Keyboard.h | Adds persistent per-key press-state storage and updates keyboard state APIs to use KeyState. |
| Generals/Code/GameEngine/Include/GameClient/KeyDefs.h | Defines the shared KeyState type and combined modifier mask for the Generals target. |
| GeneralsMD/Code/GameEngine/Include/GameClient/KeyDefs.h | Defines the shared KeyState type and combined modifier mask for the Zero Hour target. |
Sequence Diagram
sequenceDiagram
participant OS as Keyboard device
participant K as Keyboard
participant MS as MessageStream
participant ME as MetaEventTranslator
participant HK as HotKeyTranslator
OS->>K: Buffered key event
K->>K: Snapshot current modifiers
alt Key down
K->>K: Save press-time KeyState
K->>MS: RAW_KEY_DOWN(key, state)
else Key up
K->>MS: RAW_KEY_UP(key, state, pressState)
K->>K: Clear saved press state
end
MS->>ME: Translate raw key event
MS->>HK: Translate RAW_KEY_UP
HK->>HK: Suppress if release or press was modified
Reviews (7): Last reviewed commit: "Simplify keyboard press tracking and use..." | 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 |
| @@ -74,33 +73,15 @@ GameMessageDisposition HotKeyTranslator::translateGameMessage(const GameMessage | |||
|
|
|||
| if ( t == GameMessage::MSG_RAW_KEY_UP) | |||
There was a problem hiding this comment.
Would MSG_RAW_KEY_DOWN perhaps be an option for hotkeys? All the MetaEvents are key down events. Or is there a good reason why hotkey needs to be posted on down?
There was a problem hiding this comment.
Key-down could work. I found no comment explaining why hotkeys use key-up. I kept the current timing for now.
There was a problem hiding this comment.
I suggest test MSG_RAW_KEY_DOWN. It would be the simpler option and get rid of the new stuff you added to accomodate this event. Players will also be happier if their key presses register faster.
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.