From 2090584f0232645087bfa1bfd370c267eae20d7a Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Fri, 21 May 2021 15:01:09 -0700 Subject: [PATCH] This makes the monarch always be an inbound listener for console connections. --- src/cascadia/TerminalApp/AppLogic.cpp | 14 +++++- src/cascadia/TerminalApp/AppLogic.h | 2 + src/cascadia/TerminalApp/AppLogic.idl | 2 + src/cascadia/TerminalApp/TerminalPage.cpp | 52 ++++++++++++++------ src/cascadia/TerminalApp/TerminalPage.h | 2 + src/cascadia/TerminalControl/TermControl.cpp | 5 +- src/cascadia/WindowsTerminal/AppHost.cpp | 8 +++ src/cascadia/WindowsTerminal/AppHost.h | 1 + 8 files changed, 69 insertions(+), 17 deletions(-) diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index 4c9e7612bb2..cd46e446d8f 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -1206,13 +1206,25 @@ namespace winrt::TerminalApp::implementation // in and be routed to an event with no handlers or a non-ready Page. if (_appArgs.IsHandoffListener()) { - _root->SetInboundListener(); + SetInboundListener(); } } return result; } + // Method Description: + // - Triggers the setup of the listener for incoming console connections + // from the operating system. + // Arguments: + // - + // Return Value: + // - + void AppLogic::SetInboundListener() + { + _root->SetInboundListener(); + } + // Method Description: // - Parse the provided commandline arguments into actions, and try to // perform them immediately. diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index c86b543005b..da19d1e314e 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -79,6 +79,8 @@ namespace winrt::TerminalApp::implementation Windows::UI::Xaml::UIElement GetRoot() noexcept; + void SetInboundListener(); + hstring Title(); void TitlebarClicked(); bool OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down); diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl index fec67c970c3..92bd0961319 100644 --- a/src/cascadia/TerminalApp/AppLogic.idl +++ b/src/cascadia/TerminalApp/AppLogic.idl @@ -42,6 +42,8 @@ namespace TerminalApp void LoadSettings(); Windows.UI.Xaml.UIElement GetRoot(); + void SetInboundListener(); + String Title { get; }; Boolean FocusMode { get; }; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 7f728e5ad94..ee575b72bc3 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -325,23 +325,38 @@ namespace winrt::TerminalApp::implementation // This MUST be done after we've registered the event listener for the new connections // or the COM server might start receiving requests on another thread and dispatch // them to nowhere. - if (_shouldStartInboundListener) + _StartInboundListener(); + } + } + + // Routine Description: + // - Will start the listener for inbound console handoffs if we have already determined + // that we should do so. + // NOTE: Must be after TerminalPage::_OnNewConnection has been connected up. + // Arguments: + // - - Looks at _shouldStartInboundListener + // Return Value: + // - - May fail fast if setup fails as that would leave us in a weird state. + void TerminalPage::_StartInboundListener() + { + if (_shouldStartInboundListener) + { + _shouldStartInboundListener = false; + + try { - try - { - winrt::Microsoft::Terminal::TerminalConnection::ConptyConnection::StartInboundListener(); - } - // If we failed to start the listener, it will throw. - // We should fail fast here or the Terminal will be in a very strange state. - // We only start the listener if the Terminal was started with the COM server - // `-Embedding` flag and we make no tabs as a result. - // Therefore, if the listener cannot start itself up to make that tab with - // the inbound connection that caused the COM activation in the first place... - // we would be left with an empty terminal frame with no tabs. - // Instead, crash out so COM sees the server die and things unwind - // without a weird empty frame window. - CATCH_FAIL_FAST() + winrt::Microsoft::Terminal::TerminalConnection::ConptyConnection::StartInboundListener(); } + // If we failed to start the listener, it will throw. + // We should fail fast here or the Terminal will be in a very strange state. + // We only start the listener if the Terminal was started with the COM server + // `-Embedding` flag and we make no tabs as a result. + // Therefore, if the listener cannot start itself up to make that tab with + // the inbound connection that caused the COM activation in the first place... + // we would be left with an empty terminal frame with no tabs. + // Instead, crash out so COM sees the server die and things unwind + // without a weird empty frame window. + CATCH_FAIL_FAST() } } @@ -1989,6 +2004,13 @@ namespace winrt::TerminalApp::implementation void TerminalPage::SetInboundListener() { _shouldStartInboundListener = true; + + // If the page has already passed the NotInitialized state, + // then it is ready-enough for us to just start this immediately. + if (_startupState != StartupState::NotInitialized) + { + _StartInboundListener(); + } } winrt::TerminalApp::IDialogPresenter TerminalPage::DialogPresenter() const diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 794fd0e1568..0c1bed61371 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -302,6 +302,8 @@ namespace winrt::TerminalApp::implementation void _SetNewTabButtonColor(const Windows::UI::Color& color, const Windows::UI::Color& accentColor); void _ClearNewTabButtonColor(); + void _StartInboundListener(); + void _CompleteInitialization(); void _FocusActiveControl(IInspectable sender, IInspectable eventArgs); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 12b19da1f05..639c52c8509 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -1664,7 +1664,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation void TermControl::_CursorPositionChanged(const IInspectable& /*sender*/, const IInspectable& /*args*/) { - _tsfTryRedrawCanvas->Run(); + if (_tsfTryRedrawCanvas) + { + _tsfTryRedrawCanvas->Run(); + } } hstring TermControl::Title() diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 6e4e24bdaa8..e053425cb8d 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -640,6 +640,14 @@ void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*s const winrt::Windows::Foundation::IInspectable& /*args*/) { _setupGlobalHotkeys(); + + // The monarch is just going to be THE listener for inbound connections. + _listenForInboundConnections(); +} + +void AppHost::_listenForInboundConnections() +{ + _logic.SetInboundListener(); } winrt::fire_and_forget AppHost::_setupGlobalHotkeys() diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 712b757ef52..4adac9a8056 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -74,6 +74,7 @@ class AppHost bool _LazyLoadDesktopManager(); + void _listenForInboundConnections(); winrt::fire_and_forget _setupGlobalHotkeys(); winrt::fire_and_forget _createNewTerminalWindow(winrt::Microsoft::Terminal::Settings::Model::GlobalSummonArgs args); void _HandleSettingsChanged(const winrt::Windows::Foundation::IInspectable& sender,