Fix persistence of the last closed window (#18623)

Does what it says on the tin.

Closes #18525

## Validation Steps Performed
* Enable persistence
* Close the last window
* Persisted 
This commit is contained in:
Leonard Hecker 2025-02-26 11:05:59 -08:00 committed by GitHub
parent e1b28e72b3
commit e1be2f4c73
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 39 additions and 11 deletions

View File

@ -354,7 +354,10 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow)
}
// If we created no windows, e.g. because the args are "/?" we can just exit now.
_postQuitMessageIfNeeded();
if (_windows.empty())
{
_postQuitMessageIfNeeded();
}
}
// ALWAYS change the _real_ CWD of the Terminal to system32,
@ -735,9 +738,30 @@ 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.
void WindowEmperor::_postQuitMessageIfNeeded() const
{
if (_messageBoxCount <= 0 && _windows.empty() && !_app.Logic().Settings().GlobalSettings().AllowHeadless())
const auto globalSettings = _app.Logic().Settings().GlobalSettings();
const size_t windowLimit = globalSettings.ShouldUsePersistedLayout() ? 1 : 0;
if (_messageBoxCount <= 0 && _windows.size() <= windowLimit && !globalSettings.AllowHeadless())
{
PostQuitMessage(0);
}
@ -771,17 +795,20 @@ LRESULT WindowEmperor::_messageHandler(HWND window, UINT const message, WPARAM c
{
case WM_CLOSE_TERMINAL_WINDOW:
{
const auto host = reinterpret_cast<AppHost*>(lParam);
auto it = _windows.begin();
const auto end = _windows.end();
for (; it != end; ++it)
if (!_shouldSkipClosingWindows())
{
if (host == it->get())
const auto host = reinterpret_cast<AppHost*>(lParam);
auto it = _windows.begin();
const auto end = _windows.end();
for (; it != end; ++it)
{
host->Close();
_windows.erase(it);
break;
if (host == it->get())
{
host->Close();
_windows.erase(it);
break;
}
}
}

View File

@ -55,6 +55,7 @@ private:
safe_void_coroutine _dispatchCommandlineCurrentDesktop(winrt::TerminalApp::CommandlineArgs args);
LRESULT _messageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam) noexcept;
void _createMessageWindow(const wchar_t* className);
bool _shouldSkipClosingWindows() const;
void _postQuitMessageIfNeeded() const;
safe_void_coroutine _showMessageBox(winrt::hstring message, bool error);
void _notificationAreaMenuRequested(WPARAM wParam);