From 0fc4bdcf3af72cd90d1f5eec77fd6529c7f38de9 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 20 Apr 2022 16:55:55 -0500 Subject: [PATCH 1/9] This fixes #11561 Cloak the window until XAML is ready to go --- src/cascadia/TerminalApp/AppLogic.h | 1 + src/cascadia/TerminalApp/AppLogic.idl | 1 + src/cascadia/TerminalApp/TerminalPage.cpp | 13 ++++++++++++- src/cascadia/TerminalApp/TerminalPage.h | 4 ++-- src/cascadia/TerminalApp/TerminalPage.idl | 2 +- src/cascadia/WindowsTerminal/AppHost.cpp | 19 +++++++++++++++++++ src/cascadia/WindowsTerminal/AppHost.h | 4 ++++ 7 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index 1d43f113ba5..b0e8ed8cc05 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -198,6 +198,7 @@ namespace winrt::TerminalApp::implementation FORWARDED_TYPED_EVENT(FullscreenChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, FullscreenChanged); FORWARDED_TYPED_EVENT(ChangeMaximizeRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, ChangeMaximizeRequested); FORWARDED_TYPED_EVENT(AlwaysOnTopChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, AlwaysOnTopChanged); + FORWARDED_TYPED_EVENT(Initialized, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, Initialized); FORWARDED_TYPED_EVENT(RaiseVisualBell, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, RaiseVisualBell); FORWARDED_TYPED_EVENT(SetTaskbarProgress, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, SetTaskbarProgress); FORWARDED_TYPED_EVENT(IdentifyWindowsRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IdentifyWindowsRequested); diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl index 469bf27affd..6405875765d 100644 --- a/src/cascadia/TerminalApp/AppLogic.idl +++ b/src/cascadia/TerminalApp/AppLogic.idl @@ -121,6 +121,7 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler FullscreenChanged; event Windows.Foundation.TypedEventHandler ChangeMaximizeRequested; event Windows.Foundation.TypedEventHandler AlwaysOnTopChanged; + event Windows.Foundation.TypedEventHandler Initialized; event Windows.Foundation.TypedEventHandler RaiseVisualBell; event Windows.Foundation.TypedEventHandler SetTaskbarProgress; event Windows.Foundation.TypedEventHandler IdentifyWindowsRequested; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 401f3b41b98..177b9a01596 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -658,7 +658,7 @@ namespace winrt::TerminalApp::implementation // - // Return Value: // - - void TerminalPage::_CompleteInitialization() + winrt::fire_and_forget TerminalPage::_CompleteInitialization() { _startupState = StartupState::Initialized; @@ -678,9 +678,20 @@ namespace winrt::TerminalApp::implementation if (_tabs.Size() == 0 && !(_shouldStartInboundListener || _isEmbeddingInboundListener)) { _LastTabClosedHandlers(*this, nullptr); + co_return; } else { + // Capture calling context. + winrt::apartment_context ui_thread; + + // TODO! Capture a weak ref for gods sake + + // Switch to the BG thread - + co_await winrt::resume_background(); + + co_await wil::resume_foreground(Dispatcher(), CoreDispatcherPriority::Low); + _InitializedHandlers(*this, nullptr); } } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index f1be2b6177d..c0ef3f88e76 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -146,7 +146,7 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(AlwaysOnTopChanged, IInspectable, IInspectable); TYPED_EVENT(RaiseVisualBell, IInspectable, IInspectable); TYPED_EVENT(SetTaskbarProgress, IInspectable, IInspectable); - TYPED_EVENT(Initialized, IInspectable, winrt::Windows::UI::Xaml::RoutedEventArgs); + TYPED_EVENT(Initialized, IInspectable, IInspectable); TYPED_EVENT(IdentifyWindowsRequested, IInspectable, IInspectable); TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs); TYPED_EVENT(IsQuakeWindowChanged, IInspectable, IInspectable); @@ -385,7 +385,7 @@ namespace winrt::TerminalApp::implementation void _StartInboundListener(); - void _CompleteInitialization(); + winrt::fire_and_forget _CompleteInitialization(); void _FocusActiveControl(IInspectable sender, IInspectable eventArgs); diff --git a/src/cascadia/TerminalApp/TerminalPage.idl b/src/cascadia/TerminalApp/TerminalPage.idl index 979483d0ad8..84cc453568d 100644 --- a/src/cascadia/TerminalApp/TerminalPage.idl +++ b/src/cascadia/TerminalApp/TerminalPage.idl @@ -51,7 +51,7 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler FocusModeChanged; event Windows.Foundation.TypedEventHandler FullscreenChanged; event Windows.Foundation.TypedEventHandler AlwaysOnTopChanged; - event Windows.Foundation.TypedEventHandler Initialized; + event Windows.Foundation.TypedEventHandler Initialized; event Windows.Foundation.TypedEventHandler SetTaskbarProgress; event Windows.Foundation.TypedEventHandler IdentifyWindowsRequested; event Windows.Foundation.TypedEventHandler RenameWindowRequested; diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 929ee07838e..0c4dbc005ba 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -377,6 +377,7 @@ void AppHost::Initialize() _revokers.FullscreenChanged = _logic.FullscreenChanged(winrt::auto_revoke, { this, &AppHost::_FullscreenChanged }); _revokers.FocusModeChanged = _logic.FocusModeChanged(winrt::auto_revoke, { this, &AppHost::_FocusModeChanged }); _revokers.AlwaysOnTopChanged = _logic.AlwaysOnTopChanged(winrt::auto_revoke, { this, &AppHost::_AlwaysOnTopChanged }); + _revokers.Initialized = _logic.Initialized(winrt::auto_revoke, { this, &AppHost::_AppInitializedHandler }); _revokers.RaiseVisualBell = _logic.RaiseVisualBell(winrt::auto_revoke, { this, &AppHost::_RaiseVisualBell }); _revokers.SystemMenuChangeRequested = _logic.SystemMenuChangeRequested(winrt::auto_revoke, { this, &AppHost::_SystemMenuChangeRequested }); _revokers.ChangeMaximizeRequested = _logic.ChangeMaximizeRequested(winrt::auto_revoke, { this, &AppHost::_ChangeMaximizeRequested }); @@ -533,6 +534,14 @@ LaunchPosition AppHost::_GetWindowLaunchPosition() // - None void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode& launchMode) { + BOOL fCloak = TRUE; + auto result = DwmSetWindowAttribute(hwnd, + DWMWA_CLOAK, + &fCloak, + sizeof(fCloak)); + result; + LOG_IF_FAILED(result); + launchMode = _logic.GetLaunchMode(); // Acquire the actual initial position @@ -1547,3 +1556,13 @@ void AppHost::_CloseRequested(const winrt::Windows::Foundation::IInspectable& /* const auto pos = _GetWindowLaunchPosition(); _logic.CloseWindow(pos); } + +void AppHost::_AppInitializedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/, + const winrt::Windows::Foundation::IInspectable& /*arg*/) +{ + BOOL fCloak = FALSE; + DwmSetWindowAttribute(_window->GetHandle(), + DWMWA_CLOAK, + &fCloak, + sizeof(fCloak)); +} diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index c4c15555b8d..2b47ee43966 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -52,6 +52,9 @@ class AppHost const winrt::Windows::Foundation::IInspectable& arg); void _AlwaysOnTopChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& arg); + void _AppInitializedHandler(const winrt::Windows::Foundation::IInspectable& sender, + const winrt::Windows::Foundation::IInspectable& arg); + void _RaiseVisualBell(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& arg); void _WindowMouseWheeled(const til::point coord, const int32_t delta); @@ -144,6 +147,7 @@ class AppHost winrt::TerminalApp::AppLogic::FullscreenChanged_revoker FullscreenChanged; winrt::TerminalApp::AppLogic::FocusModeChanged_revoker FocusModeChanged; winrt::TerminalApp::AppLogic::AlwaysOnTopChanged_revoker AlwaysOnTopChanged; + winrt::TerminalApp::AppLogic::Initialized_revoker Initialized; winrt::TerminalApp::AppLogic::RaiseVisualBell_revoker RaiseVisualBell; winrt::TerminalApp::AppLogic::SystemMenuChangeRequested_revoker SystemMenuChangeRequested; winrt::TerminalApp::AppLogic::ChangeMaximizeRequested_revoker ChangeMaximizeRequested; From abb3549df9a44d76e7c9ffe32302113579b17a84 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 25 Apr 2022 10:24:09 -0500 Subject: [PATCH 2/9] comments, gratuitous comments --- src/cascadia/TerminalApp/TerminalPage.cpp | 33 ++++++++++++++++++++--- src/cascadia/WindowsTerminal/AppHost.cpp | 26 +++++++++--------- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 177b9a01596..9528faa8cf7 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -682,17 +682,44 @@ namespace winrt::TerminalApp::implementation } else { + // GH#11561: When we start up, our window is initially just a frame + // with a transparent content area. We're gonna do all this startup + // init on the UI thread, so the UI won't actually paint till it's + // all done. This results in a few frames where the frame is + // visible, before the page paints for the first time, before any + // tabs appears, etc. + // + // To mitigate this, we're gonna wait for the UI thread to finish + // everything it's gotta do for the initial init, and _then_ fire + // our Initialized event. By waiting for everything else to finish + // (CoreDispatcherPriority::Low), we let all the tabs and panes + // actually get created. In the window layer, we're gonna cloak the + // window till this event is fired, so we don't actually see this + // frame until we're actually all ready to go. + // + // This will result in the window seemingly not loading as fast, but + // it will actually take exactly the same amount of time before it's + // usable. + // + // We also experimented with drawing a solid BG color before the + // initialization is finished. However, there are still a few frames + // after the frame is displayed before the XAML content first draws, + // so that didn't actually resolve any issues. + // Capture calling context. winrt::apartment_context ui_thread; - - // TODO! Capture a weak ref for gods sake + auto weak{ get_weak() }; // Switch to the BG thread - co_await winrt::resume_background(); + // Then enque the rest of this function for after the UI thread settles. co_await wil::resume_foreground(Dispatcher(), CoreDispatcherPriority::Low); - _InitializedHandlers(*this, nullptr); + if (auto self{ weak.get() }) + { + _InitializedHandlers(*self, nullptr); + } } } diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 0c4dbc005ba..02f520ab1af 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -534,13 +534,13 @@ LaunchPosition AppHost::_GetWindowLaunchPosition() // - None void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode& launchMode) { - BOOL fCloak = TRUE; - auto result = DwmSetWindowAttribute(hwnd, - DWMWA_CLOAK, - &fCloak, - sizeof(fCloak)); - result; - LOG_IF_FAILED(result); + // GH#11561: Hide the window until we're totallly done being initialized. + // More commentary in TerminalPage::_CompleteInitialization + BOOL cloak = TRUE; + LOG_IF_FAILED(DwmSetWindowAttribute(hwnd, + DWMWA_CLOAK, + &cloak, + sizeof(cloak))); launchMode = _logic.GetLaunchMode(); @@ -1560,9 +1560,11 @@ void AppHost::_CloseRequested(const winrt::Windows::Foundation::IInspectable& /* void AppHost::_AppInitializedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*arg*/) { - BOOL fCloak = FALSE; - DwmSetWindowAttribute(_window->GetHandle(), - DWMWA_CLOAK, - &fCloak, - sizeof(fCloak)); + // GH#11561: We're totallly done being initialized. Uncloak the window, making it visible. + // More commentary in TerminalPage::_CompleteInitialization + BOOL cloak = FALSE; + LOG_IF_FAILED(DwmSetWindowAttribute(_window->GetHandle(), + DWMWA_CLOAK, + &cloak, + sizeof(cloak))); } From d5cab5360fce333be1a43ad877048a1a8df3dec6 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 25 Apr 2022 10:28:28 -0500 Subject: [PATCH 3/9] should just call this 'win32_api_surface.txt --- .github/actions/spelling/allow/apis.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/spelling/allow/apis.txt b/.github/actions/spelling/allow/apis.txt index ad2ce887717..8a1cf514cd7 100644 --- a/.github/actions/spelling/allow/apis.txt +++ b/.github/actions/spelling/allow/apis.txt @@ -30,6 +30,7 @@ DERR dlldata DONTADDTORECENT DWORDLONG +DWMWA endfor enumset environstrings From ea519476791425253cd95e3208f27a55fd4043a8 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 25 Apr 2022 10:29:40 -0500 Subject: [PATCH 4/9] ueueueueueueueueueue --- src/cascadia/TerminalApp/TerminalPage.cpp | 2 +- src/cascadia/WindowsTerminal/AppHost.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 9528faa8cf7..9db7be17a36 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -713,7 +713,7 @@ namespace winrt::TerminalApp::implementation // Switch to the BG thread - co_await winrt::resume_background(); - // Then enque the rest of this function for after the UI thread settles. + // Then enqueue the rest of this function for after the UI thread settles. co_await wil::resume_foreground(Dispatcher(), CoreDispatcherPriority::Low); if (auto self{ weak.get() }) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 02f520ab1af..4394c6b95d1 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -534,7 +534,7 @@ LaunchPosition AppHost::_GetWindowLaunchPosition() // - None void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode& launchMode) { - // GH#11561: Hide the window until we're totallly done being initialized. + // GH#11561: Hide the window until we're totally done being initialized. // More commentary in TerminalPage::_CompleteInitialization BOOL cloak = TRUE; LOG_IF_FAILED(DwmSetWindowAttribute(hwnd, @@ -1560,7 +1560,7 @@ void AppHost::_CloseRequested(const winrt::Windows::Foundation::IInspectable& /* void AppHost::_AppInitializedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*arg*/) { - // GH#11561: We're totallly done being initialized. Uncloak the window, making it visible. + // GH#11561: We're totally done being initialized. Uncloak the window, making it visible. // More commentary in TerminalPage::_CompleteInitialization BOOL cloak = FALSE; LOG_IF_FAILED(DwmSetWindowAttribute(_window->GetHandle(), From 492db5cb73dbd8c136646aba0784568fe21ad353 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 26 Apr 2022 05:24:47 -0500 Subject: [PATCH 5/9] This preserves the shwoop animation --- src/cascadia/WindowsTerminal/AppHost.cpp | 61 ++++++++++++------- src/cascadia/WindowsTerminal/AppHost.h | 6 +- src/cascadia/WindowsTerminal/IslandWindow.cpp | 14 ++--- src/cascadia/WindowsTerminal/IslandWindow.h | 4 +- 4 files changed, 50 insertions(+), 35 deletions(-) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 4394c6b95d1..d70d71865f6 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -73,8 +73,7 @@ AppHost::AppHost() noexcept : auto pfn = std::bind(&AppHost::_HandleCreateWindow, this, std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3); + std::placeholders::_2); _window->SetCreateCallback(pfn); _window->SetSnapDimensionCallback(std::bind(&winrt::TerminalApp::AppLogic::CalcSnappedDimension, @@ -518,12 +517,31 @@ LaunchPosition AppHost::_GetWindowLaunchPosition() return pos; } +// Method Description: +// - Callback for when the window is first being created (during WM_CREATE). +// Stash the proposed size for later. We'll need that once we're totally +// initialized, so that we can show the window in the right position *when we +// want to show it*. If we did the _initialResizeAndRepositionWindow work now, +// it would have no effect, because the window is not yet visible. +// Arguments: +// - hwnd: The HWND of the window we're about to create. +// - proposedRect: The location and size of the window that we're about to +// create. We'll use this rect to determine which monitor the window is about +// to appear on. +void AppHost::_HandleCreateWindow(const HWND /* hwnd */, RECT proposedRect) +{ + // GH#11561: Hide the window until we're totally done being initialized. + // More commentary in TerminalPage::_CompleteInitialization + _proposedRect = proposedRect; +} + // Method Description: // - Resize the window we're about to create to the appropriate dimensions, as -// specified in the settings. This will be called during the handling of -// WM_CREATE. We'll load the settings for the app, then get the proposed size -// of the terminal from the app. Using that proposed size, we'll resize the -// window we're creating, so that it'll match the values in the settings. +// specified in the settings. This is called once the app has finished it's +// initial setup, once we have created all the tabs, panes, etc. We'll load +// the settings for the app, then get the proposed size of the terminal from +// the app. Using that proposed size, we'll resize the window we're creating, +// so that it'll match the values in the settings. // Arguments: // - hwnd: The HWND of the window we're about to create. // - proposedRect: The location and size of the window that we're about to @@ -532,16 +550,8 @@ LaunchPosition AppHost::_GetWindowLaunchPosition() // - launchMode: A LaunchMode enum reference that indicates the launch mode // Return Value: // - None -void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode& launchMode) +void AppHost::_initialResizeAndRepositionWindow(const HWND hwnd, RECT proposedRect, LaunchMode& launchMode) { - // GH#11561: Hide the window until we're totally done being initialized. - // More commentary in TerminalPage::_CompleteInitialization - BOOL cloak = TRUE; - LOG_IF_FAILED(DwmSetWindowAttribute(hwnd, - DWMWA_CLOAK, - &cloak, - sizeof(cloak))); - launchMode = _logic.GetLaunchMode(); // Acquire the actual initial position @@ -1560,11 +1570,18 @@ void AppHost::_CloseRequested(const winrt::Windows::Foundation::IInspectable& /* void AppHost::_AppInitializedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*arg*/) { - // GH#11561: We're totally done being initialized. Uncloak the window, making it visible. - // More commentary in TerminalPage::_CompleteInitialization - BOOL cloak = FALSE; - LOG_IF_FAILED(DwmSetWindowAttribute(_window->GetHandle(), - DWMWA_CLOAK, - &cloak, - sizeof(cloak))); + // GH#11561: We're totally done being initialized. Resize the window to + // match the initial settings, and then call ShowWindow to finally make us + // visible. + + LaunchMode launchMode{}; + _initialResizeAndRepositionWindow(_window->GetHandle(), _proposedRect, launchMode); + + int nCmdShow = SW_SHOW; + if (WI_IsFlagSet(launchMode, LaunchMode::MaximizedMode)) + { + nCmdShow = SW_MAXIMIZE; + } + + ShowWindow(_window->GetHandle(), nCmdShow); } diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 2b47ee43966..20596e6299c 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -31,6 +31,7 @@ class AppHost bool _shouldCreateWindow{ false }; bool _useNonClientArea{ false }; + RECT _proposedRect{}; std::optional> _getWindowLayoutThrottler; winrt::Windows::Foundation::IAsyncAction _SaveWindowLayouts(); @@ -39,7 +40,7 @@ class AppHost void _HandleCommandlineArgs(); winrt::Microsoft::Terminal::Settings::Model::LaunchPosition _GetWindowLaunchPosition(); - void _HandleCreateWindow(const HWND hwnd, RECT proposedRect, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode); + void _HandleCreateWindow(const HWND hwnd, RECT proposedRect); void _UpdateTitleBarContent(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::UIElement& arg); void _UpdateTheme(const winrt::Windows::Foundation::IInspectable&, @@ -121,6 +122,9 @@ class AppHost const winrt::Windows::Foundation::IInspectable& args); void _HideNotificationIconRequested(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args); + + void _initialResizeAndRepositionWindow(const HWND hwnd, RECT proposedRect, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode); + std::unique_ptr _notificationIcon; winrt::event_token _ReAddNotificationIconToken; winrt::event_token _NotificationIconPressedToken; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 98e9f208893..d5e773b53ec 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -112,7 +112,7 @@ void IslandWindow::Close() // window. // Return Value: // - -void IslandWindow::SetCreateCallback(std::function pfn) noexcept +void IslandWindow::SetCreateCallback(std::function pfn) noexcept { _pfnCreateCallback = pfn; } @@ -154,19 +154,13 @@ void IslandWindow::_HandleCreateWindow(const WPARAM, const LPARAM lParam) noexce rc.right = rc.left + pcs->cx; rc.bottom = rc.top + pcs->cy; - LaunchMode launchMode = LaunchMode::DefaultMode; if (_pfnCreateCallback) { - _pfnCreateCallback(_window.get(), rc, launchMode); + _pfnCreateCallback(_window.get(), rc); } - int nCmdShow = SW_SHOW; - if (WI_IsFlagSet(launchMode, LaunchMode::MaximizedMode)) - { - nCmdShow = SW_MAXIMIZE; - } - - ShowWindow(_window.get(), nCmdShow); + // GH#11561: DO NOT call ShowWindow here. The AppHost will call ShowWindow + // once the app has completed it's initialization. UpdateWindow(_window.get()); diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index a39af64fc87..e162439a94e 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -37,7 +37,7 @@ class IslandWindow : virtual void Initialize(); - void SetCreateCallback(std::function pfn) noexcept; + void SetCreateCallback(std::function pfn) noexcept; void SetSnapDimensionCallback(std::function pfn) noexcept; void FocusModeChanged(const bool focusMode); @@ -92,7 +92,7 @@ class IslandWindow : winrt::Windows::UI::Xaml::Controls::Grid _rootGrid; wil::com_ptr _taskbar; - std::function _pfnCreateCallback; + std::function _pfnCreateCallback; std::function _pfnSnapDimensionCallback; void _HandleCreateWindow(const WPARAM wParam, const LPARAM lParam) noexcept; From 0b5d636ec567e16a94d6009c9ebf9e472665ff47 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 26 Apr 2022 05:34:25 -0500 Subject: [PATCH 6/9] some cleaner lifetime management --- src/cascadia/TerminalApp/TerminalPage.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 9db7be17a36..bf3cc78e900 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -713,12 +713,21 @@ namespace winrt::TerminalApp::implementation // Switch to the BG thread - co_await winrt::resume_background(); - // Then enqueue the rest of this function for after the UI thread settles. - co_await wil::resume_foreground(Dispatcher(), CoreDispatcherPriority::Low); + if (auto self{ weak.get() }) + { + // Then enqueue the rest of this function for after the UI thread settles. + co_await wil::resume_foreground(self->Dispatcher(), CoreDispatcherPriority::Low); + } + else + { + // We don't exist anymore? Well, we probably don't need to fire + // off an Initialized event then... + co_return; + } if (auto self{ weak.get() }) { - _InitializedHandlers(*self, nullptr); + self->_InitializedHandlers(*self, nullptr); } } } From 75d30651a5bd0cb5eedfaadd6b057000cf72bfa4 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 27 Apr 2022 10:37:34 -0500 Subject: [PATCH 7/9] fixes #9053 --- src/cascadia/TerminalApp/TerminalPage.cpp | 2 -- src/cascadia/WindowsTerminal/AppHost.cpp | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index bf3cc78e900..42ea0e3e3fc 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -706,8 +706,6 @@ namespace winrt::TerminalApp::implementation // after the frame is displayed before the XAML content first draws, // so that didn't actually resolve any issues. - // Capture calling context. - winrt::apartment_context ui_thread; auto weak{ get_weak() }; // Switch to the BG thread - diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index d70d71865f6..c334be97588 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -1577,7 +1577,7 @@ void AppHost::_AppInitializedHandler(const winrt::Windows::Foundation::IInspecta LaunchMode launchMode{}; _initialResizeAndRepositionWindow(_window->GetHandle(), _proposedRect, launchMode); - int nCmdShow = SW_SHOW; + int nCmdShow = SW_SHOWDEFAULT; if (WI_IsFlagSet(launchMode, LaunchMode::MaximizedMode)) { nCmdShow = SW_MAXIMIZE; From 4a7a8760279c6405cb998cf07811bf79405bb103 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 27 Apr 2022 11:39:30 -0500 Subject: [PATCH 8/9] srsly thanks for nothing user32 --- .github/actions/spelling/allow/apis.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/spelling/allow/apis.txt b/.github/actions/spelling/allow/apis.txt index 8a1cf514cd7..9600b825978 100644 --- a/.github/actions/spelling/allow/apis.txt +++ b/.github/actions/spelling/allow/apis.txt @@ -155,6 +155,7 @@ serializer SETVERSION SHELLEXECUTEINFOW shobjidl +SHOWDEFAULT SHOWMINIMIZED SHOWTIP SINGLEUSE From 04aaaa75e045217f98cf5b9e1b1dbaac61371a72 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 5 May 2022 06:50:21 -0500 Subject: [PATCH 9/9] nit --- src/cascadia/WindowsTerminal/IslandWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 51b3dca3ab6..a995ba437c7 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -160,7 +160,7 @@ void IslandWindow::_HandleCreateWindow(const WPARAM, const LPARAM lParam) noexce } // GH#11561: DO NOT call ShowWindow here. The AppHost will call ShowWindow - // once the app has completed it's initialization. + // once the app has completed its initialization. UpdateWindow(_window.get());