Compare commits

...

32 Commits

Author SHA1 Message Date
Mike Griese
2aad178aae Merge remote-tracking branch 'origin/main' into dev/migrie/b/cxn-restarting-attempt-1-backport 2023-04-17 10:30:54 -05:00
Mike Griese
4291e88c04 Merge remote-tracking branch 'origin/main' into dev/migrie/b/cxn-restarting-attempt-1-backport 2023-04-06 13:57:56 -05:00
Mike Griese
13b1516183 Merge remote-tracking branch 'origin/main' into dev/migrie/b/cxn-restarting-attempt-1-backport 2023-03-02 16:13:25 -06:00
Mike Griese
b2f9ee0610 pr nits 2023-02-05 15:46:13 -06:00
Mike Griese
c15a520235 Merge remote-tracking branch 'origin/main' into dev/migrie/b/cxn-restarting-attempt-1-backport 2023-02-05 15:41:34 -06:00
Mike Griese
871f60c3b8 good nits 2023-01-29 06:46:42 -06:00
Mike Griese
75c9657603 Merge branch 'main' into dev/migrie/b/cxn-restarting-attempt-1-backport 2023-01-29 06:42:29 -06:00
Mike Griese
c814d9e02b Merge remote-tracking branch 'origin/main' into dev/migrie/b/cxn-restarting-attempt-1-backport 2023-01-19 11:13:05 -06:00
Mike Griese
4ac6bf5784 oh no I added changes before I committed the merge. Butts 2023-01-19 11:12:33 -06:00
Mike Griese
b0aae0796b spel 2022-12-13 13:38:46 -06:00
Mike Griese
beb7b1ada0 I don't even recall touching this file 2022-12-13 12:15:19 -06:00
Mike Griese
ca8c7943ee yea of course I didn't save 2022-12-13 12:13:00 -06:00
Mike Griese
b0c3e362c0 cleanup for review 2022-12-13 12:11:05 -06:00
Mike Griese
ddb8042b38 After all, why shouldn't debug tap connections be restartable? 2022-12-13 11:29:36 -06:00
Mike Griese
5bcf0fc7bb This works for defterm connections 2022-12-13 11:20:41 -06:00
Mike Griese
24c745f8b7 Okay, the control can restart a connection now 2022-12-13 10:35:20 -06:00
Mike Griese
08c603356f Merge remote-tracking branch 'origin/main' into dev/migrie/b/cxn-restarting-attempt-1-backport 2022-12-12 10:22:04 -06:00
Mike Griese
9cc8d61b07 Merge remote-tracking branch 'origin/main' into dev/migrie/b/cxn-restarting-attempt-1-backport 2022-12-09 11:09:47 -06:00
Mike Griese
3da6613064 this is a backport of a lot of tearout ConnectionInfo code currently in review 2022-12-06 17:31:36 -06:00
Mike Griese
7febffedc5 there's not a better way to name that message 2022-12-06 13:54:27 -06:00
Mike Griese
0c190c27b9 Merge remote-tracking branch 'origin/main' into ctrl-d-support 2022-12-06 13:50:39 -06:00
Steve Otteson
52c59ed594 Merge branch 'main' into ctrl-d-support 2022-11-11 14:45:21 -08:00
Steve Otteson
899f00910e Update message to use Ctrl+D instead of ^D 2022-11-11 14:25:05 -08:00
Steve Otteson
62888a5a0f Add comment to help with localization. 2022-09-27 13:42:27 -07:00
Steve Otteson
82b687682f Fix analysis error 2022-09-23 14:53:14 -07:00
Steve Otteson
ec7dfc5525 Keep track of rows/cols in connection even when disconnected 2022-09-23 14:17:55 -07:00
Steve Otteson
27096e619f Add comment to line setting PSEUDOCONSOLE_INHERIT_CURSOR 2022-09-23 12:33:06 -07:00
Steve Otteson
092957f937 Add support for restarting terminal with Enter 2022-09-23 11:28:52 -07:00
Steve Otteson
d902eb8477 Fix formatting issues 2022-09-22 10:14:59 -07:00
Steve Otteson
6de50b036a Fix a couple of typos from the last cleanup 2022-09-22 10:06:09 -07:00
Steve Otteson
560629114c Implement ctrl+D as an event that Pane watches 2022-09-22 02:18:46 -07:00
Steve Otteson
21cf69d741 Add support to close a failed pain with ctrl+D 2022-09-22 00:32:33 -07:00
15 changed files with 227 additions and 103 deletions

View File

@@ -157,6 +157,7 @@ ptstr
QUERYENDSESSION
rcx
REGCLS
requal
RETURNCMD
rfind
RLO

View File

@@ -13,6 +13,7 @@ autoexec
backplating
bitmaps
BOMs
combase
COMPUTERNAME
CPLs
cpptools

View File

@@ -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);

View File

@@ -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);

View File

@@ -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());

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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{};

View File

@@ -33,5 +33,7 @@ namespace Microsoft.Terminal.TerminalConnection
UInt32 columns,
Guid guid,
Guid profileGuid);
Windows.Foundation.Collections.ValueSet GetDeftermSettings();
};
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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; };