Skip to content

Commit f321c30

Browse files
authored
Use Char[] for Connection stdin (#19655)
This makes it possible to pass through non-null-terminated strings. This is needed for the tmux control mode which passes string slices.
1 parent aefacd6 commit f321c30

File tree

14 files changed

+49
-89
lines changed

14 files changed

+49
-89
lines changed

src/cascadia/TerminalApp/DebugTapConnection.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,25 +120,25 @@ namespace winrt::Microsoft::TerminalApp::implementation
120120
return ConnectionState::Failed;
121121
}
122122

123-
void DebugTapConnection::_OutputHandler(const std::wstring_view str)
123+
void DebugTapConnection::_OutputHandler(const winrt::array_view<const char16_t> str)
124124
{
125-
auto output = til::visualize_control_codes(str);
125+
auto output = til::visualize_control_codes(winrt_array_to_wstring_view(str));
126126
// To make the output easier to read, we introduce a line break whenever
127127
// an LF control is encountered. But at this point, the LF would have
128128
// been converted to U+240A (␊), so that's what we need to search for.
129129
for (size_t lfPos = 0; (lfPos = output.find(L'\u240A', lfPos)) != std::wstring::npos;)
130130
{
131131
output.insert(++lfPos, L"\r\n");
132132
}
133-
TerminalOutput.raise(output);
133+
TerminalOutput.raise(winrt_wstring_to_array_view(output));
134134
}
135135

136136
// Called by the DebugInputTapConnection to print user input
137137
void DebugTapConnection::_PrintInput(const std::wstring_view str)
138138
{
139139
auto clean{ til::visualize_control_codes(str) };
140140
auto formatted{ wil::str_printf<std::wstring>(L"\x1b[91m%ls\x1b[m", clean.data()) };
141-
TerminalOutput.raise(formatted);
141+
TerminalOutput.raise(winrt_wstring_to_array_view(formatted));
142142
}
143143

144144
// Wire us up so that we can forward input through

src/cascadia/TerminalApp/DebugTapConnection.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ namespace winrt::Microsoft::TerminalApp::implementation
3131

3232
private:
3333
void _PrintInput(const std::wstring_view data);
34-
void _OutputHandler(const std::wstring_view str);
34+
void _OutputHandler(const winrt::array_view<const char16_t> str);
3535

3636
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection::TerminalOutput_revoker _outputRevoker;
3737
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection::StateChanged_revoker _stateChangedRevoker;

src/cascadia/TerminalConnection/AzureConnection.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,15 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
9494
// - helper that will write an unterminated string (generally, from a resource) to the output stream.
9595
// Arguments:
9696
// - str: the string to write.
97+
void AzureConnection::_WriteStringWithNewline(std::wstring str)
98+
{
99+
str.append(L"\r\n");
100+
TerminalOutput.raise(winrt_wstring_to_array_view(str));
101+
}
102+
97103
void AzureConnection::_WriteStringWithNewline(const std::wstring_view str)
98104
{
99-
TerminalOutput.raise(str + L"\r\n");
105+
TerminalOutput.raise(winrt_wstring_to_array_view(str + L"\r\n"));
100106
}
101107

102108
// Method description:
@@ -112,7 +118,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
112118
catch (const std::exception& runtimeException)
113119
{
114120
// This also catches the AzureException, which has a .what()
115-
TerminalOutput.raise(_colorize(91, til::u8u16(std::string{ runtimeException.what() })));
121+
TerminalOutput.raise(winrt_wstring_to_array_view(_colorize(91, til::u8u16(std::string{ runtimeException.what() }))));
116122
}
117123
catch (...)
118124
{
@@ -162,13 +168,13 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
162168

163169
_currentInputMode = mode;
164170

165-
TerminalOutput.raise(L"> \x1b[92m"); // Make prompted user input green
171+
TerminalOutput.raise(winrt_wstring_to_array_view(L"> \x1b[92m")); // Make prompted user input green
166172

167173
_inputEvent.wait(inputLock, [this, mode]() {
168174
return _currentInputMode != mode || _isStateAtOrBeyond(ConnectionState::Closing);
169175
});
170176

171-
TerminalOutput.raise(L"\x1b[m");
177+
TerminalOutput.raise(winrt_wstring_to_array_view(L"\x1b[m"));
172178

173179
if (_isStateAtOrBeyond(ConnectionState::Closing))
174180
{
@@ -211,19 +217,19 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
211217
if (_userInput.size() > 0)
212218
{
213219
_userInput.pop_back();
214-
TerminalOutput.raise(L"\x08 \x08"); // overstrike the character with a space
220+
TerminalOutput.raise(winrt_wstring_to_array_view(L"\x08 \x08")); // overstrike the character with a space
215221
}
216222
}
217223
else
218224
{
219-
TerminalOutput.raise(data); // echo back
225+
TerminalOutput.raise(winrt_wstring_to_array_view(data)); // echo back
220226

221227
switch (_currentInputMode)
222228
{
223229
case InputMode::Line:
224230
if (data.size() > 0 && gsl::at(data, 0) == UNICODE_CARRIAGERETURN)
225231
{
226-
TerminalOutput.raise(L"\r\n"); // we probably got a \r, so we need to advance to the next line.
232+
TerminalOutput.raise(winrt_wstring_to_array_view(L"\r\n")); // we probably got a \r, so we need to advance to the next line.
227233
_currentInputMode = InputMode::None; // toggling the mode indicates completion
228234
_inputEvent.notify_one();
229235
break;
@@ -429,7 +435,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
429435
}
430436

431437
// Pass the output to our registered event handlers
432-
TerminalOutput.raise(_u16Str);
438+
TerminalOutput.raise(winrt_wstring_to_array_view(_u16Str));
433439
break;
434440
}
435441
case WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE:
@@ -772,7 +778,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
772778
const auto shellType = _ParsePreferredShellType(settingsResponse);
773779
_WriteStringWithNewline(RS_(L"AzureRequestingTerminal"));
774780
const auto socketUri = _GetTerminal(shellType);
775-
TerminalOutput.raise(L"\r\n");
781+
TerminalOutput.raise(winrt_wstring_to_array_view(L"\r\n"));
776782

777783
//// Step 8: connecting to said terminal
778784
{

src/cascadia/TerminalConnection/AzureConnection.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
6767
std::optional<::Microsoft::Terminal::Azure::Tenant> _currentTenant;
6868

6969
void _writeInput(const std::wstring_view str);
70+
void _WriteStringWithNewline(std::wstring str);
7071
void _WriteStringWithNewline(const std::wstring_view str);
7172
void _WriteCaughtExceptionRecord();
7273
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);

src/cascadia/TerminalConnection/ConptyConnection.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -477,31 +477,28 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
477477
const auto hr = wil::ResultFromCaughtException();
478478

479479
// GH#11556 - make sure to format the error code to this string as an UNSIGNED int
480-
const auto failureText = RS_fmt(L"ProcessFailedToLaunch", _formatStatus(hr), _commandline);
481-
TerminalOutput.raise(failureText);
480+
auto failureText = RS_fmt(L"ProcessFailedToLaunch", _formatStatus(hr), _commandline);
482481

483482
// If the path was invalid, let's present an informative message to the user
484483
if (hr == HRESULT_FROM_WIN32(ERROR_DIRECTORY))
485484
{
486-
const auto badPathText = RS_fmt(L"BadPathText", _startingDirectory);
487-
TerminalOutput.raise(L"\r\n");
488-
TerminalOutput.raise(badPathText);
485+
failureText.append(L"\r\n");
486+
failureText.append(RS_fmt(L"BadPathText", _startingDirectory));
489487
}
490488
// If the requested action requires elevation, display appropriate message
491489
else if (hr == HRESULT_FROM_WIN32(ERROR_ELEVATION_REQUIRED))
492490
{
493-
const auto elevationText = RS_(L"ElevationRequired");
494-
TerminalOutput.raise(L"\r\n");
495-
TerminalOutput.raise(elevationText);
491+
failureText.append(L"\r\n");
492+
failureText.append(RS_(L"ElevationRequired"));
496493
}
497494
// If the requested executable was not found, display appropriate message
498495
else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
499496
{
500-
const auto fileNotFoundText = RS_(L"FileNotFound");
501-
TerminalOutput.raise(L"\r\n");
502-
TerminalOutput.raise(fileNotFoundText);
497+
failureText.append(L"\r\n");
498+
failureText.append(RS_(L"FileNotFound"));
503499
}
504500

501+
TerminalOutput.raise(winrt_wstring_to_array_view(failureText));
505502
_transitionToState(ConnectionState::Failed);
506503

507504
// Tear down any state we may have accumulated.
@@ -520,7 +517,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
520517
const auto msg1 = RS_fmt(L"ProcessExited", _formatStatus(status));
521518
const auto msg2 = RS_(L"CtrlDToClose");
522519
const auto msg = fmt::format(FMT_COMPILE(L"\r\n{}\r\n{}\r\n"), msg1, msg2);
523-
TerminalOutput.raise(msg);
520+
TerminalOutput.raise(winrt_wstring_to_array_view(msg));
524521
}
525522
CATCH_LOG();
526523
}
@@ -792,7 +789,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
792789

793790
try
794791
{
795-
TerminalOutput.raise(wstr);
792+
TerminalOutput.raise(winrt_wstring_to_array_view(wstr));
796793
}
797794
CATCH_LOG();
798795
}

src/cascadia/TerminalConnection/EchoConnection.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
3434
prettyPrint << wch;
3535
}
3636
}
37-
TerminalOutput.raise(prettyPrint.str());
37+
TerminalOutput.raise(winrt_wstring_to_array_view(prettyPrint.str()));
3838
}
3939

4040
void EchoConnection::Resize(uint32_t /*rows*/, uint32_t /*columns*/) noexcept

src/cascadia/TerminalConnection/ITerminalConnection.idl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace Microsoft.Terminal.TerminalConnection
1313
Failed
1414
};
1515

16-
delegate void TerminalOutputHandler(String output);
16+
delegate void TerminalOutputHandler(Char[] output);
1717

1818
interface ITerminalConnection
1919
{

src/cascadia/TerminalControl/ControlCore.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
#include <DefaultSettings.h>
1212
#include <unicode.hpp>
13-
#include <utils.hpp>
14-
#include <WinUser.h>
1513

1614
#include "EventArgs.h"
1715
#include "../../renderer/atlas/AtlasEngine.h"
@@ -2238,13 +2236,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
22382236
auto noticeArgs = winrt::make<NoticeEventArgs>(NoticeLevel::Info, RS_(L"TermControlReadOnly"));
22392237
RaiseNotice.raise(*this, std::move(noticeArgs));
22402238
}
2241-
void ControlCore::_connectionOutputHandler(const hstring& hstr)
2239+
void ControlCore::_connectionOutputHandler(const winrt::array_view<const char16_t> str)
22422240
{
22432241
try
22442242
{
22452243
{
22462244
const auto lock = _terminal->LockForWriting();
2247-
_terminal->Write(hstr);
2245+
_terminal->Write(winrt_array_to_wstring_view(str));
22482246
}
22492247

22502248
if (!_pendingResponses.empty())

src/cascadia/TerminalControl/ControlCore.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
349349

350350
void _raiseReadOnlyWarning();
351351
void _updateAntiAliasingMode();
352-
void _connectionOutputHandler(const hstring& hstr);
352+
void _connectionOutputHandler(winrt::array_view<const char16_t> str);
353353
void _connectionStateChangedHandler(const TerminalConnection::ITerminalConnection&, const Windows::Foundation::IInspectable&);
354354
void _updateHoveredCell(const std::optional<til::point> terminalPosition);
355355
void _setOpacity(const float opacity, const bool focused = true);

src/cascadia/TerminalSettingsEditor/PreviewConnection.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
2828
{
2929
PreviewConnection::PreviewConnection() noexcept = default;
3030

31-
void PreviewConnection::Start() noexcept
31+
void PreviewConnection::Start()
3232
{
33-
// Send the preview text
34-
TerminalOutput.raise(fmt::format(PreviewText, _displayPowerlineGlyphs ? PromptTextPowerline : PromptTextPlain));
33+
const auto prompt = _displayPowerlineGlyphs ? PromptTextPowerline : PromptTextPlain;
34+
const auto text = fmt::format(FMT_COMPILE(PreviewText), prompt);
35+
TerminalOutput.raise(winrt_wstring_to_array_view(text));
3536
}
3637

3738
void PreviewConnection::Initialize(const Windows::Foundation::Collections::ValueSet& /*settings*/) noexcept
@@ -50,7 +51,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
5051
{
5152
}
5253

53-
void PreviewConnection::DisplayPowerlineGlyphs(bool d) noexcept
54+
void PreviewConnection::DisplayPowerlineGlyphs(bool d)
5455
{
5556
if (_displayPowerlineGlyphs != d)
5657
{

0 commit comments

Comments
 (0)