## Summary of the Pull Request Fixes #5205, by replacing another use of `MapVirtualKeyW` with `ToUnicodeEx`. The latter just seems to be much more consistent at translating key combinations in general. In this particular case though it fixes the issue, because there's no differentiation in `MapVirtualKeyW` for whether it failed to return a character (`'\0'`) or succeeded in turning `^@` into `'\0'`. `ToUnicodeEx` on the other hand returns the success state separately from the translated character. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #5205 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] Tests added/passed * [ ] Requires documentation to be updated * [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #5205 ## Detailed Description of the Pull Request / Additional comments This PR changes the behavior of the `Ctrl+Alt+Key` handling slightly: ⚠️ `ToUnicodeEx` returns unshifted characters. ⚠️ For instance `Ctrl+Alt+a` is now turned into `^[^a`. Due to how ASCII works this is essentially the same though because `'A' & 0b11111` and `'a' & 0b11111` are the same. ## Validation Steps Performed * Run `showkey -a` * Ensured `Ctrl+Alt+Space` as well as `Ctrl+Alt+Shift+2` are turned into `^[^@` * Ensured other, random `Ctrl+Alt+Key` combination behave identical to the current master
This commit is contained in:
parent
2c603ef953
commit
b009d06bc3
|
@ -39,6 +39,7 @@ systemroot
|
|||
taskkill
|
||||
tasklist
|
||||
tdbuildteamid
|
||||
VCRT
|
||||
vcruntime
|
||||
visualstudio
|
||||
VSTHRD
|
||||
|
@ -47,3 +48,4 @@ wslpath
|
|||
wtl
|
||||
wtt
|
||||
wttlog
|
||||
Xamarin
|
||||
|
|
|
@ -565,25 +565,33 @@ bool TerminalInput::HandleKey(const IInputEvent* const pInEvent)
|
|||
// for the 5 least significant ones to be zeroed out.
|
||||
if (keyEvent.IsAltPressed() && keyEvent.IsCtrlPressed())
|
||||
{
|
||||
auto ch = keyEvent.GetCharData();
|
||||
if (ch == UNICODE_NULL)
|
||||
{
|
||||
// For Alt+Ctrl+Key messages GetCharData() returns 0.
|
||||
// The values of the ASCII characters and virtual key codes
|
||||
// of <Space>, A-Z (as used below) are numerically identical.
|
||||
// -> Get the char from the virtual key.
|
||||
ch = keyEvent.GetVirtualKeyCode();
|
||||
}
|
||||
const auto ch = keyEvent.GetCharData();
|
||||
const auto vkey = keyEvent.GetVirtualKeyCode();
|
||||
|
||||
// For Alt+Ctrl+Key messages GetCharData() usually returns 0.
|
||||
// Luckily the numerical values of the ASCII characters and virtual key codes
|
||||
// of <Space> and A-Z, as used below, are numerically identical.
|
||||
// -> Get the char from the virtual key if it's 0.
|
||||
const auto ctrlAltChar = keyEvent.GetCharData() != 0 ? keyEvent.GetCharData() : keyEvent.GetVirtualKeyCode();
|
||||
|
||||
// Alt+Ctrl acts as a substitute for AltGr on Windows.
|
||||
// For instance using a German keyboard both AltGr+< and Alt+Ctrl+< produce a | (pipe) character.
|
||||
// The below condition primitively ensures that we allow all common Alt+Ctrl combinations
|
||||
// while preserving most of the functionality of Alt+Ctrl as a substitute for AltGr.
|
||||
if (ch == UNICODE_SPACE || (ch > 0x40 && ch <= 0x5A))
|
||||
if (ctrlAltChar == UNICODE_SPACE || (ctrlAltChar > 0x40 && ctrlAltChar <= 0x5A))
|
||||
{
|
||||
// Pressing the control key causes all bits but the 5 least
|
||||
// significant ones to be zeroed out (when using ASCII).
|
||||
ch &= 0b11111;
|
||||
_SendEscapedInputSequence(ch);
|
||||
_SendEscapedInputSequence(ctrlAltChar & 0b11111);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Currently, when we're called with Alt+Ctrl+@, ch will be 0, since Ctrl+@ equals a null byte.
|
||||
// VkKeyScanW(0) in turn returns the vkey for the null character (ASCII @).
|
||||
// -> Use the vkey to determine if Ctrl+@ is being pressed and produce ^[^@.
|
||||
if (ch == UNICODE_NULL && vkey == LOBYTE(VkKeyScanW(0)))
|
||||
{
|
||||
_SendEscapedInputSequence(L'\0');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue