Add support for Ctrl+# keys (#4938)
## Summary of the Pull Request Fixes the <kbd>Ctrl+Num</kbd> keys in both conhost and the Terminal. These keys are supposed to be mapped to specific characters according to [this doc](https://vt100.net/docs/vt220-rm/table3-5.html). Now we actually handle them correctly. ## PR Checklist * [x] Closes #3507 * [x] I work here * [x] Tests added/passed * [n/a] Requires documentation to be updated ## Validation Steps Performed * Ran test * tested in `gnome-terminal` with `showkeys -a` * tested in conhost with `showkeys -a` * tested in Windows Terminal with `showkeys -a`
This commit is contained in:
parent
d50409b901
commit
f7d106d3f3
|
@ -45,6 +45,7 @@ public:
|
|||
TEST_METHOD(TerminalInputModifierKeyTests);
|
||||
TEST_METHOD(TerminalInputNullKeyTests);
|
||||
TEST_METHOD(DifferentModifiersTest);
|
||||
TEST_METHOD(CtrlNumTest);
|
||||
|
||||
wchar_t GetModifierChar(const bool fShift, const bool fAlt, const bool fCtrl)
|
||||
{
|
||||
|
@ -511,6 +512,13 @@ void InputTest::TerminalInputModifierKeyTests()
|
|||
s_pwsInputBuffer[1] = wchShifted;
|
||||
fExpectedKeyHandled = true;
|
||||
}
|
||||
else if (ControlPressed(uiKeystate) && (vkey >= '1' && vkey <= '9'))
|
||||
{
|
||||
// The C-# keys get translated into very specific control
|
||||
// characters that don't play nicely with this test. These keys
|
||||
// are tested in the CtrlNumTest Test instead.
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
fExpectedKeyHandled = false;
|
||||
|
@ -714,3 +722,49 @@ void InputTest::DifferentModifiersTest()
|
|||
// LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED is skipped because that's AltGr
|
||||
TestKey(pInput, SHIFT_PRESSED | RIGHT_CTRL_PRESSED | RIGHT_ALT_PRESSED, vkey, L'?');
|
||||
}
|
||||
|
||||
void InputTest::CtrlNumTest()
|
||||
{
|
||||
Log::Comment(L"Starting test...");
|
||||
|
||||
const TerminalInput* const pInput = new TerminalInput(s_TerminalInputTestCallback);
|
||||
|
||||
Log::Comment(L"Sending the various Ctrl+Num keys.");
|
||||
|
||||
unsigned int uiKeystate = LEFT_CTRL_PRESSED;
|
||||
BYTE vkey = static_cast<WORD>('1');
|
||||
s_pwszInputExpected = L"1";
|
||||
TestKey(pInput, uiKeystate, vkey);
|
||||
|
||||
Log::Comment(NoThrowString().Format(
|
||||
L"Skipping Ctrl+2, since that's supposed to send NUL, and doesn't play "
|
||||
L"nicely with this test. Ctrl+2 is covered by other tests in this class."));
|
||||
|
||||
vkey = static_cast<WORD>('3');
|
||||
s_pwszInputExpected = L"\x1b";
|
||||
TestKey(pInput, uiKeystate, vkey);
|
||||
|
||||
vkey = static_cast<WORD>('4');
|
||||
s_pwszInputExpected = L"\x1c";
|
||||
TestKey(pInput, uiKeystate, vkey);
|
||||
|
||||
vkey = static_cast<WORD>('5');
|
||||
s_pwszInputExpected = L"\x1d";
|
||||
TestKey(pInput, uiKeystate, vkey);
|
||||
|
||||
vkey = static_cast<WORD>('6');
|
||||
s_pwszInputExpected = L"\x1e";
|
||||
TestKey(pInput, uiKeystate, vkey);
|
||||
|
||||
vkey = static_cast<WORD>('7');
|
||||
s_pwszInputExpected = L"\x1f";
|
||||
TestKey(pInput, uiKeystate, vkey);
|
||||
|
||||
vkey = static_cast<WORD>('8');
|
||||
s_pwszInputExpected = L"\x7f";
|
||||
TestKey(pInput, uiKeystate, vkey);
|
||||
|
||||
vkey = static_cast<WORD>('9');
|
||||
s_pwszInputExpected = L"9";
|
||||
TestKey(pInput, uiKeystate, vkey);
|
||||
}
|
||||
|
|
|
@ -185,13 +185,31 @@ static constexpr std::array<TermKeyMap, 22> s_modifierKeyMapping{
|
|||
// These sequences are not later updated to encode the modifier state in the
|
||||
// sequence itself, they are just weird exceptional cases to the general
|
||||
// rules above.
|
||||
static constexpr std::array<TermKeyMap, 6> s_simpleModifiedKeyMapping{
|
||||
static constexpr std::array<TermKeyMap, 14> s_simpleModifiedKeyMapping{
|
||||
TermKeyMap{ VK_BACK, CTRL_PRESSED, L"\x8" },
|
||||
TermKeyMap{ VK_BACK, ALT_PRESSED, L"\x1b\x7f" },
|
||||
TermKeyMap{ VK_BACK, CTRL_PRESSED | ALT_PRESSED, L"\x1b\x8" },
|
||||
TermKeyMap{ VK_TAB, CTRL_PRESSED, L"\t" },
|
||||
TermKeyMap{ VK_TAB, SHIFT_PRESSED, L"\x1b[Z" },
|
||||
TermKeyMap{ VK_DIVIDE, CTRL_PRESSED, L"\x1F" },
|
||||
|
||||
// GH#3507 - We should also be encoding Ctrl+# according to the following table:
|
||||
// https://vt100.net/docs/vt220-rm/table3-5.html
|
||||
// * 1 and 9 do not send any special characters, but they _should_ send
|
||||
// through the character unmodified.
|
||||
// * 0 doesn't seem to send even an unmodified '0' through.
|
||||
// * Ctrl+2 is already special-cased below in `HandleKey`, so it's not
|
||||
// included here.
|
||||
TermKeyMap{ static_cast<WORD>('1'), CTRL_PRESSED, L"1" },
|
||||
// TermKeyMap{ static_cast<WORD>('2'), CTRL_PRESSED, L"\x00" },
|
||||
TermKeyMap{ static_cast<WORD>('3'), CTRL_PRESSED, L"\x1B" },
|
||||
TermKeyMap{ static_cast<WORD>('4'), CTRL_PRESSED, L"\x1C" },
|
||||
TermKeyMap{ static_cast<WORD>('5'), CTRL_PRESSED, L"\x1D" },
|
||||
TermKeyMap{ static_cast<WORD>('6'), CTRL_PRESSED, L"\x1E" },
|
||||
TermKeyMap{ static_cast<WORD>('7'), CTRL_PRESSED, L"\x1F" },
|
||||
TermKeyMap{ static_cast<WORD>('8'), CTRL_PRESSED, L"\x7F" },
|
||||
TermKeyMap{ static_cast<WORD>('9'), CTRL_PRESSED, L"9" },
|
||||
|
||||
// These two are not implemented here, because they are system keys.
|
||||
// TermKeyMap{ VK_TAB, ALT_PRESSED, L""}, This is the Windows system shortcut for switching windows.
|
||||
// TermKeyMap{ VK_ESCAPE, ALT_PRESSED, L""}, This is another Windows system shortcut for switching windows.
|
||||
|
|
Loading…
Reference in a new issue