wpf: only dismiss selection for real chars, not modifiers (#5388)

Selection would act up when you were using shift to ignore VT mouse
mode: we would get hundreds of WM_KEYDOWN for VK_SHIFT and dismiss the
selection every time.

I took the opportunity to move the actual responsibility for key event
dispatch into HwndTerminal. In the future, I'd like to make more of the
TerminalXxx calls just call impl methods on HwndTerminal.
This commit is contained in:
Dustin L. Howett (MSFT) 2020-04-17 11:28:56 -07:00 committed by GitHub
parent 38e7cb0742
commit 5740e197c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 12 deletions

View file

@ -555,23 +555,49 @@ catch (...)
return false;
}
void HwndTerminal::_SendKeyEvent(WORD vkey, WORD scanCode) noexcept
try
{
const auto flags = getControlKeyState();
_terminal->SendKeyEvent(vkey, scanCode, flags);
}
CATCH_LOG();
void HwndTerminal::_SendCharEvent(wchar_t ch, WORD scanCode) noexcept
try
{
if (_terminal->IsSelectionActive())
{
_terminal->ClearSelection();
if (ch == UNICODE_ESC)
{
// ESC should clear any selection before it triggers input.
// Other characters pass through.
return;
}
}
if (ch == UNICODE_TAB)
{
// TAB was handled as a keydown event (cf. Terminal::SendKeyEvent)
return;
}
const auto flags = getControlKeyState();
_terminal->SendCharEvent(ch, scanCode, flags);
}
CATCH_LOG();
void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode)
{
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
const auto flags = getControlKeyState();
publicTerminal->_terminal->SendKeyEvent(vkey, scanCode, flags);
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
publicTerminal->_SendKeyEvent(vkey, scanCode);
}
void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD scanCode)
{
if (ch == '\t')
{
return;
}
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
const auto flags = getControlKeyState();
publicTerminal->_terminal->SendCharEvent(ch, scanCode, flags);
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
publicTerminal->_SendCharEvent(ch, scanCode);
}
void _stdcall DestroyTerminal(void* terminal)

View file

@ -115,6 +115,9 @@ private:
bool _CanSendVTMouseInput() const noexcept;
bool _SendMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam) noexcept;
void _SendKeyEvent(WORD vkey, WORD scanCode) noexcept;
void _SendCharEvent(wchar_t ch, WORD scanCode) noexcept;
// Inherited via IControlAccessibilityInfo
COORD GetFontSize() const override;
RECT GetBounds() const noexcept override;

View file

@ -235,7 +235,6 @@ namespace Microsoft.Terminal.Wpf
case NativeMethods.WindowMessage.WM_KEYDOWN:
// WM_KEYDOWN lParam layout documentation: https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-keydown
NativeMethods.TerminalSetCursorVisible(this.terminal, true);
NativeMethods.TerminalClearSelection(this.terminal);
NativeMethods.TerminalSendKeyEvent(this.terminal, (ushort)wParam, (ushort)((uint)lParam >> 16));
this.blinkTimer?.Start();
break;