From 4de1ef73e9a8e0fb7582d60c6e1152fb9aeb1a77 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 7 Jun 2022 14:47:55 -0500 Subject: [PATCH] This makes sure we re-own the window appropriately, but defterm doesn't request focus mode. Weird. --- src/cascadia/TerminalApp/TerminalPage.cpp | 23 ++++++++++++++++++++ src/cascadia/TerminalControl/ControlCore.cpp | 21 ++++++++++++++++-- src/cascadia/TerminalControl/ControlCore.h | 8 +++---- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 46889b1db99..ea1bb14a8fb 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -69,6 +69,29 @@ namespace winrt::TerminalApp::implementation // - see GH#2988 HRESULT TerminalPage::Initialize(HWND hwnd) { + if (!_hostingHwnd.has_value()) + { + // GH#13211 - if we haven't yet set the owning hwnd, reparent all the controls now. + for (const auto& tab : _tabs) + { + if (auto terminalTab{ _GetTerminalTabImpl(tab) }) + { + terminalTab->GetRootPane()->WalkTree([&](auto&& pane) { + if (const auto& term{ pane->GetTerminalControl() }) + { + term.OwningHwnd(reinterpret_cast(hwnd)); + } + }); + } + // We don't need to worry about resetting the owning hwnd for the + // SUI here. GH#13211 only repros for a defterm connection, where + // the tab is spawned before the window is created. It's not + // possible to make a SUI tab like that, before the window is + // created. The SUI could be spawned as a part of a window restore, + // but that would still work fine. The window would be created + // before restoring previous tabs in that scenario. + } + } _hostingHwnd = hwnd; return S_OK; } diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 9d98115c912..ef0033250ff 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -267,11 +267,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto height = vp.Height(); _connection.Resize(height, width); - if (_OwningHwnd != 0) + if (_owningHwnd != 0) { if (auto conpty{ _connection.try_as() }) { - conpty.ReparentWindow(_OwningHwnd); + conpty.ReparentWindow(_owningHwnd); } } @@ -1854,4 +1854,21 @@ namespace winrt::Microsoft::Terminal::Control::implementation // transparency, or our acrylic, or our image. return Opacity() < 1.0f || UseAcrylic() || !_settings->BackgroundImage().empty() || _settings->UseBackgroundImageForWindow(); } + + uint64_t ControlCore::OwningHwnd() + { + return _owningHwnd; + } + + void ControlCore::OwningHwnd(uint64_t owner) + { + if (owner != _owningHwnd && _connection) + { + if (auto conpty{ _connection.try_as() }) + { + conpty.ReparentWindow(owner); + } + } + _owningHwnd = owner; + } } diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index b3c8afa8a98..5d270ee4f7b 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -179,10 +179,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation void WindowVisibilityChanged(const bool showOrHide); - // TODO:GH#1256 - When a tab can be torn out or otherwise reparented to - // another window, this value will need a custom setter, so that we can - // also update the connection. - WINRT_PROPERTY(uint64_t, OwningHwnd, 0); + uint64_t OwningHwnd(); + void OwningHwnd(uint64_t owner); RUNTIME_SETTING(double, Opacity, _settings->Opacity()); RUNTIME_SETTING(bool, UseAcrylic, _settings->UseAcrylic()); @@ -252,6 +250,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation double _panelHeight{ 0 }; double _compositionScale{ 0 }; + uint64_t _owningHwnd{ 0 }; + winrt::Windows::System::DispatcherQueue _dispatcher{ nullptr }; std::shared_ptr> _tsfTryRedrawCanvas; std::shared_ptr> _updatePatternLocations;