mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-10 00:48:23 -06:00
Use a plain char array to pass connection input (#17710)
`HSTRING` does not permit strings that aren't null-terminated. As such we'll simply use a plain char array which compiles down to a `UINT32` and `wchar_t*` pointer pair. Unfortunately, cppwinrt uses `char16_t` in place of `wchar_t`, and also offers no trivial conversion between `winrt::array_view` and `std::wstring_view` either. As such, most of this PR is about explicit type casting. Closes #17697 ## Validation Steps Performed * Patch the `DeviceAttributes` implementation in `adaptDispatch.cpp` to respond like this: ```cpp _api.ReturnResponse({L"ABCD", 3}); ``` * Open a WSL shell and execute this: ```sh printf "\e[c"; read ``` * Doesn't crash ✅
This commit is contained in:
parent
4a40c4329a
commit
9c1436775e
@ -39,10 +39,10 @@ namespace winrt::Microsoft::TerminalApp::implementation
|
||||
|
||||
_wrappedConnection.Start();
|
||||
}
|
||||
void WriteInput(const hstring& data)
|
||||
void WriteInput(const winrt::array_view<const char16_t> buffer)
|
||||
{
|
||||
_pairedTap->_PrintInput(data);
|
||||
_wrappedConnection.WriteInput(data);
|
||||
_pairedTap->_PrintInput(winrt_array_to_wstring_view(buffer));
|
||||
_wrappedConnection.WriteInput(buffer);
|
||||
}
|
||||
void Resize(uint32_t rows, uint32_t columns) { _wrappedConnection.Resize(rows, columns); }
|
||||
void Close() { _wrappedConnection.Close(); }
|
||||
@ -77,13 +77,13 @@ namespace winrt::Microsoft::TerminalApp::implementation
|
||||
_start.count_down();
|
||||
}
|
||||
|
||||
void DebugTapConnection::WriteInput(const hstring& data)
|
||||
void DebugTapConnection::WriteInput(const winrt::array_view<const char16_t> buffer)
|
||||
{
|
||||
// If the user types into the tap side, forward it to the input side
|
||||
if (auto strongInput{ _inputSide.get() })
|
||||
{
|
||||
auto inputAsTap{ winrt::get_self<DebugInputTapConnection>(strongInput) };
|
||||
inputAsTap->WriteInput(data);
|
||||
inputAsTap->WriteInput(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ namespace winrt::Microsoft::TerminalApp::implementation
|
||||
return ConnectionState::Failed;
|
||||
}
|
||||
|
||||
void DebugTapConnection::_OutputHandler(const hstring str)
|
||||
void DebugTapConnection::_OutputHandler(const std::wstring_view str)
|
||||
{
|
||||
auto output = til::visualize_control_codes(str);
|
||||
// To make the output easier to read, we introduce a line break whenever
|
||||
@ -131,7 +131,7 @@ namespace winrt::Microsoft::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Called by the DebugInputTapConnection to print user input
|
||||
void DebugTapConnection::_PrintInput(const hstring& str)
|
||||
void DebugTapConnection::_PrintInput(const std::wstring_view str)
|
||||
{
|
||||
auto clean{ til::visualize_control_codes(str) };
|
||||
auto formatted{ wil::str_printf<std::wstring>(L"\x1b[91m%ls\x1b[m", clean.data()) };
|
||||
|
||||
@ -16,7 +16,7 @@ namespace winrt::Microsoft::TerminalApp::implementation
|
||||
void Initialize(const Windows::Foundation::Collections::ValueSet& /*settings*/){};
|
||||
~DebugTapConnection();
|
||||
void Start();
|
||||
void WriteInput(const hstring& data);
|
||||
void WriteInput(const winrt::array_view<const char16_t> data);
|
||||
void Resize(uint32_t rows, uint32_t columns);
|
||||
void Close();
|
||||
|
||||
@ -30,8 +30,8 @@ namespace winrt::Microsoft::TerminalApp::implementation
|
||||
til::typed_event<winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection, winrt::Windows::Foundation::IInspectable> StateChanged;
|
||||
|
||||
private:
|
||||
void _PrintInput(const hstring& data);
|
||||
void _OutputHandler(const hstring str);
|
||||
void _PrintInput(const std::wstring_view data);
|
||||
void _OutputHandler(const std::wstring_view str);
|
||||
|
||||
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection::TerminalOutput_revoker _outputRevoker;
|
||||
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection::StateChanged_revoker _stateChangedRevoker;
|
||||
|
||||
@ -42,7 +42,7 @@ static ConnectionState RunConnectionToCompletion(const ITerminalConnection& conn
|
||||
auto input = reader.Read();
|
||||
if (input)
|
||||
{
|
||||
connection.WriteInput(*input);
|
||||
connection.WriteInput(winrt_wstring_to_array_view(*input));
|
||||
}
|
||||
}
|
||||
}).detach();
|
||||
|
||||
@ -186,7 +186,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
// - handles the different possible inputs in the different states
|
||||
// Arguments:
|
||||
// the user's input
|
||||
void AzureConnection::WriteInput(const hstring& data)
|
||||
void AzureConnection::WriteInput(const winrt::array_view<const char16_t> buffer)
|
||||
{
|
||||
_writeInput(winrt_array_to_wstring_view(buffer));
|
||||
}
|
||||
|
||||
void AzureConnection::_writeInput(const std::wstring_view data)
|
||||
{
|
||||
// We read input while connected AND connecting.
|
||||
if (!_isStateOneOf(ConnectionState::Connected, ConnectionState::Connecting))
|
||||
@ -804,7 +809,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
std::swap(_userInput, queuedUserInput);
|
||||
if (queuedUserInput.size() > 0)
|
||||
{
|
||||
WriteInput(static_cast<winrt::hstring>(queuedUserInput)); // send the user's queued up input back through
|
||||
_writeInput(queuedUserInput); // send the user's queued up input back through
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
void Initialize(const Windows::Foundation::Collections::ValueSet& settings);
|
||||
|
||||
void Start();
|
||||
void WriteInput(const hstring& data);
|
||||
void WriteInput(const winrt::array_view<const char16_t> buffer);
|
||||
void Resize(uint32_t rows, uint32_t columns);
|
||||
void Close();
|
||||
|
||||
@ -66,6 +66,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
std::vector<::Microsoft::Terminal::Azure::Tenant> _tenantList;
|
||||
std::optional<::Microsoft::Terminal::Azure::Tenant> _currentTenant;
|
||||
|
||||
void _writeInput(const std::wstring_view str);
|
||||
void _WriteStringWithNewline(const std::wstring_view str);
|
||||
void _WriteCaughtExceptionRecord();
|
||||
winrt::Windows::Data::Json::JsonObject _SendRequestReturningJson(std::wstring_view uri, const winrt::Windows::Web::Http::IHttpContent& content = nullptr, winrt::Windows::Web::Http::HttpMethod method = nullptr, const winrt::Windows::Foundation::Uri referer = nullptr);
|
||||
|
||||
@ -473,8 +473,10 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
}
|
||||
CATCH_LOG()
|
||||
|
||||
void ConptyConnection::WriteInput(const hstring& data)
|
||||
void ConptyConnection::WriteInput(const winrt::array_view<const char16_t> buffer)
|
||||
{
|
||||
const auto data = winrt_array_to_wstring_view(buffer);
|
||||
|
||||
if (!_isConnected())
|
||||
{
|
||||
return;
|
||||
|
||||
@ -21,7 +21,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
static winrt::fire_and_forget final_release(std::unique_ptr<ConptyConnection> connection);
|
||||
|
||||
void Start();
|
||||
void WriteInput(const hstring& data);
|
||||
void WriteInput(const winrt::array_view<const char16_t> buffer);
|
||||
void Resize(uint32_t rows, uint32_t columns);
|
||||
void Close() noexcept;
|
||||
void ClearBuffer();
|
||||
|
||||
@ -15,8 +15,9 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
{
|
||||
}
|
||||
|
||||
void EchoConnection::WriteInput(const hstring& data)
|
||||
void EchoConnection::WriteInput(const winrt::array_view<const char16_t> buffer)
|
||||
{
|
||||
const auto data = winrt_array_to_wstring_view(buffer);
|
||||
std::wstringstream prettyPrint;
|
||||
for (const auto& wch : data)
|
||||
{
|
||||
|
||||
@ -12,7 +12,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
EchoConnection() noexcept;
|
||||
|
||||
void Start() noexcept;
|
||||
void WriteInput(const hstring& data);
|
||||
void WriteInput(const winrt::array_view<const char16_t> buffer);
|
||||
void Resize(uint32_t rows, uint32_t columns) noexcept;
|
||||
void Close() noexcept;
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ namespace Microsoft.Terminal.TerminalConnection
|
||||
void Initialize(Windows.Foundation.Collections.ValueSet settings);
|
||||
|
||||
void Start();
|
||||
void WriteInput(String data);
|
||||
void WriteInput(Char[] data);
|
||||
void Resize(UInt32 rows, UInt32 columns);
|
||||
void Close();
|
||||
|
||||
|
||||
@ -438,7 +438,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
else
|
||||
{
|
||||
_connection.WriteInput(wstr);
|
||||
_connection.WriteInput(winrt_wstring_to_array_view(wstr));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2487,7 +2487,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
// _sendInputToConnection() asserts that we aren't in focus mode,
|
||||
// but window focus events are always fine to send.
|
||||
_connection.WriteInput(*out);
|
||||
_connection.WriteInput(winrt_wstring_to_array_view(*out));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
}
|
||||
|
||||
void PreviewConnection::WriteInput(const hstring& /*data*/)
|
||||
void PreviewConnection::WriteInput(const winrt::array_view<const char16_t> /*data*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
void Initialize(const Windows::Foundation::Collections::ValueSet& settings) noexcept;
|
||||
void Start() noexcept;
|
||||
void WriteInput(const hstring& data);
|
||||
void WriteInput(const winrt::array_view<const char16_t> buffer);
|
||||
void Resize(uint32_t rows, uint32_t columns) noexcept;
|
||||
void Close() noexcept;
|
||||
|
||||
|
||||
@ -249,9 +249,9 @@ namespace ControlUnitTests
|
||||
L"(leaving the cursor afer 'Bar')");
|
||||
for (auto i = 0; i < 40; ++i)
|
||||
{
|
||||
conn->WriteInput(L"Foo\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
}
|
||||
conn->WriteInput(L"Bar");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Bar"));
|
||||
|
||||
// We printed that 40 times, but the final \r\n bumped the view down one MORE row.
|
||||
Log::Comment(L"Check the buffer viewport before the clear");
|
||||
@ -286,9 +286,9 @@ namespace ControlUnitTests
|
||||
L"(leaving the cursor afer 'Bar')");
|
||||
for (auto i = 0; i < 40; ++i)
|
||||
{
|
||||
conn->WriteInput(L"Foo\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
}
|
||||
conn->WriteInput(L"Bar");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Bar"));
|
||||
|
||||
// We printed that 40 times, but the final \r\n bumped the view down one MORE row.
|
||||
Log::Comment(L"Check the buffer viewport before the clear");
|
||||
@ -323,9 +323,9 @@ namespace ControlUnitTests
|
||||
L"(leaving the cursor afer 'Bar')");
|
||||
for (auto i = 0; i < 40; ++i)
|
||||
{
|
||||
conn->WriteInput(L"Foo\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
}
|
||||
conn->WriteInput(L"Bar");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Bar"));
|
||||
|
||||
// We printed that 40 times, but the final \r\n bumped the view down one MORE row.
|
||||
Log::Comment(L"Check the buffer viewport before the clear");
|
||||
@ -358,25 +358,26 @@ namespace ControlUnitTests
|
||||
_standardInit(core);
|
||||
|
||||
Log::Comment(L"Print some text");
|
||||
conn->WriteInput(L"This is some text \r\n");
|
||||
conn->WriteInput(L"with varying amounts \r\n");
|
||||
conn->WriteInput(L"of whitespace \r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"This is some text \r\n"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"with varying amounts \r\n"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"of whitespace \r\n"));
|
||||
|
||||
Log::Comment(L"Check the buffer contents");
|
||||
VERIFY_ARE_EQUAL(L"This is some text\r\nwith varying amounts\r\nof whitespace\r\n",
|
||||
core->ReadEntireBuffer());
|
||||
}
|
||||
void _writePrompt(const winrt::com_ptr<MockConnection>& conn, const auto& path)
|
||||
|
||||
static void _writePrompt(const winrt::com_ptr<MockConnection>& conn, const std::wstring_view& path)
|
||||
{
|
||||
conn->WriteInput(L"\x1b]133;D\x7");
|
||||
conn->WriteInput(L"\x1b]133;A\x7");
|
||||
conn->WriteInput(L"\x1b]9;9;");
|
||||
conn->WriteInput(path);
|
||||
conn->WriteInput(L"\x7");
|
||||
conn->WriteInput(L"PWSH ");
|
||||
conn->WriteInput(path);
|
||||
conn->WriteInput(L"> ");
|
||||
conn->WriteInput(L"\x1b]133;B\x7");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\x1b]133;D\x7"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\x1b]133;A\x7"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\x1b]9;9;"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(path));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\x7"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"PWSH "));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(path));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"> "));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\x1b]133;B\x7"));
|
||||
}
|
||||
|
||||
void ControlCoreTests::TestSelectCommandSimple()
|
||||
@ -390,13 +391,13 @@ namespace ControlUnitTests
|
||||
Log::Comment(L"Print some text");
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows");
|
||||
conn->WriteInput(L"Foo-bar");
|
||||
conn->WriteInput(L"\x1b]133;C\x7");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo-bar"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\x1b]133;C\x7"));
|
||||
|
||||
conn->WriteInput(L"\r\n");
|
||||
conn->WriteInput(L"This is some text \r\n");
|
||||
conn->WriteInput(L"with varying amounts \r\n");
|
||||
conn->WriteInput(L"of whitespace \r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\r\n"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"This is some text \r\n"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"with varying amounts \r\n"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"of whitespace \r\n"));
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows");
|
||||
|
||||
@ -422,8 +423,8 @@ namespace ControlUnitTests
|
||||
}
|
||||
|
||||
core->_terminal->ClearSelection();
|
||||
conn->WriteInput(L"Boo-far");
|
||||
conn->WriteInput(L"\x1b]133;C\x7");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Boo-far"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\x1b]133;C\x7"));
|
||||
|
||||
VERIFY_IS_FALSE(core->HasSelection());
|
||||
{
|
||||
@ -473,13 +474,13 @@ namespace ControlUnitTests
|
||||
Log::Comment(L"Print some text");
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows");
|
||||
conn->WriteInput(L"Foo-bar");
|
||||
conn->WriteInput(L"\x1b]133;C\x7");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo-bar"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\x1b]133;C\x7"));
|
||||
|
||||
conn->WriteInput(L"\r\n");
|
||||
conn->WriteInput(L"This is some text \r\n");
|
||||
conn->WriteInput(L"with varying amounts \r\n");
|
||||
conn->WriteInput(L"of whitespace \r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\r\n"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"This is some text \r\n"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"with varying amounts \r\n"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"of whitespace \r\n"));
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows");
|
||||
|
||||
@ -515,13 +516,13 @@ namespace ControlUnitTests
|
||||
Log::Comment(L"Print some text");
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows");
|
||||
conn->WriteInput(L"Foo-bar");
|
||||
conn->WriteInput(L"\x1b]133;C\x7");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo-bar"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\x1b]133;C\x7"));
|
||||
|
||||
conn->WriteInput(L"\r\n");
|
||||
conn->WriteInput(L"This is some text \r\n");
|
||||
conn->WriteInput(L"with varying amounts \r\n");
|
||||
conn->WriteInput(L"of whitespace \r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\r\n"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"This is some text \r\n"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"with varying amounts \r\n"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"of whitespace \r\n"));
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows");
|
||||
|
||||
@ -535,7 +536,7 @@ namespace ControlUnitTests
|
||||
}
|
||||
|
||||
Log::Comment(L"Write 'Bar' to the command...");
|
||||
conn->WriteInput(L"Bar");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Bar"));
|
||||
{
|
||||
auto historyContext{ core->CommandHistory() };
|
||||
// Bar shouldn't be in the history, it should be the current command
|
||||
@ -544,9 +545,9 @@ namespace ControlUnitTests
|
||||
}
|
||||
|
||||
Log::Comment(L"then delete it");
|
||||
conn->WriteInput(L"\b \b");
|
||||
conn->WriteInput(L"\b \b");
|
||||
conn->WriteInput(L"\b \b");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\b \b"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\b \b"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\b \b"));
|
||||
{
|
||||
auto historyContext{ core->CommandHistory() };
|
||||
VERIFY_ARE_EQUAL(1u, historyContext.History().Size());
|
||||
@ -566,23 +567,23 @@ namespace ControlUnitTests
|
||||
Log::Comment(L"Print some text");
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows"); // row 0
|
||||
conn->WriteInput(L"Foo-bar"); // row 0
|
||||
conn->WriteInput(L"\x1b]133;C\x7");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo-bar")); // row 0
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\x1b]133;C\x7"));
|
||||
|
||||
conn->WriteInput(L"\r\n");
|
||||
conn->WriteInput(L"This is some text \r\n"); // row 1
|
||||
conn->WriteInput(L"with varying amounts \r\n"); // row 2
|
||||
conn->WriteInput(L"of whitespace \r\n"); // row 3
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\r\n"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"This is some text \r\n")); // row 1
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"with varying amounts \r\n")); // row 2
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"of whitespace \r\n")); // row 3
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows"); // row 4
|
||||
conn->WriteInput(L"gci");
|
||||
conn->WriteInput(L"\x1b]133;C\x7");
|
||||
conn->WriteInput(L"\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"gci"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\x1b]133;C\x7"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\r\n"));
|
||||
|
||||
// enough to scroll
|
||||
for (auto i = 0; i < 30; i++) // row 5-34
|
||||
{
|
||||
conn->WriteInput(L"-a--- 2/8/2024 9:47 README\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"-a--- 2/8/2024 9:47 README\r\n"));
|
||||
}
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows");
|
||||
@ -635,23 +636,23 @@ namespace ControlUnitTests
|
||||
Log::Comment(L"Print some text");
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows"); // row 0
|
||||
conn->WriteInput(L"Foo-bar"); // row 0
|
||||
conn->WriteInput(L"\x1b]133;C\x7");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo-bar")); // row 0
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\x1b]133;C\x7"));
|
||||
|
||||
conn->WriteInput(L"\r\n");
|
||||
conn->WriteInput(L"This is some text \r\n"); // row 1
|
||||
conn->WriteInput(L"with varying amounts \r\n"); // row 2
|
||||
conn->WriteInput(L"of whitespace \r\n"); // row 3
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\r\n"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"This is some text \r\n")); // row 1
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"with varying amounts \r\n")); // row 2
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"of whitespace \r\n")); // row 3
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows"); // row 4
|
||||
conn->WriteInput(L"gci");
|
||||
conn->WriteInput(L"\x1b]133;C\x7");
|
||||
conn->WriteInput(L"\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"gci"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\x1b]133;C\x7"));
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\r\n"));
|
||||
|
||||
// enough to scroll
|
||||
for (auto i = 0; i < 30; i++) // row 5-35
|
||||
{
|
||||
conn->WriteInput(L"-a--- 2/8/2024 9:47 README.md\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"-a--- 2/8/2024 9:47 README.md\r\n"));
|
||||
}
|
||||
|
||||
_writePrompt(conn, L"C:\\Windows");
|
||||
|
||||
@ -230,7 +230,7 @@ namespace ControlUnitTests
|
||||
expectedBufferHeight++;
|
||||
}
|
||||
|
||||
conn->WriteInput(L"Foo\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
}
|
||||
// We printed that 40 times, but the final \r\n bumped the view down one MORE row.
|
||||
VERIFY_ARE_EQUAL(20, core->_terminal->GetViewport().Height());
|
||||
@ -398,7 +398,7 @@ namespace ControlUnitTests
|
||||
Log::Comment(L"Add some test to the terminal so we can scroll");
|
||||
for (auto i = 0; i < 40; ++i)
|
||||
{
|
||||
conn->WriteInput(L"Foo\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
}
|
||||
// We printed that 40 times, but the final \r\n bumped the view down one MORE row.
|
||||
VERIFY_ARE_EQUAL(20, core->_terminal->GetViewport().Height());
|
||||
@ -475,7 +475,7 @@ namespace ControlUnitTests
|
||||
|
||||
for (auto i = 0; i < 40; ++i)
|
||||
{
|
||||
conn->WriteInput(L"Foo\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
}
|
||||
// We printed that 40 times, but the final \r\n bumped the view down one MORE row.
|
||||
VERIFY_ARE_EQUAL(20, core->_terminal->GetViewport().Height());
|
||||
@ -534,7 +534,7 @@ namespace ControlUnitTests
|
||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 2/5
|
||||
VERIFY_ARE_EQUAL(21, core->ScrollOffset());
|
||||
|
||||
conn->WriteInput(L"Foo\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
VERIFY_ARE_EQUAL(22, core->ScrollOffset());
|
||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 1/5
|
||||
VERIFY_ARE_EQUAL(22, core->ScrollOffset());
|
||||
@ -699,7 +699,7 @@ namespace ControlUnitTests
|
||||
expectedBufferHeight++;
|
||||
}
|
||||
|
||||
conn->WriteInput(L"Foo\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
}
|
||||
// We printed that 40 times, but the final \r\n bumped the view down one MORE row.
|
||||
VERIFY_ARE_EQUAL(20, core->_terminal->GetViewport().Height());
|
||||
@ -721,7 +721,7 @@ namespace ControlUnitTests
|
||||
}
|
||||
|
||||
// Enable VT mouse event tracking
|
||||
conn->WriteInput(L"\x1b[?1003;1006h");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"\x1b[?1003;1006h"));
|
||||
|
||||
// Mouse clicks in the inactive region (i.e. the top 10 rows in this case) should not register
|
||||
Log::Comment(L"Click on the terminal");
|
||||
@ -765,7 +765,7 @@ namespace ControlUnitTests
|
||||
// at the point where outputting more lines causes circular incrementing
|
||||
for (auto i = 0; i < settings->HistorySize() + core->ViewHeight(); ++i)
|
||||
{
|
||||
conn->WriteInput(L"Foo\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
}
|
||||
VERIFY_ARE_EQUAL(scrollbackLength, core->_terminal->GetScrollOffset());
|
||||
|
||||
@ -811,7 +811,7 @@ namespace ControlUnitTests
|
||||
VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionEnd());
|
||||
|
||||
Log::Comment(L"Output a line of text");
|
||||
conn->WriteInput(L"Foo\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
|
||||
Log::Comment(L"Verify the location of the selection");
|
||||
// The selection should now be 1 row lower
|
||||
@ -829,7 +829,7 @@ namespace ControlUnitTests
|
||||
VERIFY_ARE_EQUAL(scrollbackLength - 1, core->_terminal->GetScrollOffset());
|
||||
|
||||
Log::Comment(L"Output a line of text");
|
||||
conn->WriteInput(L"Foo\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
|
||||
Log::Comment(L"Verify the location of the selection");
|
||||
// The selection should now be 1 row lower
|
||||
@ -875,7 +875,7 @@ namespace ControlUnitTests
|
||||
Log::Comment(L"Output a line ant move the mouse a little to update the selection, all at once");
|
||||
// Same as above. The viewport has moved, so the mouse is still over the
|
||||
// same character, even though it's at a new offset.
|
||||
conn->WriteInput(L"Foo\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
expectedAnchor.y -= 1;
|
||||
VERIFY_ARE_EQUAL(scrollbackLength - 3, core->_terminal->GetScrollOffset());
|
||||
interactivity->PointerMoved(leftMouseDown,
|
||||
@ -900,7 +900,7 @@ namespace ControlUnitTests
|
||||
// Output enough text for the selection to get pushed off the buffer
|
||||
for (auto i = 0; i < settings->HistorySize() + core->ViewHeight(); ++i)
|
||||
{
|
||||
conn->WriteInput(L"Foo\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
}
|
||||
// Verify that the selection got reset
|
||||
VERIFY_IS_FALSE(core->HasSelection());
|
||||
@ -954,7 +954,7 @@ namespace ControlUnitTests
|
||||
// Output enough text for view to start scrolling
|
||||
for (auto i = 0; i < core->ViewHeight() * 2; ++i)
|
||||
{
|
||||
conn->WriteInput(L"Foo\r\n");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
}
|
||||
|
||||
// Start checking output
|
||||
@ -1018,7 +1018,7 @@ namespace ControlUnitTests
|
||||
modifiers,
|
||||
cursorPosition0.to_core_point());
|
||||
// Flush it out.
|
||||
conn->WriteInput(L"sentinel");
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"sentinel"));
|
||||
VERIFY_ARE_EQUAL(0u, expectedOutput.size(), L"Validate we drained all the expected output");
|
||||
|
||||
// This is the part as mentioned in GH#12719
|
||||
|
||||
@ -16,9 +16,9 @@ namespace ControlUnitTests
|
||||
|
||||
void Initialize(const winrt::Windows::Foundation::Collections::ValueSet& /*settings*/){};
|
||||
void Start() noexcept {};
|
||||
void WriteInput(const winrt::hstring& data)
|
||||
void WriteInput(const winrt::array_view<const char16_t> data)
|
||||
{
|
||||
TerminalOutput.raise(data);
|
||||
TerminalOutput.raise(winrt_array_to_wstring_view(data));
|
||||
}
|
||||
void Resize(uint32_t /*rows*/, uint32_t /*columns*/) noexcept {}
|
||||
void Close() noexcept {}
|
||||
|
||||
@ -176,6 +176,18 @@ protected:
|
||||
{ \
|
||||
};
|
||||
|
||||
inline winrt::array_view<const char16_t> winrt_wstring_to_array_view(const std::wstring_view& str)
|
||||
{
|
||||
#pragma warning(suppress : 26490) // Don't use reinterpret_cast (type.1).
|
||||
return winrt::array_view<const char16_t>(reinterpret_cast<const char16_t*>(str.data()), gsl::narrow<uint32_t>(str.size()));
|
||||
}
|
||||
|
||||
inline std::wstring_view winrt_array_to_wstring_view(const winrt::array_view<const char16_t>& str) noexcept
|
||||
{
|
||||
#pragma warning(suppress : 26490) // Don't use reinterpret_cast (type.1).
|
||||
return { reinterpret_cast<const wchar_t*>(str.data()), str.size() };
|
||||
}
|
||||
|
||||
// This is a helper method for deserializing a SAFEARRAY of
|
||||
// COM objects and converting it to a vector that
|
||||
// owns the extracted COM objects
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user