Skip to content

Overlay windows support - #219

Open
jasonkneen wants to merge 3 commits into
vercel-labs:mainfrom
jasonkneen:overlay-windows
Open

Overlay windows support#219
jasonkneen wants to merge 3 commits into
vercel-labs:mainfrom
jasonkneen:overlay-windows

Conversation

@jasonkneen

Copy link
Copy Markdown
Contributor

This pull request introduces a comprehensive overlay window system for the AppKit host, enabling advanced desktop companion windows (such as pointer followers and always-on-top overlays) with fine-grained control over appearance, stacking, and interaction. It also adds support for injecting user scripts into WebViews at document start, facilitating advanced app-driven page observation and integration. These features are exposed via new runtime APIs and are implemented to avoid focus-stealing or visual glitches.

Overlay window system and control:

  • Added support for overlay window options in WindowOptions/WindowCreateOptions including transparent, shadow, level, click_through, all_workspaces, visible, and activate, allowing apps to create overlays that do not steal focus or flash opaque at creation (changelog.d/overlay-windows.md, src/platform/macos/appkit_host.h, src/platform/macos/appkit_host.m).
  • Implemented new runtime verbs for overlay window control: setWindowFrame, setWindowVisible (show without activating), setWindowClickThrough, and queries for pointerPosition and screenWorkArea to support overlay placement logic (src/platform/macos/appkit_host.h, src/platform/macos/appkit_host.m).

WebView user script injection:

  • Added support for WebViewOptions.user_script, enabling injection of app-supplied JavaScript into the main frame of a child WebView at document start, isolated from page JS and only on the system engine (changelog.d/overlay-windows.md, src/platform/macos/appkit_host.h, src/platform/macos/appkit_host.m).

AppKit host implementation details:

  • Refactored and extended internal data structures to stage overlay and user script configuration prior to window/WebView creation, ensuring visual and behavioral correctness (e.g., no focus stealing, no opaque flash, click-through behavior, etc.) (src/platform/macos/appkit_host.m).

  • Overrode acceptsFirstMouse: in overlay WebViews to ensure first clicks are delivered to web content even if the app is not frontmost, improving UX for overlay/companion windows (src/platform/macos/appkit_host.m).

Adds overlay/companion window capabilities to WindowOptions and WindowCreateOptions: transparent, shadow, level (normal/floating/status/screen_saver), click_through, all_workspaces, visible, and activate fields.

New runtime verbs: setWindowFrame, setWindowVisible, setWindowClickThrough, pointerPosition, and screenWorkArea. Implemented on the AppKit host with pre-create staging to avoid opaque/focus-stealing flash, stubbed on the Chromium host for ABI parity, and recorded by the null platform for headless tests.

Also adds WebViewOptions.user_script and WindowOptions.user_script for injecting JavaScript into WebViews at document start.
Copilot AI review requested due to automatic review settings July 27, 2026 10:35
@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

@jasonkneen is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

// click on such a window is consumed as an app-activation click and never
// reaches the web content — the window appears dead until it is already
// focused. Accepting first mouse delivers that click straight to the page.
- (BOOL)acceptsFirstMouse:(NSEvent *)event {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NativeSdkWebView acceptsFirstMouse: returns YES unconditionally, so every SDK window (main + child webviews), not just overlay/companion windows, delivers a background-window activation click straight to web content.

Fix on Vercel

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an overlay-window feature set across the runtime and macOS hosts, enabling always-on-top / click-through / non-activating companion windows, plus document-start JavaScript injection for window main WebViews and child WebViews (system WebKit host).

Changes:

  • Extended WindowOptions/WindowCreateOptions with overlay-specific fields (transparency, shadow, level, click-through, all-workspaces, visible/activate) and added WindowLevel.
  • Added new runtime verbs for overlay control (setWindowFrame, setWindowVisible, setWindowClickThrough) and placement queries (pointerPosition, screenWorkArea).
  • Implemented macOS AppKit host support for overlay staging + WebView user scripts; updated the Chromium host ABI to accept new calls/params; expanded the null platform seam recording and tests.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/runtime/window_views.zig Exposes new runtime window verbs/queries for overlays.
src/runtime/core.zig Re-exports the new window APIs on Runtime.
src/root.zig Exposes WindowLevel from the platform layer at the root API.
src/platform/types.zig Adds WindowLevel, overlay fields to window options, WebViewOptions.user_script, and new PlatformServices hooks.
src/platform/root.zig Re-exports WindowLevel from types.
src/platform/null_platform.zig Records overlay create options and implements new platform service hooks (frame/visibility/click-through, pointer/work-area).
src/platform/null_platform_tests.zig Adds seam regression tests for overlay options and control calls.
src/platform/macos/root.zig Wires new platform services into the macOS host and stages overlay + user scripts prior to window creation.
src/platform/macos/cef_host.mm Adds ABI-parity stubs and implements configure/visibility/frame/pointer/work-area overlay support for the Chromium host.
src/platform/macos/appkit_host.m Implements overlay staging/ordering, window main-webview script injection, and child webview user scripts.
src/platform/macos/appkit_host.h Extends the C ABI with overlay and user-script functions; extends create-webview signature.
changelog.d/overlay-windows.md Documents new overlay-window capabilities, runtime verbs, and WebView user script injection.
Comments suppressed due to low confidence (1)

src/platform/macos/appkit_host.m:7350

  • For deferred-show windows (showPolicy == 1), the new overlay visible:false option is ignored: the window is still registered in deferredShowWindows and will be shown on first present / fallback deadline. This contradicts the documented behavior that visible:false windows should stay ordered out until an explicit setWindowVisible.

A minimal fix is to remove deferred-show bookkeeping when overlayVisible is false so the deferred show path never orders it front.

    if (makeMain) {
        self.window = window;
        self.delegate = delegate;
        self.windowLabel = label.length > 0 ? label : @"main";
    } else if (showPolicy != 1 && overlayVisible) {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1294 to 1308
// Overlay config must be staged BEFORE the create call — the host
// consumes it inside createWindowWithId: so transparency/level apply
// before the window is ever ordered front, and visible:false /
// activate:false windows never flash or steal focus at create.
if (windowHasOverlayOptions(options)) {
_ = native_sdk_appkit_set_pending_window_overlay(self.host, options.id, if (options.transparent) 1 else 0, if (options.shadow) 1 else 0, windowLevelInt(options.level), if (options.click_through) 1 else 0, if (options.all_workspaces) 1 else 0, if (options.visible) 1 else 0, if (options.activate) 1 else 0);
}
// Stage the main-webview content script BEFORE create so the lazily
// built webview picks it up on first load.
if (options.user_script.len > 0) {
_ = native_sdk_appkit_set_window_user_script(self.host, options.id, options.user_script.ptr, options.user_script.len);
}
if (native_sdk_appkit_create_window(self.host, options.id, title.ptr, title.len, options.label.ptr, options.label.len, frame.x, frame.y, frame.width, frame.height, if (options.restore_state) 1 else 0, if (options.resizable) 1 else 0, titlebarStyleInt(options.titlebar), showModeInt(options.show)) == 0) return error.CreateFailed;
applyWindowContentMinSize(self.host, options.id, options.min_width, options.min_height);
applyWindowClosePolicy(self.host, options.id, options.close_policy);
Comment on lines +1265 to +1267
- (BOOL)acceptsFirstMouse:(NSEvent *)event {
return YES;
}
Comment on lines 1105 to +1110
// Present-before-show: deferred windows are created hidden and
// become visible on their first gpu-surface present.
if (options.show == .immediate) {
// become visible on their first gpu-surface present. An overlay
// window declared `visible:false` is also created hidden — it
// appears only on an explicit `setWindowVisible` (the real hosts
// skip its order-front inside create).
if (options.show == .immediate and options.visible) {
Comment on lines +7344 to +7345
BOOL overlayVisible = overlay[@"visible"] ? [overlay[@"visible"] boolValue] : YES;
BOOL overlayActivate = overlay[@"activate"] ? [overlay[@"activate"] boolValue] : YES;
@ctate

ctate commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Partial support for this was added in v0.6.2, after making sure the options in #228 work across macOS, Linux and Windows (added you as a co-author)

Will work on getting the other options added!

ETA: v0.6.2 is being cut now and will be out in ~30m

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants