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

## Validation Steps Performed

Honestly, none. It's a race condition in the first place.
This commit is contained in:
Leonard Hecker
2025-05-23 01:02:58 +02:00
committed by GitHub
parent a093ca3d54
commit 26cd15a14b
2 changed files with 11 additions and 3 deletions

View File

@@ -899,7 +899,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:
@@ -946,7 +947,7 @@ void WindowEmperor::_persistState(const ApplicationState& state, bool serializeB
state.PersistedWindowLayouts(nullptr);
}
if (_forcePersistence || _app.Logic().Settings().GlobalSettings().ShouldUsePersistedLayout())
if (_app.Logic().Settings().GlobalSettings().ShouldUsePersistedLayout())
{
for (const auto& w : _windows)
{
@@ -960,6 +961,13 @@ void WindowEmperor::_persistState(const ApplicationState& state, bool serializeB
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();
_persistState(state, true);

View File

@@ -77,7 +77,7 @@ private:
UINT WM_TASKBARCREATED = 0;
HMENU _currentWindowMenu = nullptr;
bool _notificationIconShown = false;
bool _forcePersistence = false;
bool _skipPersistence = false;
bool _needsPersistenceCleanup = false;
SafeDispatcherTimer _persistStateTimer;
std::optional<bool> _currentSystemThemeIsDark;