diff --git a/apps/web/src/browser/HostedBrowserWebview.tsx b/apps/web/src/browser/HostedBrowserWebview.tsx
index cd1852d369279..e128cdfdcdcec 100644
--- a/apps/web/src/browser/HostedBrowserWebview.tsx
+++ b/apps/web/src/browser/HostedBrowserWebview.tsx
@@ -289,6 +289,7 @@ export function HostedBrowserWebview(props: {
const wrapperStyle = resolveHostedBrowserWebviewWrapperStyle({
active,
renderingActive,
+ serverDriven,
// Electron 43 can permanently blank a macOS webview after `visibility: hidden`.
keepPaintableWhenInactive: isMacPlatform(navigator.platform),
cornerRadius: presentation.cornerRadius,
@@ -303,7 +304,7 @@ export function HostedBrowserWebview(props: {
className="fixed overflow-hidden bg-muted/35"
style={{ ...wrapperStyle, overscrollBehavior: "contain" }}
onScroll={syncContentPresentation}
- data-preview-rendering={renderingActive ? "active" : "suspended"}
+ data-preview-rendering={renderingActive || serverDriven ? "active" : "suspended"}
data-preview-viewport={runtimeTabId}
>
diff --git a/apps/web/src/browser/hostedBrowserWebviewStyle.ts b/apps/web/src/browser/hostedBrowserWebviewStyle.ts
index f37c222b08e9c..fcc1c8c7b5cdc 100644
--- a/apps/web/src/browser/hostedBrowserWebviewStyle.ts
+++ b/apps/web/src/browser/hostedBrowserWebviewStyle.ts
@@ -21,6 +21,7 @@ const HIDDEN_BROWSER_WEBVIEW_OFFSET = -100_000;
export function resolveHostedBrowserWebviewWrapperStyle(input: {
readonly active: boolean;
readonly renderingActive: boolean;
+ readonly serverDriven?: boolean;
readonly keepPaintableWhenInactive?: boolean;
readonly cornerRadius?: number;
readonly zIndex?: number;
@@ -34,6 +35,7 @@ export function resolveHostedBrowserWebviewWrapperStyle(input: {
keepPaintableWhenInactive = false,
rect,
renderingActive,
+ serverDriven = false,
zIndex = 30,
} = input;
if (active && rect) {
@@ -48,8 +50,9 @@ export function resolveHostedBrowserWebviewWrapperStyle(input: {
};
}
- if (renderingActive) {
+ if (renderingActive || serverDriven) {
// Electron stops compositing offscreen guests; keep capture-active guests inside the viewport behind the app.
+ // Server-driven guests must paint before the remote handshake's first capture.
return {
left: 0,
top: 0,