MarshallOfSound

#53566: fix: persist window state when a display-mode transition ends

Merged
Created: Sep 4, 2026, 8:05:13 PM
Merged: Sep 5, 2026, 3:57:53 AM
3 comments
Target: main

Only resize and move scheduled a window-state save. Entering or leaving fullscreen and maximizing or unmaximizing did not, and bounds events fired during those transitions are skipped by SaveWindowState. So an app that went fullscreen (or maximized) and quit without moving the window lost that state on next launch.

BaseWindow::OnWindowEnterFullScreen, OnWindowLeaveFullScreen, OnWindowMaximize and OnWindowUnmaximize now schedule a save, the same way OnWindowResize and OnWindowMove do. All three platforms route through these hooks.

This PR also speeds up the windowStatePersistence spec, which is what surfaced the bug:

  • Window state reaches disk through PrefService, which batches writes on a 10s timer. The spec polled the prefs file once a second and waited on that timer for every save.
  • electron_common_testing (DCHECK builds only) gains commitPendingLocalStateWrites(), which forces the write and resolves when it lands. The spec uses it when available and falls back to polling otherwise.
  • createAndSaveWindowState now waits for the state it asked for (fullscreen/kiosk on disk), not for any change. With the forced flush, the pre-transition save could land first, which is how the missing transition save showed up.

Locally the suite went from 408s to 251s (the remaining time is mostly the multi-monitor tests, which need a virtual display this machine can't create, timing out). On CI it was ~4 minutes of the slowest macOS x64 shard.

Notes: Fixed window state not being persisted when a window entered or left fullscreen, or was maximized or unmaximized, without also being moved or resized.

Backports

44-x-y
In-flight
PR Number
#53576
Waiting to be merged
45-x-y
In-flight
PR Number
#53577
Waiting to be merged

Semver Impact

Major
Breaking changes
Minor
New features
Patch
Bug fixes
None
Docs, tests, etc.

Semantic Versioning helps users understand the impact of updates:

  • Major (X.y.z): Breaking changes that may require code modifications
  • Minor (x.Y.z): New features that maintain backward compatibility
  • Patch (x.y.Z): Bug fixes that don't change the API
  • None: Changes that don't affect using facing parts of Electron