Refactor headless mode platform window management on macOS
Minor
Commit Hash:
a8f945e308123e7c96f0ff51190534b8340fd6b1
Commit Time: 2026-02-04 00:58:46+00:00
Impact Level: Minor
Generated By: webview2-upstream-sentry
Upstream Review:
View Upstream Review 🔗
📋 Summary
This commit performs a major refactoring of window management for headless mode on macOS. The previous implementation tweaked browser window behavior at the NSWindow bridge level, while the new implementation works at a lower level by overriding NSWindow methods responsible for window visibility, zoom, fullscreen, and minimization. Key changes include:
1. **Architecture change**: Removed the HeadlessModeWindow struct from NativeWidgetNSWindowBridge and replaced it with a more comprehensive WindowState enum (kNormal, kZoomed, kFullscreen, kMiniaturized) in NativeWidgetMacNSWindowHeadlessInfo.
2. **Method swizzling**: Directly overrides core NSWindow methods (isVisible, isZoomed, setIsZoomed:, performZoom:, miniaturize:, deminiaturize:, toggleFullScreen:, makeKeyWindow, orderFront:, etc.) via Objective-C method swizzling instead of intercepting at the bridge layer.
3. **Visibility management**: Removed approximately 40 lines of special headless mode handling logic from NativeWidgetNSWindowBridge::SetVisibilityState(), moving it to the NSWindow layer. Added invokeOriginalIsVisibleForTesting() method to obtain the actual platform window state during testing.
4. **window_visible() simplification**: Simplified window_visible() from a complex conditional function to an inline function that directly returns the window_visible_ member variable.
5. **Enhanced state tracking**: Added is_visible and is_key flags to NativeWidgetMacNSWindowHeadlessInfo to track window visibility and focus state in headless mode.
1. **Architecture change**: Removed the HeadlessModeWindow struct from NativeWidgetNSWindowBridge and replaced it with a more comprehensive WindowState enum (kNormal, kZoomed, kFullscreen, kMiniaturized) in NativeWidgetMacNSWindowHeadlessInfo.
2. **Method swizzling**: Directly overrides core NSWindow methods (isVisible, isZoomed, setIsZoomed:, performZoom:, miniaturize:, deminiaturize:, toggleFullScreen:, makeKeyWindow, orderFront:, etc.) via Objective-C method swizzling instead of intercepting at the bridge layer.
3. **Visibility management**: Removed approximately 40 lines of special headless mode handling logic from NativeWidgetNSWindowBridge::SetVisibilityState(), moving it to the NSWindow layer. Added invokeOriginalIsVisibleForTesting() method to obtain the actual platform window state during testing.
4. **window_visible() simplification**: Simplified window_visible() from a complex conditional function to an inline function that directly returns the window_visible_ member variable.
5. **Enhanced state tracking**: Added is_visible and is_key flags to NativeWidgetMacNSWindowHeadlessInfo to track window visibility and focus state in headless mode.
🎯 Impact Analysis
The impact of this change on WebView2Mac is **Minor**, for the following reasons:
**Direct Impact Analysis**:
1. **Interface stability**: All remote_cocoa public interfaces remain unchanged, with no modifications to Mojo interface definitions or virtual function signatures.
2. **Inheritance unchanged**: The public interfaces of core classes inherited by WebView2Mac (NativeWidgetNSWindowBridge, WebContentsNSViewBridge) are unaffected.
3. **Implementation detail refactoring**: Changes are primarily focused on internal headless mode implementation, altering the hierarchy of window state management through method swizzling without exposure to external consumers.
**Potential Risks**:
1. **window_visible() behavior change**: While this method changed from a function declaration to an inline implementation in bridge.h, this is transparent to WebView2Mac since its inherited class HostingNSWindowBridge does not override this method.
2. **NativeWidgetMacNSWindow extension**: The newly added invokeOriginalIsVisibleForTesting() method is for testing purposes only and does not affect runtime behavior.
3. **Headless mode scoping**: The entire refactoring only activates when display::Screen::Get()->IsHeadless() returns true, and WebView2Mac typically runs in non-headless mode.
**Why the Impact is Minor**:
- WebView2Mac does not use headless mode functionality (does not depend on HeadlessModeWindow structure or related logic)
- The refactored window visibility and state management logic is encapsulated at the NSWindow layer through method swizzling, transparent to downstream code that inherits NativeWidgetNSWindowBridge
- The public API of the core dependency NativeWidgetNSWindowBridge maintains backward compatibility
- Changes do not involve key components directly used by WebView2Mac such as ApplicationBridge and NativeWidgetNSWindowHostHelper
**Recommended Actions**:
- Verify that WebView2Mac window visibility-related functionality works correctly
- Confirm no code directly depends on the removed HeadlessModeWindow structure (extremely unlikely as this was upstream internal implementation)
- Monitor for behavioral changes related to window state transitions (show/hide, minimize, fullscreen)
**Direct Impact Analysis**:
1. **Interface stability**: All remote_cocoa public interfaces remain unchanged, with no modifications to Mojo interface definitions or virtual function signatures.
2. **Inheritance unchanged**: The public interfaces of core classes inherited by WebView2Mac (NativeWidgetNSWindowBridge, WebContentsNSViewBridge) are unaffected.
3. **Implementation detail refactoring**: Changes are primarily focused on internal headless mode implementation, altering the hierarchy of window state management through method swizzling without exposure to external consumers.
**Potential Risks**:
1. **window_visible() behavior change**: While this method changed from a function declaration to an inline implementation in bridge.h, this is transparent to WebView2Mac since its inherited class HostingNSWindowBridge does not override this method.
2. **NativeWidgetMacNSWindow extension**: The newly added invokeOriginalIsVisibleForTesting() method is for testing purposes only and does not affect runtime behavior.
3. **Headless mode scoping**: The entire refactoring only activates when display::Screen::Get()->IsHeadless() returns true, and WebView2Mac typically runs in non-headless mode.
**Why the Impact is Minor**:
- WebView2Mac does not use headless mode functionality (does not depend on HeadlessModeWindow structure or related logic)
- The refactored window visibility and state management logic is encapsulated at the NSWindow layer through method swizzling, transparent to downstream code that inherits NativeWidgetNSWindowBridge
- The public API of the core dependency NativeWidgetNSWindowBridge maintains backward compatibility
- Changes do not involve key components directly used by WebView2Mac such as ApplicationBridge and NativeWidgetNSWindowHostHelper
**Recommended Actions**:
- Verify that WebView2Mac window visibility-related functionality works correctly
- Confirm no code directly depends on the removed HeadlessModeWindow structure (extremely unlikely as this was upstream internal implementation)
- Monitor for behavioral changes related to window state transitions (show/hide, minimize, fullscreen)
Impacted Classes:
NativeWidgetNSWindowBridge
NativeWidgetMacNSWindow
NativeWidgetMacNSWindowHeadlessInfo