From 94a2aa01007a48f2e3fde9866dfb1c09a1a58f5c Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Fri, 23 May 2025 01:02:58 +0200 Subject: [PATCH] Eagerly persist on WM_ENDSESSION (#18912) Once an application has returned from handling `WM_ENDSESSION` the OS may kill the app at any point. This means we must persist our state while inside the message handler. Closes #17179 Honestly, none. It's a race condition in the first place. (cherry picked from commit 26cd15a14b0bfc06a951c800d960336328176173) Service-Card-Id: PVTI_lADOAF3p4s4AxadtzgaZoI8 Service-Version: 1.23 --- src/cascadia/WindowsTerminal/WindowEmperor.cpp | 12 ++++++++++-- src/cascadia/WindowsTerminal/WindowEmperor.h | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/cascadia/WindowsTerminal/WindowEmperor.cpp b/src/cascadia/WindowsTerminal/WindowEmperor.cpp index 381b7f4c8e..1d274c1f82 100644 --- a/src/cascadia/WindowsTerminal/WindowEmperor.cpp +++ b/src/cascadia/WindowsTerminal/WindowEmperor.cpp @@ -897,7 +897,8 @@ LRESULT WindowEmperor::_messageHandler(HWND window, UINT const message, WPARAM c RegisterApplicationRestart(nullptr, RESTART_NO_CRASH | RESTART_NO_HANG); return TRUE; case WM_ENDSESSION: - _forcePersistence = true; + _finalizeSessionPersistence(); + _skipPersistence = true; PostQuitMessage(0); return 0; default: @@ -923,6 +924,13 @@ LRESULT WindowEmperor::_messageHandler(HWND window, UINT const message, WPARAM c void WindowEmperor::_finalizeSessionPersistence() const { + if (_skipPersistence) + { + // We received WM_ENDSESSION and persisted the state. + // We don't need to persist it again. + return; + } + const auto state = ApplicationState::SharedInstance(); // Calling an `ApplicationState` setter triggers a write to state.json. @@ -932,7 +940,7 @@ void WindowEmperor::_finalizeSessionPersistence() const state.PersistedWindowLayouts(nullptr); } - if (_forcePersistence || _app.Logic().Settings().GlobalSettings().ShouldUsePersistedLayout()) + if (_app.Logic().Settings().GlobalSettings().ShouldUsePersistedLayout()) { for (const auto& w : _windows) { diff --git a/src/cascadia/WindowsTerminal/WindowEmperor.h b/src/cascadia/WindowsTerminal/WindowEmperor.h index 3024ab7a2c..c232c6cd1a 100644 --- a/src/cascadia/WindowsTerminal/WindowEmperor.h +++ b/src/cascadia/WindowsTerminal/WindowEmperor.h @@ -75,7 +75,7 @@ private: UINT WM_TASKBARCREATED = 0; HMENU _currentWindowMenu = nullptr; bool _notificationIconShown = false; - bool _forcePersistence = false; + bool _skipPersistence = false; bool _needsPersistenceCleanup = false; std::optional _currentSystemThemeIsDark; int32_t _windowCount = 0;