[KBM] Fix modifier key remapped to non-modifier delivering WM_SYSKEYDOWN#47192
[KBM] Fix modifier key remapped to non-modifier delivering WM_SYSKEYDOWN#47192oMatheusmol wants to merge 1 commit into
Conversation
@check-spelling-bot Report🔴 Please reviewSee the 📂 files view, the 📜action log, 👼 SARIF report, or 📝 job summary for details.Unrecognized words (1)DEFAULTTONEAREST These words are not needed and should be removeddefaulttonearestTo accept these unrecognized words as correct and remove the previously acknowledged and now absent words, you could run the following commands... in a clone of the git@github.com:oMatheusmol/PowerToys.git repository curl -s -S -L 'https://raw.githubusercontent.com/check-spelling/check-spelling/cfb6f7e75bbfc89c71eaa30366d0c166f1bd9c8c/apply.pl' |
perl - 'https://github.com/microsoft/PowerToys/actions/runs/24868842762/attempts/1' &&
git commit -m 'Update check-spelling metadata'If the flagged items are 🤯 false positivesIf items relate to a ...
|
|
@microsoft-github-policy-service agree |
There was a problem hiding this comment.
Pull request overview
Fixes an issue in Keyboard Manager where remapping a modifier key (Ctrl/Alt/Shift) to a non-modifier can cause the injected target key to be interpreted with an unintended modifier context (e.g., Alt causing WM_SYSKEYDOWN semantics). The change aligns modifier→non-modifier remaps with the existing “reset modifier state via suppress-flag key-up” approach already used for Caps Lock-related cases.
Changes:
- Add a suppress-flag key-up injection for the source modifier key before injecting the remapped target key when modifier → non-modifier remaps occur.
- Add a unit test to validate that the suppress-flag injection happens for a representative modifier→non-modifier remap (LAlt → Backspace).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardEventHandlers.cpp | Injects a suppress-flag key-up for the remapped modifier on keydown to clear modifier state before sending the target key. |
| src/modules/keyboardmanager/KeyboardManagerEngineTest/SingleKeyRemappingTests.cpp | Adds a unit test asserting exactly one suppress-flag event is issued for a modifier→non-modifier remap. |
|
Hi @MuyuanMS , just following up on this PR. Could you please take a look when you have time? Let me know if any changes are needed. Thanks! |
|
Hi @niels9001 , Just following up on this PR since it has been open for a little over a month. The issue is still reproducible and the proposed fix is ready on my side. Could you please let me know if there's anything else needed from me, or if any changes are required before review? Thanks! |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
MuyuanMS
left a comment
There was a problem hiding this comment.
Interestingly I was not able to reproduce the original bug - I remapped left alt to backspace and notepad shows WM_KEYDOWN even without the fix.
My guess is on issue is only reproducible on windows 10, and the fix itself has low risks and looks good to me
Summary of the Pull Request
When a modifier key (Ctrl/Alt/Shift) is remapped to a non-modifier key using
Keyboard Manager, the injected key event is delivered to applications as
WM_SYSKEYDOWN instead of WM_KEYDOWN. This causes unexpected behavior — for
example, remapping Left Alt to Backspace results in whole words being deleted
instead of single characters, because applications interpret WM_SYSKEYDOWN +
VK_BACK as Alt+Backspace.
The fix resets the modifier state with a suppress-flag key-up event before
injecting the target key, consistent with the existing approach used for the
Caps Lock remapping scenario.
PR Checklist
Detailed Description of the Pull Request / Additional comments
The root cause is that SendInput is called inside the low-level keyboard hook
callback before the original modifier event is suppressed. At that point the
modifier state is still active, so the OS delivers the injected key as
WM_SYSKEYDOWN (system key with Alt context) rather than WM_KEYDOWN.
This is the same mechanism that was already fixed for the Ctrl/Alt/Shift ↔
Caps Lock case. This PR extends the fix to cover modifier → non-modifier remaps.
Validation Steps Performed