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
34 lines
1.2 KiB
C++
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;
|
|
};
|
|
}
|