Skip to content

Commit

Permalink
wpf: only dismiss selection for real chars, not modifiers (#5388)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
DHowett committed Apr 17, 2020
1 parent 38e7cb0 commit 5740e19
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
40 changes: 33 additions & 7 deletions src/cascadia/PublicTerminalCore/HwndTerminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,23 +555,49 @@ catch (...)
return false;
}

void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode)
void HwndTerminal::_SendKeyEvent(WORD vkey, WORD scanCode) noexcept
try
{
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
const auto flags = getControlKeyState();
publicTerminal->_terminal->SendKeyEvent(vkey, scanCode, flags);
_terminal->SendKeyEvent(vkey, scanCode, flags);
}
CATCH_LOG();

void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD scanCode)
void HwndTerminal::_SendCharEvent(wchar_t ch, WORD scanCode) noexcept
try
{
if (ch == '\t')
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 publicTerminal = static_cast<const HwndTerminal*>(terminal);
const auto flags = getControlKeyState();
publicTerminal->_terminal->SendCharEvent(ch, scanCode, flags);
_terminal->SendCharEvent(ch, scanCode, flags);
}
CATCH_LOG();

void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode)
{
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
publicTerminal->_SendKeyEvent(vkey, scanCode);
}

void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD scanCode)
{
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
publicTerminal->_SendCharEvent(ch, scanCode);
}

void _stdcall DestroyTerminal(void* terminal)
Expand Down
3 changes: 3 additions & 0 deletions src/cascadia/PublicTerminalCore/HwndTerminal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ struct HwndTerminal : ::Microsoft::Console::Types::IControlAccessibilityInfo
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;
Expand Down
1 change: 0 additions & 1 deletion src/cascadia/WpfTerminalControl/TerminalContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@ private IntPtr TerminalContainer_MessageHook(IntPtr hwnd, int msg, IntPtr wParam
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;
Expand Down

0 comments on commit 5740e19

Please sign in to comment.