From 455dc443e7a03cf578d11911449348fab8a955f2 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Thu, 27 Feb 2025 15:49:12 +0100 Subject: [PATCH] Fix bugs introduced in #18623 --- .../WindowsTerminal/WindowEmperor.cpp | 49 +++++++++---------- src/cascadia/WindowsTerminal/WindowEmperor.h | 1 + 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/cascadia/WindowsTerminal/WindowEmperor.cpp b/src/cascadia/WindowsTerminal/WindowEmperor.cpp index 6a25256af6f..d0ab37175a7 100644 --- a/src/cascadia/WindowsTerminal/WindowEmperor.cpp +++ b/src/cascadia/WindowsTerminal/WindowEmperor.cpp @@ -246,6 +246,8 @@ void WindowEmperor::CreateNewWindow(winrt::TerminalApp::WindowRequestedArgs args auto host = std::make_shared(this, _app.Logic(), std::move(args)); host->Initialize(); + + _windowCount += 1; _windows.emplace_back(std::move(host)); } @@ -354,10 +356,7 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow) } // If we created no windows, e.g. because the args are "/?" we can just exit now. - if (_windows.empty()) - { - _postQuitMessageIfNeeded(); - } + _postQuitMessageIfNeeded(); } // ALWAYS change the _real_ CWD of the Terminal to system32, @@ -738,30 +737,14 @@ void WindowEmperor::_createMessageWindow(const wchar_t* className) StringCchCopy(_notificationIcon.szTip, ARRAYSIZE(_notificationIcon.szTip), appNameLoc.c_str()); } -// Counterpart to _postQuitMessageIfNeeded: -// If it returns true, don't close that last window, if any. -// This ensures we persist the last window. -bool WindowEmperor::_shouldSkipClosingWindows() const -{ - const auto globalSettings = _app.Logic().Settings().GlobalSettings(); - const size_t windowLimit = globalSettings.ShouldUsePersistedLayout() ? 1 : 0; - return _windows.size() <= windowLimit; -} - // Posts a WM_QUIT as soon as we have no reason to exist anymore. -// That basically means no windows [^1] and no message boxes. -// -// [^1] Unless: -// * We've been asked to persist the last remaining window -// in which case we exit with 1 remaining window. -// * We're allowed to be headless -// in which case we never exit. +// That basically means no windows and no message boxes. void WindowEmperor::_postQuitMessageIfNeeded() const { - const auto globalSettings = _app.Logic().Settings().GlobalSettings(); - const size_t windowLimit = globalSettings.ShouldUsePersistedLayout() ? 1 : 0; - - if (_messageBoxCount <= 0 && _windows.size() <= windowLimit && !globalSettings.AllowHeadless()) + if ( + _messageBoxCount <= 0 && + _windowCount <= 0 && + !_app.Logic().Settings().GlobalSettings().AllowHeadless()) { PostQuitMessage(0); } @@ -795,8 +778,20 @@ LRESULT WindowEmperor::_messageHandler(HWND window, UINT const message, WPARAM c { case WM_CLOSE_TERMINAL_WINDOW: { - if (!_shouldSkipClosingWindows()) + const auto globalSettings = _app.Logic().Settings().GlobalSettings(); + // Keep the last window in the array so that we can persist it on exit. + // We check for AllowHeadless(), as that being true prevents us from ever quitting in the first place. + // (= If we avoided closing the last window you wouldn't be able to reach a headless state.) + const auto shouldKeepWindow = + _windows.size() == 1 && + globalSettings.ShouldUsePersistedLayout() && + !globalSettings.AllowHeadless(); + + if (!shouldKeepWindow) { + // Did the window counter get out of sync? It shouldn't. + assert(_windowCount == gsl::narrow_cast(_windows.size())); + const auto host = reinterpret_cast(lParam); auto it = _windows.begin(); const auto end = _windows.end(); @@ -812,6 +807,8 @@ LRESULT WindowEmperor::_messageHandler(HWND window, UINT const message, WPARAM c } } + // Counterpart specific to CreateNewWindow(). + _windowCount -= 1; _postQuitMessageIfNeeded(); return 0; } diff --git a/src/cascadia/WindowsTerminal/WindowEmperor.h b/src/cascadia/WindowsTerminal/WindowEmperor.h index 7012a7d66ee..3024ab7a2cf 100644 --- a/src/cascadia/WindowsTerminal/WindowEmperor.h +++ b/src/cascadia/WindowsTerminal/WindowEmperor.h @@ -78,6 +78,7 @@ class WindowEmperor bool _forcePersistence = false; bool _needsPersistenceCleanup = false; std::optional _currentSystemThemeIsDark; + int32_t _windowCount = 0; int32_t _messageBoxCount = 0; #ifdef NDEBUG