Skip to content

Commit e1be2f4

Browse files
authored
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 ✅
1 parent e1b28e7 commit e1be2f4

File tree

2 files changed

+39
-11
lines changed

2 files changed

+39
-11
lines changed

src/cascadia/WindowsTerminal/WindowEmperor.cpp

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,10 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow)
354354
}
355355

356356
// If we created no windows, e.g. because the args are "/?" we can just exit now.
357-
_postQuitMessageIfNeeded();
357+
if (_windows.empty())
358+
{
359+
_postQuitMessageIfNeeded();
360+
}
358361
}
359362

360363
// ALWAYS change the _real_ CWD of the Terminal to system32,
@@ -735,9 +738,30 @@ void WindowEmperor::_createMessageWindow(const wchar_t* className)
735738
StringCchCopy(_notificationIcon.szTip, ARRAYSIZE(_notificationIcon.szTip), appNameLoc.c_str());
736739
}
737740

741+
// Counterpart to _postQuitMessageIfNeeded:
742+
// If it returns true, don't close that last window, if any.
743+
// This ensures we persist the last window.
744+
bool WindowEmperor::_shouldSkipClosingWindows() const
745+
{
746+
const auto globalSettings = _app.Logic().Settings().GlobalSettings();
747+
const size_t windowLimit = globalSettings.ShouldUsePersistedLayout() ? 1 : 0;
748+
return _windows.size() <= windowLimit;
749+
}
750+
751+
// Posts a WM_QUIT as soon as we have no reason to exist anymore.
752+
// That basically means no windows [^1] and no message boxes.
753+
//
754+
// [^1] Unless:
755+
// * We've been asked to persist the last remaining window
756+
// in which case we exit with 1 remaining window.
757+
// * We're allowed to be headless
758+
// in which case we never exit.
738759
void WindowEmperor::_postQuitMessageIfNeeded() const
739760
{
740-
if (_messageBoxCount <= 0 && _windows.empty() && !_app.Logic().Settings().GlobalSettings().AllowHeadless())
761+
const auto globalSettings = _app.Logic().Settings().GlobalSettings();
762+
const size_t windowLimit = globalSettings.ShouldUsePersistedLayout() ? 1 : 0;
763+
764+
if (_messageBoxCount <= 0 && _windows.size() <= windowLimit && !globalSettings.AllowHeadless())
741765
{
742766
PostQuitMessage(0);
743767
}
@@ -771,17 +795,20 @@ LRESULT WindowEmperor::_messageHandler(HWND window, UINT const message, WPARAM c
771795
{
772796
case WM_CLOSE_TERMINAL_WINDOW:
773797
{
774-
const auto host = reinterpret_cast<AppHost*>(lParam);
775-
auto it = _windows.begin();
776-
const auto end = _windows.end();
777-
778-
for (; it != end; ++it)
798+
if (!_shouldSkipClosingWindows())
779799
{
780-
if (host == it->get())
800+
const auto host = reinterpret_cast<AppHost*>(lParam);
801+
auto it = _windows.begin();
802+
const auto end = _windows.end();
803+
804+
for (; it != end; ++it)
781805
{
782-
host->Close();
783-
_windows.erase(it);
784-
break;
806+
if (host == it->get())
807+
{
808+
host->Close();
809+
_windows.erase(it);
810+
break;
811+
}
785812
}
786813
}
787814

src/cascadia/WindowsTerminal/WindowEmperor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class WindowEmperor
5555
safe_void_coroutine _dispatchCommandlineCurrentDesktop(winrt::TerminalApp::CommandlineArgs args);
5656
LRESULT _messageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam) noexcept;
5757
void _createMessageWindow(const wchar_t* className);
58+
bool _shouldSkipClosingWindows() const;
5859
void _postQuitMessageIfNeeded() const;
5960
safe_void_coroutine _showMessageBox(winrt::hstring message, bool error);
6061
void _notificationAreaMenuRequested(WPARAM wParam);

0 commit comments

Comments
 (0)