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
This commit is contained in:
Leonard Hecker 2025-05-23 01:02:58 +02:00 committed by Dustin L. Howett
parent b6f56d63f5
commit 94a2aa0100
2 changed files with 11 additions and 3 deletions

View File

@ -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)
{

View File

@ -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<bool> _currentSystemThemeIsDark;
int32_t _windowCount = 0;