gpui: render deferred overlays above native child views - #24
Open
huacnlee wants to merge 17 commits into
Open
Conversation
Add a transparent macOS GPUI overlay surface that renders deferred window content above embedded native child views while preserving WebView input when the overlay is empty. Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Split DirectComposition into base, native portal, and transparent overlay visuals. Add a platform-neutral native surface handle for binding WebView2 composition controllers. Co-authored-by: Codex <codex@openai.com>
Owner
Author
|
Windows implementation checkpoint: |
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Native child views such as
WKWebViewand Windows composition visuals are hosted outside GPUI's normal scene. A native view placed above GPUI's primary render surface also covers deferred GPUI content, so popovers, dialogs, menus, and other window-level overlays cannot appear above it.This PR introduces an opt-in three-plane composition model:
The root UI remains on the existing renderer, while deferred and window-level draws are replayed onto the transparent surface above the native content.
Why this is significant
This change is significant because it gives GPUI a general composition boundary for content that GPUI does not render itself. GPUI can continue to own the application shell, layout, commands, and overlays, while a specialized native surface renders in the middle of the same visual stack.
A WebView is the first concrete use case, but the same architecture can provide a foundation for other embedded surfaces, for example:
This PR does not make all of those integrations complete by itself; each one still needs its own lifecycle, input, focus, and platform adapter. The important first step is now demonstrated: GPUI and an independently rendered native surface can work as one composed interface, including GPUI content both below and above it.
If this foundation proves reliable, Zed could build on it to embed WebView-backed experiences such as a richer Markdown Preview and other HTML preview surfaces. macOS and Windows both have mature WebView implementations that make this direction practical. Linux is likely to require more platform work because its display-server, desktop, toolkit, and WebKit environments are more varied. That makes Linux support harder, but not a fundamental blocker; it can be solved in follow-up work.
API
Window::enable_scene_overlay()enables layered scene presentation for a window. Without this opt-in, platforms continue using the existing single-surface draw path.Window::create_native_surface()creates a platform-native slot between the GPUI base and overlay planes. The initial implementation exposes this portal on Windows.PlatformNativeSurfaceis the platform-neutral handle for a native slot:set_boundssynchronizes its geometry in device pixels.set_visibleincludes or excludes it from composition.platform_handleexposes the platform attachment object, such as anIDCompositionVisual.Key implementation points
Frame::overlay_scene_startrecords the scene boundary immediately before deferred draws are painted.PlatformWindow::draw_layered(scene, overlay_start)presents the base and overlay ranges separately. Its default implementation preserves the previous single-surface behavior on unsupported platforms.Scene::is_empty()checks for drawable primitives rather than bookkeeping operations. The macOS overlay uses this to capture input only while visible overlay content exists; otherwise events pass through to the native view.new_overlay_renderercreates a transparentCAMetalLayerrenderer that shares the base renderer's Metal device and sprite atlas. AppKit places this layer above native child views.DirectCompositionPortalimplementsPlatformNativeSurface.Example
cargo run -p gpui --example native_webviewThe macOS-only example embeds
WKWebViewdirectly, without adding awrydependency to GPUI. It demonstrates:Companion component integration and documentation: longbridge/gpui-component#2626
Current scope
wry/WebKitGTK integration is not suitable for this iterationWebView-specific focus and clipboard behavior remains in the embedding component so the GPUI API stays focused on rendering and native-surface composition.
Test Plan
cargo test -p gpui scene::tests --libcargo check -p gpui -p gpui_macoscargo check -p gpui --example native_webview