Fix window space restoration on macOS 15+

Commit: daf1cc36 | 2026-03-05 21:34:25

← Back to List

Fix window space restoration on macOS 15+

Moderate
Commit Hash: daf1cc3653a55e6866f26357e12d3900fce9a169
Commit Time: 2026-03-05 21:34:25
Impact Level: Moderate
Generated By: webview2-upstream-sentry
Upstream Review: View Upstream Review 🔗

📋 Summary

This commit fixes window space (workspace) restoration on macOS 15 and newer. Key changes include:
1. Mojo interface change: Added a new StateRestorationData struct in native_widget_ns_window.mojom, splitting the original array state_restoration_data into appkit_restoration_data (raw AppKit data) and restore_space (whether to restore to the original workspace). The type in NativeWidgetNSWindowInitParams is changed to an optional StateRestorationData?.
2. Added RestorationOptionsKeyedUnarchiver class (NSKeyedUnarchiver subclass), which implements the private _windowRestorationOptions method to return a default-initialized NSWindowRestorationOptions object, working around the NSWindowRestoresWorkspaceAtLaunch defaults key no longer functioning in macOS 15.
3. Added static method SetMoveWindowsToOriginalSpacesUponRestoration() on NativeWidgetMacNSWindowHost, called by ChromeBrowserMainPartsMac at startup based on the kWasRestarted preference.
4. Modified NativeWidgetNSWindowBridge::SetVisibilityState() to select restoration strategy by macOS version: macOS 15+ uses RestorationOptionsKeyedUnarchiver, macOS 14 and below still uses the NSWindowRestoresWorkspaceAtLaunch defaults key.
5. NativeWidgetMacNSWindowHost::InitWindow() now constructs a StateRestorationData object with the restore_space flag, instead of directly assigning the raw byte array.

🎯 Impact Analysis

This change has a moderate impact on WebView2Mac that warrants attention. Key analysis:

1. **Breaking Mojo interface change**: The state_restoration_data field in NativeWidgetNSWindowInitParams (native_widget_ns_window.mojom) changed from array to an optional StateRestorationData? struct. This is a core Remote Cocoa cross-process communication interface used between WebView2Mac's Host App process and Browser process for passing window initialization parameters. The Edge repo still uses the array type, so all references to this interface must be updated synchronously upon integration.

2. **NativeWidgetMacNSWindowHost changes**: The logic for constructing window_params->state_restoration_data in InitWindow() has changed. WebView2Mac's window creation flow passes through this method (both in-process and remote modes). If Edge has custom modifications here, merge conflicts should be expected.

3. **NativeWidgetNSWindowBridge restoration logic changes**: The window state restoration code path in SetVisibilityState() has significant modifications, including changing pending_restoration_data_ type from vector to mojom::StateRestorationDataPtr. This method is a key entry point for WebView2Mac window show/activation, executed in the app shim process. For WebView2Mac scenarios, embedded WebView windows typically do not use workspace restoration (as they are embedded within host app windows), so the runtime impact is limited.

4. **macOS 15+ compatibility fix**: The introduced RestorationOptionsKeyedUnarchiver uses private AppKit APIs (_windowRestorationOptions and NSWindowRestorationOptions class), which may change in future macOS versions. If WebView2Mac relies on window state restoration, this compatibility risk should be monitored.

5. **base::Base64Decode API update**: The Base64 decoding in InitWindow() migrated from the old output-parameter style to the new optional-returning API. This is a minor API migration that must be aligned with Edge's own code upon integration.

Impacted Classes:

remote_cocoa::mojom::StateRestorationData remote_cocoa::mojom::NativeWidgetNSWindowInitParams views::NativeWidgetMacNSWindowHost remote_cocoa::NativeWidgetNSWindowBridge RestorationOptionsKeyedUnarchiver