Skip to content

add frameless transparent always-on-top window options and window.move bridge command#1

Open
Railly wants to merge 3 commits into
vercel-labs:mainfrom
Railly:feature/floating-window
Open

add frameless transparent always-on-top window options and window.move bridge command#1
Railly wants to merge 3 commits into
vercel-labs:mainfrom
Railly:feature/floating-window

Conversation

@Railly
Copy link
Copy Markdown

@Railly Railly commented May 9, 2026

Adds three optional window flags and a new builtin bridge command that
unblock overlay/companion window patterns the current API can't express.
Same primitives as Tauri, Electron, and GTK.

Window options

All default false. Readable from app.zon:

  • framelessNSWindowStyleMaskBorderless
  • transparent — clear NSWindow + transparent WKWebView
  • always_on_topNSFloatingWindowLevel + can-join-all-spaces
.windows = .{
    .{ .label = "overlay", .frameless = true, .transparent = true, .always_on_top = true },
},

window.move

const r = await window.zero.invoke("zero-native.window.move", {
  dx: 12, dy: -7, clampToVisibleFrame: true,
});
// r.hitX / r.hitY signal boundary hits

dx/dy are screen-space, Y-down. When the payload omits a selector,
the move targets the window that sent the message (matches Tauri's
setPosition). Boundary clamping is opt-in.

Combined with pointer events, this enables custom drag UX with
velocity, momentum, and edge stops — similar to window.startDragging().

Scope

  • macOS only. Linux/Windows backends keep their existing signatures.
  • CEF host threads the flags through but stubs them (Chromium
    transparency is a follow-up).
  • All flags default to false → backwards compatible.

Tests

zig build test passes on macOS 14 / Zig 0.16. New coverage:

  • manifest parser for the three flags + defaults
  • bridge dispatch for window.move including source-window fallback
    and clamp/hit reporting through an extended NullPlatform

Happy to split into smaller PRs if preferred.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 9, 2026

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

A member of the Team first needs to authorize it.

Copy link
Copy Markdown

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

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

Additional Suggestion:

CEF backend (cef_host.mm) is missing the zero_native_appkit_move_window implementation, causing a linker error when building with the chromium web engine.

Fix on Vercel

Copy link
Copy Markdown

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

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

Additional Suggestion:

CEF backend (cef_host.mm) is missing the zero_native_appkit_move_window implementation, causing a linker error when building with the chromium web engine.

Fix on Vercel

@ctate
Copy link
Copy Markdown
Collaborator

ctate commented May 9, 2026

@Railly good call! Can you address these plz?

  1. Webview example policy gap: The webview example's builtin_policies array doesn't include zero-native.window.move.

  2. Silent CEF transparency no-op: When using the CEF backend, transparent (and the other flags for the main window) are (void)-cast away with no warning. A developer who sets transparent = true in their manifest with CEF will get an opaque window with no indication anything went wrong. Could you add a runtime trace/log warning when these flags are set but unsupported on the active backend?

@Railly Railly force-pushed the feature/floating-window branch 3 times, most recently from 942d8d6 to 9828fa8 Compare May 9, 2026 03:20
@Railly
Copy link
Copy Markdown
Author

Railly commented May 9, 2026

@ctate Pushed 9828fa8. Both items addressed:

  1. Webview policy gap: added zero-native.window.move to builtin_policies.
  2. Silent CEF flags: ZeroNativeWarnUnsupportedFlags warns via NSLog when frameless, transparent, or always_on_top are requested on the Chromium backend, covering all three since CEF doesn't honor any of them yet. Went with NSLog for now. If you'd rather route this through the runtime trace sink, lmk and I'll wire it through.

Same commit also fixes the CEF linker issue the Vercel bot flagged (zero_native_appkit_move_window stub in cef_host.mm). Verified locally with zero-native cef install + zig build -Dweb-engine=chromium on examples/hello: pre-fix reproduces undefined symbol: _zero_native_appkit_move_window, post-fix builds clean.

@ctate
Copy link
Copy Markdown
Collaborator

ctate commented May 9, 2026

@Railly Thanks for the quick follow-up. Policy gap and CEF linker fix both look good.

Found one more CEF thing while testing: frameless and always_on_top actually seem to work fine on CEF since they're just NSWindow attributes. createWindowWithId already applies them. But the main window path in initWithAppName hardcodes them all to NO, so they only take effect on sub-windows. Could you thread the flags through initWithAppName too?

Related: ZeroNativeWarnUnsupportedFlags warns for all three, but only transparent is genuinely unsupported on CEF (opaque Chromium surface). Worth narrowing that to just transparent. Also, CEF window.move silently no-ops clampToVisibleFrame.

@Railly
Copy link
Copy Markdown
Author

Railly commented May 9, 2026

@ctate Nice catches, just pushed this commit: 7c5e737:

  • initWithAppName: now takes the three flags and threads them into the main window path.
  • ZeroNativeWarnUnsupportedFlags warns only on transparent.
  • window.move clamps to NSScreen.visibleFrame in CEF, matching AppKit.

Verified with examples/hello -Dweb-engine=chromium and all three flags set: frameless + always-on-top honored, only the transparent warning fires.

@Railly Railly force-pushed the feature/floating-window branch from 7c5e737 to 664ef39 Compare May 13, 2026 19:40
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.

2 participants