terminal/src/cascadia/TerminalCore/ITerminalInput.hpp
Leonard Hecker a9c9714295
Delegate all character input to the character event handler (#4192)
My basic idea was that `WM_CHAR` is just the better `WM_KEYDOWN`.
The latter fails to properly support common dead key sequences like in
#3516.

As such I added some logic to `Terminal::SendKeyEvent` to make it return
false if the pressed key represents a printable character.
This causes us to receive a character event with a (hopefully) correctly
composed code unit, which then gets sent to `Terminal::SendCharEvent`.
`Terminal::SendCharEvent` in turn had to be modified to support
potentially pressed modifier keys, since `Terminal::SendKeyEvent` isn't
doing that for us anymore.
Lastly `TerminalInput` had to be modified heavily to support character
events with modifier key states. In order to do so I merged its
`HandleKey` and `HandleChar` methods into a single one, that now handles
both cases.
Since key events will now contain character data and character events
key codes the decision logic in `TerminalInput::HandleKey` had to be
rewritten.

## PR Checklist
* [x] CLA signed
* [x] Tests added/passed
* [x] I've discussed this with core contributors already.

## Validation Steps Performed

* See #3516.
* I don't have any keyboard that generates surrogate characters. Due to
  this I modified `TermControl::_SendPastedTextToConnection` to send the
  data to `_terminal->SendCharEvent()` instead. I then pasted the test
  string ""𐐌𐐜𐐬" and ensured that the new `TerminalInput::_SendChar`
  method still correctly assembles surrogate pairs.

Closes #3516
Closes #3554 (obsoleted by this PR)
Potentially impacts #391, which sounds like a duplicate of #3516
2020-04-07 19:09:28 +00:00

34 lines
1.2 KiB
C++

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "ControlKeyStates.hpp"
namespace Microsoft::Terminal::Core
{
class ITerminalInput
{
public:
virtual ~ITerminalInput() {}
ITerminalInput(const ITerminalInput&) = default;
ITerminalInput(ITerminalInput&&) = default;
ITerminalInput& operator=(const ITerminalInput&) = default;
ITerminalInput& operator=(ITerminalInput&&) = default;
virtual bool SendKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states) = 0;
virtual bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta) = 0;
virtual bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) = 0;
// void SendMouseEvent(uint row, uint col, KeyModifiers modifiers);
[[nodiscard]] virtual HRESULT UserResize(const COORD size) noexcept = 0;
virtual void UserScrollViewport(const int viewTop) = 0;
virtual int GetScrollOffset() = 0;
virtual void TrySnapOnInput() = 0;
protected:
ITerminalInput() = default;
};
}