From 6e70c4ae0720666dd95505e0ac924e6a7735accd Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 20 Jul 2021 10:02:17 -0500 Subject: [PATCH] Switch Connections to use `ValueSet`s to initialize them (#10184) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### ⚠️ targets #10051 ## Summary of the Pull Request This PR does one big, primary thing. It removes all the constructors from any TerminalConnections, and changes them to use an `Initialize` method that accepts a `ValueSet` of properties. Why? For the upcoming window/content process work, we'll need the content process to be able to initialize the connection _in the content process_. However, the window process will be the one that knows what type of connection to make. Enter `ConnectionInformation`. This class will let us specify the class name of the type we want to create, and a set of settings to use when initializing that connection. **IMPORTANT**: As a part of this, the constructor for a connection must have 0 arguments. `RoActivateInstance` lets you just conjure a WinRT type just by class name, but that class must have a 0 arg ctor. Hence the need for `Initialize`, to actually pass the settings. We're using a `ValueSet` here because it's basically a json blob, with more steps. In the future, when extension authors want to have custom connections, we can always deserialize the json into a `ValueSet`, pass it to their connection's `Initialize`, and let then get what they need out of it. ## References * Tear-out: #1256 * Megathread: #5000 * Project: https://github.com/microsoft/terminal/projects/5 ## PR Checklist * [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760298 * [x] I work here * [n/a] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments `ConnectionInformation` was included as a part of this PR, to demonstrate how this will eventually be used. `ConnectionInformation` is not _currently_ used. ## Validation Steps Performed It still builds and runs. --- scratch/ScratchIslandApp/SampleApp/MyPage.cpp | 23 +++-- .../ScratchIslandApp/SampleApp/MyPage.xaml | 13 ++- .../ScratchIslandApp/SampleApp/MySettings.h | 13 ++- .../SampleApp/dll/SampleApp.vcxproj | 4 + .../TerminalApp/DebugTapConnection.cpp | 1 + src/cascadia/TerminalApp/DebugTapConnection.h | 1 + src/cascadia/TerminalApp/TerminalPage.cpp | 31 +++---- src/cascadia/TerminalAzBridge/main.cpp | 6 +- src/cascadia/TerminalAzBridge/pch.h | 1 + .../TerminalConnection/AzureConnection.cpp | 10 ++- .../TerminalConnection/AzureConnection.h | 4 +- .../TerminalConnection/AzureConnection.idl | 2 +- .../ConnectionInformation.cpp | 66 ++++++++++++++ .../ConnectionInformation.h | 43 +++++++++ .../ConnectionInformation.idl | 17 ++++ .../TerminalConnection/ConptyConnection.cpp | 88 +++++++++++++------ .../TerminalConnection/ConptyConnection.h | 33 +++---- .../TerminalConnection/ConptyConnection.idl | 10 ++- .../TerminalConnection/EchoConnection.h | 2 + .../ITerminalConnection.idl | 2 + .../TerminalConnection.vcxproj | 7 ++ .../PreviewConnection.cpp | 4 + .../PreviewConnection.h | 1 + .../UnitTests_Control/MockConnection.h | 1 + 24 files changed, 304 insertions(+), 79 deletions(-) create mode 100644 src/cascadia/TerminalConnection/ConnectionInformation.cpp create mode 100644 src/cascadia/TerminalConnection/ConnectionInformation.h create mode 100644 src/cascadia/TerminalConnection/ConnectionInformation.idl diff --git a/scratch/ScratchIslandApp/SampleApp/MyPage.cpp b/scratch/ScratchIslandApp/SampleApp/MyPage.cpp index d4af3d80e..647fb11d2 100644 --- a/scratch/ScratchIslandApp/SampleApp/MyPage.cpp +++ b/scratch/ScratchIslandApp/SampleApp/MyPage.cpp @@ -5,7 +5,7 @@ #include "MyPage.h" #include #include "MyPage.g.cpp" -#include "..\..\..\src\cascadia\UnitTests_Control\MockControlSettings.h" +#include "MySettings.h" using namespace std::chrono_literals; using namespace winrt::Microsoft::Terminal; @@ -26,17 +26,24 @@ namespace winrt::SampleApp::implementation void MyPage::Create() { - TerminalConnection::EchoConnection conn{}; - auto settings = winrt::make_self(); + auto settings = winrt::make_self(); + auto connectionSettings{ TerminalConnection::ConptyConnection::CreateSettings(L"cmd.exe /k echo This TermControl is hosted in-proc...", + winrt::hstring{}, + L"", + nullptr, + 32, + 80, + winrt::guid()) }; + + // "Microsoft.Terminal.TerminalConnection.ConptyConnection" + winrt::hstring myClass{ winrt::name_of() }; + TerminalConnection::ConnectionInformation connectInfo{ myClass, connectionSettings }; + + TerminalConnection::ITerminalConnection conn{ TerminalConnection::ConnectionInformation::CreateConnection(connectInfo) }; Control::TermControl control{ *settings, conn }; InProcContent().Children().Append(control); - - // Once the control loads (and not before that), write some text for debugging: - control.Initialized([conn](auto&&, auto&&) { - conn.WriteInput(L"This TermControl is hosted in-proc..."); - }); } // Method Description: diff --git a/scratch/ScratchIslandApp/SampleApp/MyPage.xaml b/scratch/ScratchIslandApp/SampleApp/MyPage.xaml index f6e129ee7..0c132dea2 100644 --- a/scratch/ScratchIslandApp/SampleApp/MyPage.xaml +++ b/scratch/ScratchIslandApp/SampleApp/MyPage.xaml @@ -19,10 +19,15 @@ - + + + + + #include #include "MySettings.g.h" @@ -12,9 +14,6 @@ namespace winrt::SampleApp::implementation { struct MySettings : MySettingsT { - public: - MySettings() = default; - // --------------------------- Core Settings --------------------------- // All of these settings are defined in ICoreSettings. @@ -88,6 +87,14 @@ namespace winrt::SampleApp::implementation winrt::Microsoft::Terminal::Core::Color GetColorTableEntry(int32_t index) noexcept { return _ColorTable.at(index); } std::array ColorTable() { return _ColorTable; } void ColorTable(std::array /*colors*/) {} + + MySettings() + { + const auto campbellSpan = ::Microsoft::Console::Utils::CampbellColorTable(); + std::transform(campbellSpan.begin(), campbellSpan.end(), _ColorTable.begin(), [](auto&& color) { + return static_cast(til::color{ color }); + }); + } }; } diff --git a/scratch/ScratchIslandApp/SampleApp/dll/SampleApp.vcxproj b/scratch/ScratchIslandApp/SampleApp/dll/SampleApp.vcxproj index d49f6c697..23b157e9d 100644 --- a/scratch/ScratchIslandApp/SampleApp/dll/SampleApp.vcxproj +++ b/scratch/ScratchIslandApp/SampleApp/dll/SampleApp.vcxproj @@ -48,6 +48,10 @@ true true + + + {18D09A24-8240-42D6-8CB6-236EEE820263} + diff --git a/src/cascadia/TerminalApp/DebugTapConnection.cpp b/src/cascadia/TerminalApp/DebugTapConnection.cpp index 0a71c8bff..54f327b3e 100644 --- a/src/cascadia/TerminalApp/DebugTapConnection.cpp +++ b/src/cascadia/TerminalApp/DebugTapConnection.cpp @@ -19,6 +19,7 @@ namespace winrt::Microsoft::TerminalApp::implementation _wrappedConnection{ std::move(wrappedConnection) } { } + void Initialize(const Windows::Foundation::Collections::ValueSet& /*settings*/) {} ~DebugInputTapConnection() = default; void Start() { diff --git a/src/cascadia/TerminalApp/DebugTapConnection.h b/src/cascadia/TerminalApp/DebugTapConnection.h index 16e3fc82e..c5156afc4 100644 --- a/src/cascadia/TerminalApp/DebugTapConnection.h +++ b/src/cascadia/TerminalApp/DebugTapConnection.h @@ -13,6 +13,7 @@ namespace winrt::Microsoft::TerminalApp::implementation { public: explicit DebugTapConnection(Microsoft::Terminal::TerminalConnection::ITerminalConnection wrappedConnection); + void Initialize(const Windows::Foundation::Collections::ValueSet& /*settings*/){}; ~DebugTapConnection(); void Start(); void WriteInput(hstring const& data); diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index d781e6fe8..75e95291c 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -797,13 +797,14 @@ namespace winrt::TerminalApp::implementation // TODO GH#4661: Replace this with directly using the AzCon when our VT is better std::filesystem::path azBridgePath{ wil::GetModuleFileNameW(nullptr) }; azBridgePath.replace_filename(L"TerminalAzBridge.exe"); - connection = TerminalConnection::ConptyConnection(azBridgePath.wstring(), - L".", - L"Azure", - nullptr, - settings.InitialRows(), - settings.InitialCols(), - winrt::guid()); + connection = TerminalConnection::ConptyConnection(); + connection.Initialize(TerminalConnection::ConptyConnection::CreateSettings(azBridgePath.wstring(), + L".", + L"Azure", + nullptr, + ::base::saturated_cast(settings.InitialRows()), + ::base::saturated_cast(settings.InitialCols()), + winrt::guid())); } else @@ -833,14 +834,14 @@ namespace winrt::TerminalApp::implementation std::filesystem::path cwd{ cwdString }; cwd /= settings.StartingDirectory().c_str(); - auto conhostConn = TerminalConnection::ConptyConnection( - settings.Commandline(), - winrt::hstring{ cwd.c_str() }, - settings.StartingTitle(), - envMap.GetView(), - settings.InitialRows(), - settings.InitialCols(), - winrt::guid()); + auto conhostConn = TerminalConnection::ConptyConnection(); + conhostConn.Initialize(TerminalConnection::ConptyConnection::CreateSettings(settings.Commandline(), + winrt::hstring{ cwd.wstring() }, + settings.StartingTitle(), + envMap.GetView(), + ::base::saturated_cast(settings.InitialRows()), + ::base::saturated_cast(settings.InitialCols()), + winrt::guid())); sessionGuid = conhostConn.Guid(); connection = conhostConn; diff --git a/src/cascadia/TerminalAzBridge/main.cpp b/src/cascadia/TerminalAzBridge/main.cpp index df51677d7..3137109e9 100644 --- a/src/cascadia/TerminalAzBridge/main.cpp +++ b/src/cascadia/TerminalAzBridge/main.cpp @@ -96,7 +96,11 @@ int wmain(int /*argc*/, wchar_t** /*argv*/) const auto size = GetConsoleScreenSize(conOut); - AzureConnection azureConn{ gsl::narrow_cast(size.Y), gsl::narrow_cast(size.X) }; + AzureConnection azureConn{}; + winrt::Windows::Foundation::Collections::ValueSet vs{}; + vs.Insert(L"initialRows", winrt::Windows::Foundation::PropertyValue::CreateUInt32(gsl::narrow_cast(size.Y))); + vs.Insert(L"initialCols", winrt::Windows::Foundation::PropertyValue::CreateUInt32(gsl::narrow_cast(size.X))); + azureConn.Initialize(vs); const auto state = RunConnectionToCompletion(azureConn, conOut, conIn); diff --git a/src/cascadia/TerminalAzBridge/pch.h b/src/cascadia/TerminalAzBridge/pch.h index 8a1dc650f..5b8835166 100644 --- a/src/cascadia/TerminalAzBridge/pch.h +++ b/src/cascadia/TerminalAzBridge/pch.h @@ -33,6 +33,7 @@ Abstract: #include #include +#include #include #include diff --git a/src/cascadia/TerminalConnection/AzureConnection.cpp b/src/cascadia/TerminalConnection/AzureConnection.cpp index 2798896a2..d5fe0bdd7 100644 --- a/src/cascadia/TerminalConnection/AzureConnection.cpp +++ b/src/cascadia/TerminalConnection/AzureConnection.cpp @@ -71,11 +71,13 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation return (AzureClientID != L"0"); } - AzureConnection::AzureConnection(const uint32_t initialRows, const uint32_t initialCols) : - _initialRows{ initialRows }, - _initialCols{ initialCols }, - _expiry{} + void AzureConnection::Initialize(const Windows::Foundation::Collections::ValueSet& settings) { + if (settings) + { + _initialRows = winrt::unbox_value_or(settings.TryLookup(L"initialRows").try_as(), _initialRows); + _initialCols = winrt::unbox_value_or(settings.TryLookup(L"initialCols").try_as(), _initialCols); + } } // Method description: diff --git a/src/cascadia/TerminalConnection/AzureConnection.h b/src/cascadia/TerminalConnection/AzureConnection.h index b2afd99ab..7c51294f8 100644 --- a/src/cascadia/TerminalConnection/AzureConnection.h +++ b/src/cascadia/TerminalConnection/AzureConnection.h @@ -21,7 +21,9 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation { static winrt::guid ConnectionType() noexcept; static bool IsAzureConnectionAvailable() noexcept; - AzureConnection(const uint32_t rows, const uint32_t cols); + + AzureConnection() = default; + void Initialize(const Windows::Foundation::Collections::ValueSet& settings); void Start(); void WriteInput(hstring const& data); diff --git a/src/cascadia/TerminalConnection/AzureConnection.idl b/src/cascadia/TerminalConnection/AzureConnection.idl index 6bd6e4930..ecaface97 100644 --- a/src/cascadia/TerminalConnection/AzureConnection.idl +++ b/src/cascadia/TerminalConnection/AzureConnection.idl @@ -10,7 +10,7 @@ namespace Microsoft.Terminal.TerminalConnection static Guid ConnectionType { get; }; static Boolean IsAzureConnectionAvailable(); - AzureConnection(UInt32 rows, UInt32 columns); + AzureConnection(); }; } diff --git a/src/cascadia/TerminalConnection/ConnectionInformation.cpp b/src/cascadia/TerminalConnection/ConnectionInformation.cpp new file mode 100644 index 000000000..5ae37fad6 --- /dev/null +++ b/src/cascadia/TerminalConnection/ConnectionInformation.cpp @@ -0,0 +1,66 @@ +#include "pch.h" +#include "ConnectionInformation.h" +#include "ConnectionInformation.g.cpp" + +namespace winrt::Microsoft::Terminal::TerminalConnection::implementation +{ + ConnectionInformation::ConnectionInformation(hstring const& className, + const Windows::Foundation::Collections::ValueSet& settings) : + _ClassName{ className }, + _Settings{ settings } + { + } + + // Function Description: + // - Create an instance of the connection specified in the + // ConnectionInformation, and Initialize it. + // - This static method allows the content process to create a connection + // from information that lives in the window process. + // Arguments: + // - info: A ConnectionInformation object that possibly lives out-of-proc, + // containing the name of the WinRT class we should activate for this + // connection, and a bag of setting to use to initialize that object. + // Return Value: + // - + TerminalConnection::ITerminalConnection ConnectionInformation::CreateConnection(TerminalConnection::ConnectionInformation info) + try + { + Windows::Foundation::IInspectable inspectable{}; + + const auto name = static_cast(winrt::get_abi(info.ClassName())); + const auto pointer = winrt::put_abi(inspectable); + +#pragma warning(push) +#pragma warning(disable : 26490) + // C++/WinRT just loves it's void**, nothing we can do here _except_ reinterpret_cast + ::IInspectable** raw = reinterpret_cast<::IInspectable**>(pointer); +#pragma warning(pop) + + // RoActivateInstance() will try to create an instance of the object, + // who's fully qualified name is the string in Name(). + // + // The class has to be activatable. For the Terminal, this is easy + // enough - we're not hosting anything that's not already in our + // manifest, or living as a .dll & .winmd SxS. + // + // When we get to extensions (GH#4000), we may want to revisit. + if (LOG_IF_FAILED(RoActivateInstance(name, raw))) + { + return nullptr; + } + + // Now that thing we made, make sure it's actually a ITerminalConnection + if (const auto connection{ inspectable.try_as() }) + { + // Initialize it, and return it. + connection.Initialize(info.Settings()); + return connection; + } + return nullptr; + } + catch (...) + { + LOG_CAUGHT_EXCEPTION(); + return nullptr; + } +} diff --git a/src/cascadia/TerminalConnection/ConnectionInformation.h b/src/cascadia/TerminalConnection/ConnectionInformation.h new file mode 100644 index 000000000..75bdd23d7 --- /dev/null +++ b/src/cascadia/TerminalConnection/ConnectionInformation.h @@ -0,0 +1,43 @@ +/*++ +Copyright (c) Microsoft Corporation +Licensed under the MIT license. + +Class Name: +- ConnectionInformation.h + +Abstract: +- This is a helper object for storing both the name of a type of connection, and + a bag of settings to use to initialize that connection. +- This helper is used primarily in cross-proc scenarios, to allow the window + process to tell the content process the name of the connection type it wants + created, and how to set that connection up. This is done so the connection can + live entirely in the content process, without having to go through the window + process at all. +--*/ + +#pragma once +#include "../inc/cppwinrt_utils.h" +#include "ConnectionInformation.g.h" + +namespace winrt::Microsoft::Terminal::TerminalConnection::implementation +{ + struct ConnectionInformation : ConnectionInformationT + { + ConnectionInformation(hstring const& className, + const Windows::Foundation::Collections::ValueSet& settings); + + static TerminalConnection::ITerminalConnection CreateConnection(TerminalConnection::ConnectionInformation info); + + winrt::hstring ClassName() const { return _ClassName; } + void ClassName(const winrt::hstring& value) { _ClassName = value; } + + WINRT_PROPERTY(Windows::Foundation::Collections::ValueSet, Settings); + + private: + winrt::hstring _ClassName{}; + }; +} +namespace winrt::Microsoft::Terminal::TerminalConnection::factory_implementation +{ + BASIC_FACTORY(ConnectionInformation); +} diff --git a/src/cascadia/TerminalConnection/ConnectionInformation.idl b/src/cascadia/TerminalConnection/ConnectionInformation.idl new file mode 100644 index 000000000..832336eaf --- /dev/null +++ b/src/cascadia/TerminalConnection/ConnectionInformation.idl @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import "ITerminalConnection.idl"; + +namespace Microsoft.Terminal.TerminalConnection +{ + [default_interface] runtimeclass ConnectionInformation + { + ConnectionInformation(String className, Windows.Foundation.Collections.ValueSet settings); + String ClassName { get; }; + Windows.Foundation.Collections.ValueSet Settings { get; }; + + static ITerminalConnection CreateConnection(ConnectionInformation info); + } + +} diff --git a/src/cascadia/TerminalConnection/ConptyConnection.cpp b/src/cascadia/TerminalConnection/ConptyConnection.cpp index a5666f782..2be231e80 100644 --- a/src/cascadia/TerminalConnection/ConptyConnection.cpp +++ b/src/cascadia/TerminalConnection/ConptyConnection.cpp @@ -116,17 +116,23 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation // add additional WT env vars like WT_SETTINGS, WT_DEFAULTS and WT_PROFILE_ID for (auto item : _environment) { - auto key = item.Key(); - auto value = item.Value(); - - // avoid clobbering WSLENV - if (std::wstring_view{ key } == L"WSLENV") + try { - auto current = environment[L"WSLENV"]; - value = current + L":" + value; - } + auto key = item.Key(); + // This will throw if the value isn't a string. If that + // happens, then just skip this entry. + auto value = winrt::unbox_value(item.Value()); - environment.insert_or_assign(key.c_str(), value.c_str()); + // avoid clobbering WSLENV + if (std::wstring_view{ key } == L"WSLENV") + { + auto current = environment[L"WSLENV"]; + value = current + L":" + value; + } + + environment.insert_or_assign(key.c_str(), value.c_str()); + } + CATCH_LOG(); } } @@ -219,24 +225,54 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation _piClient.hProcess = hClientProcess; } - ConptyConnection::ConptyConnection(const hstring& commandline, - const hstring& startingDirectory, - const hstring& startingTitle, - const Windows::Foundation::Collections::IMapView& environment, - const uint32_t initialRows, - const uint32_t initialCols, - const guid& initialGuid) : - _initialRows{ initialRows }, - _initialCols{ initialCols }, - _commandline{ commandline }, - _startingDirectory{ startingDirectory }, - _startingTitle{ startingTitle }, - _environment{ environment }, - _guid{ initialGuid }, - _u8State{}, - _u16Str{}, - _buffer{} + // Function Description: + // - Helper function for constructing a ValueSet that we can use to get our settings from. + Windows::Foundation::Collections::ValueSet ConptyConnection::CreateSettings(const winrt::hstring& cmdline, + const winrt::hstring& startingDirectory, + const winrt::hstring& startingTitle, + Windows::Foundation::Collections::IMapView const& environment, + uint32_t rows, + uint32_t columns, + winrt::guid const& guid) { + Windows::Foundation::Collections::ValueSet vs{}; + + vs.Insert(L"commandline", Windows::Foundation::PropertyValue::CreateString(cmdline)); + vs.Insert(L"startingDirectory", Windows::Foundation::PropertyValue::CreateString(startingDirectory)); + vs.Insert(L"startingTitle", Windows::Foundation::PropertyValue::CreateString(startingTitle)); + vs.Insert(L"initialRows", Windows::Foundation::PropertyValue::CreateUInt32(rows)); + vs.Insert(L"initialCols", Windows::Foundation::PropertyValue::CreateUInt32(columns)); + vs.Insert(L"guid", Windows::Foundation::PropertyValue::CreateGuid(guid)); + + if (environment) + { + Windows::Foundation::Collections::ValueSet env{}; + for (const auto& [k, v] : environment) + { + env.Insert(k, Windows::Foundation::PropertyValue::CreateString(v)); + } + vs.Insert(L"environment", env); + } + return vs; + } + + void ConptyConnection::Initialize(const Windows::Foundation::Collections::ValueSet& settings) + { + if (settings) + { + // For the record, the following won't crash: + // auto bad = unbox_value_or(settings.TryLookup(L"foo").try_as(), nullptr); + // It'll just return null + + _commandline = winrt::unbox_value_or(settings.TryLookup(L"commandline").try_as(), _commandline); + _startingDirectory = winrt::unbox_value_or(settings.TryLookup(L"startingDirectory").try_as(), _startingDirectory); + _startingTitle = winrt::unbox_value_or(settings.TryLookup(L"startingTitle").try_as(), _startingTitle); + _initialRows = winrt::unbox_value_or(settings.TryLookup(L"initialRows").try_as(), _initialRows); + _initialCols = winrt::unbox_value_or(settings.TryLookup(L"initialCols").try_as(), _initialCols); + _guid = winrt::unbox_value_or(settings.TryLookup(L"guid").try_as(), _guid); + _environment = settings.TryLookup(L"environment").try_as(); + } + if (_guid == guid{}) { _guid = Utils::CreateGuid(); diff --git a/src/cascadia/TerminalConnection/ConptyConnection.h b/src/cascadia/TerminalConnection/ConptyConnection.h index f53b4a56e..8f82a617b 100644 --- a/src/cascadia/TerminalConnection/ConptyConnection.h +++ b/src/cascadia/TerminalConnection/ConptyConnection.h @@ -26,14 +26,9 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation const HANDLE hServerProcess, const HANDLE hClientProcess); - ConptyConnection( - const hstring& cmdline, - const hstring& startingDirectory, - const hstring& startingTitle, - const Windows::Foundation::Collections::IMapView& environment, - const uint32_t rows, - const uint32_t cols, - const guid& guid); + ConptyConnection() noexcept = default; + void Initialize(const Windows::Foundation::Collections::ValueSet& settings); + static winrt::fire_and_forget final_release(std::unique_ptr connection); void Start(); @@ -49,6 +44,14 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation static winrt::event_token NewConnection(NewConnectionHandler const& handler); static void NewConnection(winrt::event_token const& token); + static Windows::Foundation::Collections::ValueSet CreateSettings(const winrt::hstring& cmdline, + const winrt::hstring& startingDirectory, + const winrt::hstring& startingTitle, + Windows::Foundation::Collections::IMapView const& environment, + uint32_t rows, + uint32_t columns, + winrt::guid const& guid); + WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler); private: @@ -60,10 +63,10 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation uint32_t _initialRows{}; uint32_t _initialCols{}; - hstring _commandline; - hstring _startingDirectory; - hstring _startingTitle; - Windows::Foundation::Collections::IMapView _environment; + hstring _commandline{}; + hstring _startingDirectory{}; + hstring _startingTitle{}; + Windows::Foundation::Collections::ValueSet _environment{ nullptr }; guid _guid{}; // A unique session identifier for connected client hstring _clientName{}; // The name of the process hosted by this ConPTY connection (as of launch). @@ -77,9 +80,9 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation wil::unique_static_pseudoconsole_handle _hPC; wil::unique_threadpool_wait _clientExitWait; - til::u8state _u8State; - std::wstring _u16Str; - std::array _buffer; + til::u8state _u8State{}; + std::wstring _u16Str{}; + std::array _buffer{}; DWORD _OutputThread(); }; diff --git a/src/cascadia/TerminalConnection/ConptyConnection.idl b/src/cascadia/TerminalConnection/ConptyConnection.idl index 766c7263a..a1cfa9790 100644 --- a/src/cascadia/TerminalConnection/ConptyConnection.idl +++ b/src/cascadia/TerminalConnection/ConptyConnection.idl @@ -7,11 +7,19 @@ namespace Microsoft.Terminal.TerminalConnection { [default_interface] runtimeclass ConptyConnection : ITerminalConnection { - ConptyConnection(String cmdline, String startingDirectory, String startingTitle, IMapView environment, UInt32 rows, UInt32 columns, Guid guid); + ConptyConnection(); Guid Guid { get; }; static event NewConnectionHandler NewConnection; static void StartInboundListener(); static void StopInboundListener(); + + static Windows.Foundation.Collections.ValueSet CreateSettings(String cmdline, + String startingDirectory, + String startingTitle, + IMapView environment, + UInt32 rows, + UInt32 columns, + Guid guid); }; } diff --git a/src/cascadia/TerminalConnection/EchoConnection.h b/src/cascadia/TerminalConnection/EchoConnection.h index 0f034457d..e29f07429 100644 --- a/src/cascadia/TerminalConnection/EchoConnection.h +++ b/src/cascadia/TerminalConnection/EchoConnection.h @@ -18,6 +18,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation void Resize(uint32_t rows, uint32_t columns) noexcept; void Close() noexcept; + void Initialize(const Windows::Foundation::Collections::ValueSet& /*settings*/) const noexcept {}; + ConnectionState State() const noexcept { return ConnectionState::Connected; } WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler); diff --git a/src/cascadia/TerminalConnection/ITerminalConnection.idl b/src/cascadia/TerminalConnection/ITerminalConnection.idl index e485cc06d..28de4f520 100644 --- a/src/cascadia/TerminalConnection/ITerminalConnection.idl +++ b/src/cascadia/TerminalConnection/ITerminalConnection.idl @@ -17,6 +17,8 @@ namespace Microsoft.Terminal.TerminalConnection interface ITerminalConnection { + void Initialize(Windows.Foundation.Collections.ValueSet settings); + void Start(); void WriteInput(String data); void Resize(UInt32 rows, UInt32 columns); diff --git a/src/cascadia/TerminalConnection/TerminalConnection.vcxproj b/src/cascadia/TerminalConnection/TerminalConnection.vcxproj index 8af1cf09a..5cfd57c40 100644 --- a/src/cascadia/TerminalConnection/TerminalConnection.vcxproj +++ b/src/cascadia/TerminalConnection/TerminalConnection.vcxproj @@ -13,6 +13,9 @@ + + ConnectionInformation.idl + AzureConnection.idl @@ -28,6 +31,9 @@ + + ConnectionInformation.idl + AzureConnection.idl @@ -43,6 +49,7 @@ + diff --git a/src/cascadia/TerminalSettingsEditor/PreviewConnection.cpp b/src/cascadia/TerminalSettingsEditor/PreviewConnection.cpp index c7d9cd345..949c22e3b 100644 --- a/src/cascadia/TerminalSettingsEditor/PreviewConnection.cpp +++ b/src/cascadia/TerminalSettingsEditor/PreviewConnection.cpp @@ -24,6 +24,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation _TerminalOutputHandlers(PreviewText); } + void PreviewConnection::Initialize(const Windows::Foundation::Collections::ValueSet& /*settings*/) noexcept + { + } + void PreviewConnection::WriteInput(hstring const& /*data*/) { } diff --git a/src/cascadia/TerminalSettingsEditor/PreviewConnection.h b/src/cascadia/TerminalSettingsEditor/PreviewConnection.h index 0c04664f0..7d4c773d7 100644 --- a/src/cascadia/TerminalSettingsEditor/PreviewConnection.h +++ b/src/cascadia/TerminalSettingsEditor/PreviewConnection.h @@ -22,6 +22,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation public: PreviewConnection() noexcept; + void Initialize(const Windows::Foundation::Collections::ValueSet& settings) noexcept; void Start() noexcept; void WriteInput(hstring const& data); void Resize(uint32_t rows, uint32_t columns) noexcept; diff --git a/src/cascadia/UnitTests_Control/MockConnection.h b/src/cascadia/UnitTests_Control/MockConnection.h index 14b024df1..1b7b36131 100644 --- a/src/cascadia/UnitTests_Control/MockConnection.h +++ b/src/cascadia/UnitTests_Control/MockConnection.h @@ -16,6 +16,7 @@ namespace ControlUnitTests public: MockConnection() noexcept = default; + void Initialize(const winrt::Windows::Foundation::Collections::ValueSet& /*settings*/){}; void Start() noexcept {}; void WriteInput(winrt::hstring const& data) {