mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-06 14:19:45 +00:00
Compare commits
32 Commits
dev/cazamo
...
dev/migrie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2aad178aae | ||
|
|
4291e88c04 | ||
|
|
13b1516183 | ||
|
|
b2f9ee0610 | ||
|
|
c15a520235 | ||
|
|
871f60c3b8 | ||
|
|
75c9657603 | ||
|
|
c814d9e02b | ||
|
|
4ac6bf5784 | ||
|
|
b0aae0796b | ||
|
|
beb7b1ada0 | ||
|
|
ca8c7943ee | ||
|
|
b0c3e362c0 | ||
|
|
ddb8042b38 | ||
|
|
5bcf0fc7bb | ||
|
|
24c745f8b7 | ||
|
|
08c603356f | ||
|
|
9cc8d61b07 | ||
|
|
3da6613064 | ||
|
|
7febffedc5 | ||
|
|
0c190c27b9 | ||
|
|
52c59ed594 | ||
|
|
899f00910e | ||
|
|
62888a5a0f | ||
|
|
82b687682f | ||
|
|
ec7dfc5525 | ||
|
|
27096e619f | ||
|
|
092957f937 | ||
|
|
d902eb8477 | ||
|
|
6de50b036a | ||
|
|
560629114c | ||
|
|
21cf69d741 |
1
.github/actions/spelling/allow/apis.txt
vendored
1
.github/actions/spelling/allow/apis.txt
vendored
@@ -157,6 +157,7 @@ ptstr
|
||||
QUERYENDSESSION
|
||||
rcx
|
||||
REGCLS
|
||||
requal
|
||||
RETURNCMD
|
||||
rfind
|
||||
RLO
|
||||
|
||||
1
.github/actions/spelling/allow/microsoft.txt
vendored
1
.github/actions/spelling/allow/microsoft.txt
vendored
@@ -13,6 +13,7 @@ autoexec
|
||||
backplating
|
||||
bitmaps
|
||||
BOMs
|
||||
combase
|
||||
COMPUTERNAME
|
||||
CPLs
|
||||
cpptools
|
||||
|
||||
@@ -1187,43 +1187,45 @@ namespace winrt::TerminalApp::implementation
|
||||
// - the terminal settings
|
||||
// Return value:
|
||||
// - the desired connection
|
||||
TerminalConnection::ITerminalConnection TerminalPage::_CreateConnectionFromSettings(Profile profile,
|
||||
TerminalSettings settings)
|
||||
TerminalConnection::ConnectionInformation TerminalPage::_CreateConnectionInfoFromSettings(Profile profile,
|
||||
TerminalSettings settings)
|
||||
{
|
||||
TerminalConnection::ITerminalConnection connection{ nullptr };
|
||||
|
||||
auto connectionType = profile.ConnectionType();
|
||||
winrt::guid sessionGuid{};
|
||||
|
||||
Windows::Foundation::Collections::ValueSet connectionSettings{ nullptr };
|
||||
winrt::hstring className;
|
||||
|
||||
if (connectionType == TerminalConnection::AzureConnection::ConnectionType() &&
|
||||
TerminalConnection::AzureConnection::IsAzureConnectionAvailable())
|
||||
{
|
||||
std::filesystem::path azBridgePath{ wil::GetModuleFileNameW<std::wstring>(nullptr) };
|
||||
azBridgePath.replace_filename(L"TerminalAzBridge.exe");
|
||||
|
||||
if constexpr (Feature_AzureConnectionInProc::IsEnabled())
|
||||
{
|
||||
connection = TerminalConnection::AzureConnection{};
|
||||
className = winrt::name_of<TerminalConnection::AzureConnection>();
|
||||
// AzureConnection doesn't have any connection-specific config
|
||||
// currently. Just use an empty blob.
|
||||
connectionSettings = Windows::Foundation::Collections::ValueSet{};
|
||||
}
|
||||
else
|
||||
{
|
||||
connection = TerminalConnection::ConptyConnection{};
|
||||
className = winrt::name_of<TerminalConnection::ConptyConnection>();
|
||||
connectionSettings = TerminalConnection::ConptyConnection::CreateSettings(azBridgePath.wstring(),
|
||||
L".",
|
||||
L"Azure",
|
||||
nullptr,
|
||||
settings.InitialRows(),
|
||||
settings.InitialCols(),
|
||||
winrt::guid(),
|
||||
profile.Guid());
|
||||
}
|
||||
|
||||
auto valueSet = TerminalConnection::ConptyConnection::CreateSettings(azBridgePath.wstring(),
|
||||
L".",
|
||||
L"Azure",
|
||||
nullptr,
|
||||
settings.InitialRows(),
|
||||
settings.InitialCols(),
|
||||
winrt::guid(),
|
||||
profile.Guid());
|
||||
|
||||
if constexpr (Feature_VtPassthroughMode::IsEnabled())
|
||||
{
|
||||
valueSet.Insert(L"passthroughMode", Windows::Foundation::PropertyValue::CreateBoolean(settings.VtPassthrough()));
|
||||
connectionSettings.Insert(L"passthroughMode", Windows::Foundation::PropertyValue::CreateBoolean(settings.VtPassthrough()));
|
||||
}
|
||||
|
||||
connection.Initialize(valueSet);
|
||||
}
|
||||
|
||||
else
|
||||
@@ -1256,38 +1258,31 @@ namespace winrt::TerminalApp::implementation
|
||||
cwd /= settings.StartingDirectory().c_str();
|
||||
newWorkingDirectory = winrt::hstring{ cwd.wstring() };
|
||||
}
|
||||
className = winrt::name_of<TerminalConnection::ConptyConnection>();
|
||||
|
||||
auto conhostConn = TerminalConnection::ConptyConnection();
|
||||
auto valueSet = TerminalConnection::ConptyConnection::CreateSettings(settings.Commandline(),
|
||||
newWorkingDirectory,
|
||||
settings.StartingTitle(),
|
||||
environment,
|
||||
settings.InitialRows(),
|
||||
settings.InitialCols(),
|
||||
winrt::guid(),
|
||||
profile.Guid());
|
||||
connectionSettings = TerminalConnection::ConptyConnection::CreateSettings(settings.Commandline(),
|
||||
newWorkingDirectory,
|
||||
settings.StartingTitle(),
|
||||
environment,
|
||||
settings.InitialRows(),
|
||||
settings.InitialCols(),
|
||||
winrt::guid(),
|
||||
profile.Guid());
|
||||
|
||||
valueSet.Insert(L"passthroughMode", Windows::Foundation::PropertyValue::CreateBoolean(settings.VtPassthrough()));
|
||||
valueSet.Insert(L"reloadEnvironmentVariables",
|
||||
Windows::Foundation::PropertyValue::CreateBoolean(_settings.GlobalSettings().ReloadEnvironmentVariables()));
|
||||
|
||||
conhostConn.Initialize(valueSet);
|
||||
|
||||
sessionGuid = conhostConn.Guid();
|
||||
connection = conhostConn;
|
||||
if constexpr (Feature_VtPassthroughMode::IsEnabled())
|
||||
{
|
||||
connectionSettings.Insert(L"passthroughMode", Windows::Foundation::PropertyValue::CreateBoolean(settings.VtPassthrough()));
|
||||
}
|
||||
connectionSettings.Insert(L"reloadEnvironmentVariables",
|
||||
Windows::Foundation::PropertyValue::CreateBoolean(_settings.GlobalSettings().ReloadEnvironmentVariables()));
|
||||
}
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider,
|
||||
"ConnectionCreated",
|
||||
TraceLoggingDescription("Event emitted upon the creation of a connection"),
|
||||
TraceLoggingGuid(connectionType, "ConnectionTypeGuid", "The type of the connection"),
|
||||
TraceLoggingGuid(profile.Guid(), "ProfileGuid", "The profile's GUID"),
|
||||
TraceLoggingGuid(sessionGuid, "SessionGuid", "The WT_SESSION's GUID"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
return TerminalConnection::ConnectionInformation{ className, connectionSettings };
|
||||
}
|
||||
|
||||
return connection;
|
||||
TerminalConnection::ITerminalConnection TerminalPage::_CreateConnectionFromInfo(TerminalConnection::ConnectionInformation connectInfo)
|
||||
{
|
||||
return ConnectionInformation::CreateConnection(connectInfo);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -2774,14 +2769,19 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
TermControl TerminalPage::_CreateNewControlAndContent(const TerminalSettingsCreateResult& settings, const ITerminalConnection& connection)
|
||||
TermControl TerminalPage::_CreateNewControlAndContent(
|
||||
const TerminalSettingsCreateResult& settings,
|
||||
const ITerminalConnection& connection,
|
||||
const TerminalConnection::ConnectionInformation& connectionInfo)
|
||||
{
|
||||
// Do any initialization that needs to apply to _every_ TermControl we
|
||||
// create here.
|
||||
// TermControl will copy the settings out of the settings passed to it.
|
||||
|
||||
const auto content = _manager.CreateCore(settings.DefaultSettings(), settings.UnfocusedSettings(), connection);
|
||||
return _SetupControl(TermControl{ content });
|
||||
const auto& content = _manager.CreateCore(settings.DefaultSettings(), settings.UnfocusedSettings(), connection);
|
||||
const auto& control = _SetupControl(TermControl{ content });
|
||||
control.ConnectionInfo(connectionInfo);
|
||||
return control;
|
||||
}
|
||||
|
||||
TermControl TerminalPage::_AttachControlToContent(const uint64_t& contentId)
|
||||
@@ -2881,10 +2881,44 @@ namespace winrt::TerminalApp::implementation
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto connection = existingConnection ? existingConnection : _CreateConnectionFromSettings(profile, controlSettings.DefaultSettings());
|
||||
// Get the connection info for this set of settings.
|
||||
auto connectionInfo = existingConnection ? nullptr :
|
||||
_CreateConnectionInfoFromSettings(profile, controlSettings.DefaultSettings());
|
||||
|
||||
// If we need to create a new connection, do that now, from the settings
|
||||
// we just built.
|
||||
auto connection = existingConnection ? existingConnection : _CreateConnectionFromInfo(connectionInfo);
|
||||
|
||||
// Finalize some defterm properties
|
||||
if (existingConnection)
|
||||
{
|
||||
connection.Resize(controlSettings.DefaultSettings().InitialRows(), controlSettings.DefaultSettings().InitialCols());
|
||||
|
||||
// If we had an existing connection (i.e., defterm), then get the
|
||||
// current settings out of it and stash those with the control. It
|
||||
// won't be perfect, but it'll be good enough.
|
||||
if (const auto& conpty{ existingConnection.try_as<ConptyConnection>() })
|
||||
{
|
||||
connectionInfo = TerminalConnection::ConnectionInformation(winrt::name_of<TerminalConnection::ConptyConnection>(),
|
||||
conpty.GetDeftermSettings());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// trace log an event if we made the connection ourselves.
|
||||
if (const auto& conpty{ connection.try_as<TerminalConnection::ConptyConnection>() })
|
||||
{
|
||||
const auto sessionGuid = conpty.Guid();
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider,
|
||||
"ConnectionCreated",
|
||||
TraceLoggingDescription("Event emitted upon the creation of a connection"),
|
||||
TraceLoggingGuid(profile.ConnectionType(), "ConnectionTypeGuid", "The type of the connection"),
|
||||
TraceLoggingGuid(profile.Guid(), "ProfileGuid", "The profile's GUID"),
|
||||
TraceLoggingGuid(sessionGuid, "SessionGuid", "The WT_SESSION's GUID"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
}
|
||||
|
||||
TerminalConnection::ITerminalConnection debugConnection{ nullptr };
|
||||
@@ -2898,16 +2932,20 @@ namespace winrt::TerminalApp::implementation
|
||||
if (bothAltsPressed)
|
||||
{
|
||||
std::tie(connection, debugConnection) = OpenDebugTapConnection(connection);
|
||||
// Debug Tap connections aren't really restartable. The
|
||||
// underlying connection is, but it would require some _gnarly_
|
||||
// plumbing to connect the recreated connection back up to the
|
||||
// debug connection.
|
||||
}
|
||||
}
|
||||
|
||||
const auto control = _CreateNewControlAndContent(controlSettings, connection);
|
||||
const auto control = _CreateNewControlAndContent(controlSettings, connection, connectionInfo);
|
||||
|
||||
auto resultPane = std::make_shared<Pane>(profile, control);
|
||||
|
||||
if (debugConnection) // this will only be set if global debugging is on and tap is active
|
||||
{
|
||||
auto newControl = _CreateNewControlAndContent(controlSettings, debugConnection);
|
||||
auto newControl = _CreateNewControlAndContent(controlSettings, debugConnection, nullptr);
|
||||
// Split (auto) with the debug tap.
|
||||
auto debugPane = std::make_shared<Pane>(profile, newControl);
|
||||
|
||||
|
||||
@@ -290,8 +290,10 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _OpenNewTabDropdown();
|
||||
HRESULT _OpenNewTab(const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
|
||||
|
||||
void _CreateNewTabFromPane(std::shared_ptr<Pane> pane, uint32_t insertPosition = -1);
|
||||
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection _CreateConnectionFromSettings(Microsoft::Terminal::Settings::Model::Profile profile, Microsoft::Terminal::Settings::Model::TerminalSettings settings);
|
||||
winrt::Microsoft::Terminal::TerminalConnection::ConnectionInformation _CreateConnectionInfoFromSettings(Microsoft::Terminal::Settings::Model::Profile profile, Microsoft::Terminal::Settings::Model::TerminalSettings settings);
|
||||
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection _CreateConnectionFromInfo(winrt::Microsoft::Terminal::TerminalConnection::ConnectionInformation);
|
||||
|
||||
winrt::fire_and_forget _OpenNewWindow(const Microsoft::Terminal::Settings::Model::NewTerminalArgs newTerminalArgs);
|
||||
|
||||
@@ -429,7 +431,8 @@ namespace winrt::TerminalApp::implementation
|
||||
void _Find(const TerminalTab& tab);
|
||||
|
||||
winrt::Microsoft::Terminal::Control::TermControl _CreateNewControlAndContent(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
|
||||
const winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection& connection);
|
||||
const winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection& connection,
|
||||
const winrt::Microsoft::Terminal::TerminalConnection::ConnectionInformation& connectionInfo);
|
||||
winrt::Microsoft::Terminal::Control::TermControl _SetupControl(const winrt::Microsoft::Terminal::Control::TermControl& term);
|
||||
winrt::Microsoft::Terminal::Control::TermControl _AttachControlToContent(const uint64_t& contentGuid);
|
||||
|
||||
|
||||
@@ -25,32 +25,35 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
TerminalConnection::ITerminalConnection ConnectionInformation::CreateConnection(TerminalConnection::ConnectionInformation info)
|
||||
try
|
||||
{
|
||||
Windows::Foundation::IInspectable inspectable{};
|
||||
// pilfered from `winrt_get_activation_factory` in module.g.cpp. Does a
|
||||
// reverse string match, so that we check the classname first, skipping
|
||||
// the namespace prefixes.
|
||||
static auto requal = [](std::wstring_view const& left, std::wstring_view const& right) noexcept -> bool {
|
||||
return std::equal(left.rbegin(), left.rend(), right.rbegin(), right.rend());
|
||||
};
|
||||
|
||||
const auto name = static_cast<HSTRING>(winrt::get_abi(info.ClassName()));
|
||||
const auto pointer = winrt::put_abi(inspectable);
|
||||
TerminalConnection::ITerminalConnection connection{ nullptr };
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 26490)
|
||||
// C++/WinRT just loves its void**, nothing we can do here _except_ reinterpret_cast
|
||||
auto 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)))
|
||||
// A couple short-circuits, for connections that _we_ implement.
|
||||
if (requal(info.ClassName(), winrt::name_of<TerminalConnection::ConptyConnection>()))
|
||||
{
|
||||
return nullptr;
|
||||
connection = TerminalConnection::ConptyConnection();
|
||||
}
|
||||
else if (requal(info.ClassName(), winrt::name_of<TerminalConnection::AzureConnection>()))
|
||||
{
|
||||
connection = TerminalConnection::AzureConnection();
|
||||
}
|
||||
else if (requal(info.ClassName(), winrt::name_of<TerminalConnection::EchoConnection>()))
|
||||
{
|
||||
connection = TerminalConnection::EchoConnection();
|
||||
}
|
||||
// We don't want to instantiate anything else that we weren't expecting.
|
||||
//
|
||||
// When we get to extensions (GH#4000), we may want to revisit, and try
|
||||
// if (LOG_IF_FAILED(RoActivateInstance(name, raw)))
|
||||
|
||||
// Now that thing we made, make sure it's actually a ITerminalConnection
|
||||
if (const auto connection{ inspectable.try_as<TerminalConnection::ITerminalConnection>() })
|
||||
if (connection)
|
||||
{
|
||||
// Initialize it, and return it.
|
||||
connection.Initialize(info.Settings());
|
||||
|
||||
@@ -86,14 +86,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
return _isStateOneOf(ConnectionState::Connected);
|
||||
}
|
||||
|
||||
void _resetConnectionState()
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> stateLock{ _stateMutex };
|
||||
_connectionState = ConnectionState::NotConnected;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic<ConnectionState> _connectionState{ ConnectionState::NotConnected };
|
||||
mutable std::mutex _stateMutex;
|
||||
|
||||
@@ -263,6 +263,28 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
return vs;
|
||||
}
|
||||
|
||||
// This is used for defterm connections. The app will get these from the
|
||||
// connection when we create the pane, and stash them in the ControlCore.
|
||||
// The core can later use these to attempt to "restart" this defterm
|
||||
// connection. It likely won't be perfect - for example, any env vars that
|
||||
// were used to create the initial client process will be lost in this
|
||||
// process.
|
||||
//
|
||||
// Rows, Columns, guid - none of that should be persisted. That's irrelevant.
|
||||
//
|
||||
// Starting Directory - alas, we don't know that for a defterm connection.
|
||||
// The Core might be able to fill it in, if the client app ever tells the
|
||||
// Terminal.
|
||||
Windows::Foundation::Collections::ValueSet ConptyConnection::GetDeftermSettings()
|
||||
{
|
||||
Windows::Foundation::Collections::ValueSet vs{};
|
||||
|
||||
vs.Insert(L"commandline", Windows::Foundation::PropertyValue::CreateString(_commandline));
|
||||
vs.Insert(L"startingTitle", Windows::Foundation::PropertyValue::CreateString(_startupInfo.title));
|
||||
|
||||
return vs;
|
||||
}
|
||||
|
||||
void ConptyConnection::Initialize(const Windows::Foundation::Collections::ValueSet& settings)
|
||||
{
|
||||
if (settings)
|
||||
@@ -282,6 +304,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
{
|
||||
_passthroughMode = winrt::unbox_value_or<bool>(settings.TryLookup(L"passthroughMode").try_as<Windows::Foundation::IPropertyValue>(), _passthroughMode);
|
||||
}
|
||||
_inheritCursor = winrt::unbox_value_or<bool>(settings.TryLookup(L"inheritCursor").try_as<Windows::Foundation::IPropertyValue>(), _inheritCursor);
|
||||
_reloadEnvironmentVariables = winrt::unbox_value_or<bool>(settings.TryLookup(L"reloadEnvironmentVariables").try_as<Windows::Foundation::IPropertyValue>(),
|
||||
_reloadEnvironmentVariables);
|
||||
_profileGuid = winrt::unbox_value_or<winrt::guid>(settings.TryLookup(L"profileGuid").try_as<Windows::Foundation::IPropertyValue>(), _profileGuid);
|
||||
@@ -316,13 +339,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
void ConptyConnection::Start()
|
||||
try
|
||||
{
|
||||
bool usingExistingBuffer = false;
|
||||
if (_isStateAtOrBeyond(ConnectionState::Closed))
|
||||
{
|
||||
_resetConnectionState();
|
||||
usingExistingBuffer = true;
|
||||
}
|
||||
|
||||
_transitionToState(ConnectionState::Connecting);
|
||||
|
||||
const til::size dimensions{ gsl::narrow<til::CoordType>(_cols), gsl::narrow<til::CoordType>(_rows) };
|
||||
@@ -338,7 +354,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
// PseudoConsole sends a clear screen VT code which our renderer
|
||||
// interprets into making all the previous lines be outside the
|
||||
// current viewport.
|
||||
if (usingExistingBuffer)
|
||||
if (_inheritCursor)
|
||||
{
|
||||
flags |= PSEUDOCONSOLE_INHERIT_CURSOR;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
const winrt::guid& guid,
|
||||
const winrt::guid& profileGuid);
|
||||
|
||||
Windows::Foundation::Collections::ValueSet GetDeftermSettings();
|
||||
|
||||
WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler);
|
||||
|
||||
private:
|
||||
@@ -90,6 +92,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
std::wstring _u16Str{};
|
||||
std::array<char, 4096> _buffer{};
|
||||
bool _passthroughMode{};
|
||||
bool _inheritCursor{ false };
|
||||
bool _reloadEnvironmentVariables{};
|
||||
guid _profileGuid{};
|
||||
|
||||
|
||||
@@ -33,5 +33,7 @@ namespace Microsoft.Terminal.TerminalConnection
|
||||
UInt32 columns,
|
||||
Guid guid,
|
||||
Guid profileGuid);
|
||||
|
||||
Windows.Foundation.Collections.ValueSet GetDeftermSettings();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -78,7 +78,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
ControlCore::ControlCore(Control::IControlSettings settings,
|
||||
Control::IControlAppearance unfocusedAppearance,
|
||||
TerminalConnection::ITerminalConnection connection) :
|
||||
_connection{ connection },
|
||||
_desiredFont{ DEFAULT_FONT_FACE, 0, DEFAULT_FONT_WEIGHT, DEFAULT_FONT_SIZE, CP_UTF8 },
|
||||
_actualFont{ DEFAULT_FONT_FACE, 0, DEFAULT_FONT_WEIGHT, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false }
|
||||
{
|
||||
@@ -86,13 +85,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
_terminal = std::make_shared<::Microsoft::Terminal::Core::Terminal>();
|
||||
|
||||
// Subscribe to the connection's disconnected event and call our connection closed handlers.
|
||||
_connectionStateChangedRevoker = _connection.StateChanged(winrt::auto_revoke, [this](auto&& /*s*/, auto&& /*v*/) {
|
||||
_ConnectionStateChangedHandlers(*this, nullptr);
|
||||
});
|
||||
|
||||
// This event is explicitly revoked in the destructor: does not need weak_ref
|
||||
_connectionOutputEventToken = _connection.TerminalOutput({ this, &ControlCore::_connectionOutputHandler });
|
||||
_setConnection(connection);
|
||||
|
||||
_terminal->SetWriteInputCallback([this](std::wstring_view wstr) {
|
||||
_sendInputToConnection(wstr);
|
||||
@@ -364,6 +357,27 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return true;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Setup our event handlers for this connection. If we've currently got a
|
||||
// connection, then this'll revoke the existing connection's handlers.
|
||||
void ControlCore::_setConnection(const TerminalConnection::ITerminalConnection& connection)
|
||||
{
|
||||
if (_connection)
|
||||
{
|
||||
_connectionOutputEventRevoker.revoke();
|
||||
}
|
||||
|
||||
// Subscribe to the connection's disconnected event and call our connection closed handlers.
|
||||
_connectionStateChangedRevoker = connection.StateChanged(winrt::auto_revoke, [this](auto&& /*s*/, auto&& /*v*/) {
|
||||
_ConnectionStateChangedHandlers(*this, nullptr);
|
||||
});
|
||||
|
||||
_connection = connection;
|
||||
|
||||
// This event is explicitly revoked in the destructor: does not need weak_ref
|
||||
_connectionOutputEventRevoker = _connection.TerminalOutput(winrt::auto_revoke, { this, &ControlCore::_connectionOutputHandler });
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Tell the renderer to start painting.
|
||||
// - !! IMPORTANT !! Make sure that we've attached our swap chain to an
|
||||
@@ -425,11 +439,43 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ch == Enter)
|
||||
// If we have a connection info with which to try and re-create the
|
||||
// connection, then let's try doing that on Enter
|
||||
if (_ConnectionInfo != nullptr)
|
||||
{
|
||||
_connection.Close();
|
||||
_connection.Start();
|
||||
return true;
|
||||
if (ch == Enter)
|
||||
{
|
||||
// Manually update the startingDirectory. If we had a CWD set
|
||||
// by the client, then let's try and use that as the CWD for
|
||||
// a restart, so it's more "seamless"
|
||||
_ConnectionInfo.Settings().Insert(L"startingDirectory", Windows::Foundation::PropertyValue::CreateString(WorkingDirectory()));
|
||||
// pass in the magic "inheritCursor" setting to the
|
||||
// connection's settings. This'll cause conpty to restart
|
||||
// the connection at the current place in the buffer.
|
||||
_ConnectionInfo.Settings().Insert(L"inheritCursor", Windows::Foundation::PropertyValue::CreateBoolean(true));
|
||||
auto c = TerminalConnection::ConnectionInformation::CreateConnection(_ConnectionInfo);
|
||||
|
||||
// Get our current size in rows/cols, and hook them up to
|
||||
// this connection too.
|
||||
{
|
||||
const auto vp = _terminal->GetViewport();
|
||||
const auto width = vp.Width();
|
||||
const auto height = vp.Height();
|
||||
|
||||
c.Resize(height, width);
|
||||
}
|
||||
|
||||
// Window owner too.
|
||||
if (auto conpty{ c.try_as<TerminalConnection::ConptyConnection>() })
|
||||
{
|
||||
conpty.ReparentWindow(_owningHwnd);
|
||||
}
|
||||
|
||||
_connection.Close();
|
||||
_setConnection(c);
|
||||
_connection.Start();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1541,7 +1587,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_midiAudio.BeginSkip();
|
||||
|
||||
// Stop accepting new output and state changes before we disconnect everything.
|
||||
_connection.TerminalOutput(_connectionOutputEventToken);
|
||||
_connectionOutputEventRevoker.revoke();
|
||||
_connectionStateChangedRevoker.revoke();
|
||||
_connection.Close();
|
||||
}
|
||||
|
||||
@@ -221,6 +221,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
RUNTIME_SETTING(double, Opacity, _settings->Opacity());
|
||||
RUNTIME_SETTING(bool, UseAcrylic, _settings->UseAcrylic());
|
||||
WINRT_PROPERTY(TerminalConnection::ConnectionInformation, ConnectionInfo, nullptr);
|
||||
|
||||
// -------------------------------- WinRT Events ---------------------------------
|
||||
// clang-format off
|
||||
@@ -256,7 +257,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
bool _closing{ false };
|
||||
|
||||
TerminalConnection::ITerminalConnection _connection{ nullptr };
|
||||
event_token _connectionOutputEventToken;
|
||||
TerminalConnection::ITerminalConnection::TerminalOutput_revoker _connectionOutputEventRevoker;
|
||||
TerminalConnection::ITerminalConnection::StateChanged_revoker _connectionStateChangedRevoker;
|
||||
|
||||
winrt::com_ptr<ControlSettings> _settings{ nullptr };
|
||||
@@ -348,6 +349,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
bool _isBackgroundTransparent();
|
||||
void _focusChanged(bool focused);
|
||||
|
||||
void _setConnection(const TerminalConnection::ITerminalConnection& connection);
|
||||
|
||||
inline bool _IsClosing() const noexcept
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
|
||||
@@ -68,6 +68,8 @@ namespace Microsoft.Terminal.Control
|
||||
Single actualHeight,
|
||||
Single compositionScale);
|
||||
|
||||
Microsoft.Terminal.TerminalConnection.ConnectionInformation ConnectionInfo{ get; set; };
|
||||
|
||||
void UpdateSettings(IControlSettings settings, IControlAppearance appearance);
|
||||
void ApplyAppearance(Boolean focused);
|
||||
|
||||
|
||||
@@ -3321,6 +3321,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_core.ColorSelection(fg, bg, matchMode);
|
||||
}
|
||||
|
||||
TerminalConnection::ConnectionInformation TermControl::ConnectionInfo()
|
||||
{
|
||||
return _core.ConnectionInfo();
|
||||
}
|
||||
void TermControl::ConnectionInfo(const TerminalConnection::ConnectionInformation& info)
|
||||
{
|
||||
_core.ConnectionInfo(info);
|
||||
}
|
||||
|
||||
void TermControl::_contextMenuHandler(IInspectable /*sender*/,
|
||||
Control::ContextMenuRequestedEventArgs args)
|
||||
{
|
||||
|
||||
@@ -35,6 +35,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
winrt::fire_and_forget UpdateControlSettings(Control::IControlSettings settings, Control::IControlAppearance unfocusedAppearance);
|
||||
IControlSettings Settings() const;
|
||||
|
||||
TerminalConnection::ConnectionInformation ConnectionInfo();
|
||||
void ConnectionInfo(const TerminalConnection::ConnectionInformation& info);
|
||||
|
||||
uint64_t ContentId() const;
|
||||
|
||||
hstring GetProfileName() const;
|
||||
|
||||
@@ -34,6 +34,8 @@ namespace Microsoft.Terminal.Control
|
||||
void UpdateControlSettings(IControlSettings settings);
|
||||
void UpdateControlSettings(IControlSettings settings, IControlAppearance unfocusedAppearance);
|
||||
|
||||
Microsoft.Terminal.TerminalConnection.ConnectionInformation ConnectionInfo { get; set; };
|
||||
|
||||
UInt64 ContentId{ get; };
|
||||
|
||||
Microsoft.Terminal.Control.IControlSettings Settings { get; };
|
||||
|
||||
Reference in New Issue
Block a user