Skip to content

fix(desktop): keep remote browser host tabs paintable - #22465

Closed
pablo-kitz wants to merge 10 commits into
pingdotgg:mainfrom
pablo-kitz:fix/remote-browser-host-compositing
Closed

pablo-kitz wants to merge 10 commits into
pingdotgg:mainfrom
pablo-kitz:fix/remote-browser-host-compositing

Conversation

@pablo-kitz

@pablo-kitz pablo-kitz commented Oct 20, 2026 •

Copy link
Copy Markdown

Problem

Closes #22461.

Connecting from the Mac desktop app to a Windows-hosted environment leaves the remote browser on “Connecting…”, even after restarting both computers. The environment itself remains reachable. Both applications run 0.1.1-nightly.20261020.3411.

The host's server-driven webview is suspended when no local panel displays it: its wrapper is hidden and moved to −100,000 px. Electron stops compositing guests outside the window. Meanwhile, ServerBrowser.attachViewer waits for capture initialization before the stream's WebSocket upgrade, so a stalled capture can leave the remote client waiting for its connection.

Change

Keep server-driven webviews inside the host viewport, visible behind the app with pointer events disabled, using the existing background-capture presentation. Ordinary inactive local tabs retain their suspended behavior.

Only the two browser-host rendering files are changed. Preserve upstream #22557's deletion of the layout and rendered-webview test suites instead of restoring those suites during conflict resolution.

Scope and approval

This is submitted as a small, focused correction to the established remote-browser capability: an unattended server guest must remain paintable for remote capture. #22461 records the observed failure and source investigation; it has not yet been maintainer-triaged. The patch keeps server-driven tabs paintable while open, including before a viewer connects. It does not introduce viewer-count signaling or idle suspension for those tabs.

The specific Mac-to-Windows failure is not yet verified against a patched desktop build; maintainers may prefer a narrower capture-lifetime signal instead of keeping every open server-driven guest paintable.

Verification

On Windows 11 x64, in an isolated worktree:

  • vp test run apps/web/src/browser/browserSurfaceStore.test.ts packages/client-runtime/src/preview/serverBrowserStream.test.ts: 8 passed after merging current main. These cover the remaining surface-store and stream-transport behavior; they do not establish Electron composition or successful Mac-to-Windows streaming.
  • vp run --filter @t3tools/web typecheck: passed after installing the locked dependencies in the isolated worktree.
  • Targeted lint, formatting and git diff --check: passed.

An isolated dev server was seeded from a read-only snapshot of stopped threads and opened through T3's Browser panel. Pairing/session requests succeeded, but live verification failed with Preview automation evaluate timed out after 15000ms and then No preview automation host is available for snapshot. The repository's test-t3-app workflow requires stopping verification when that panel is unavailable. No before/after screenshots or successful patched Mac-to-Windows run are available yet. No live installation or live database was changed. This remains an outstanding verification gap.

Written with GPT-6.1-sol through the Codex harness in T3 Code.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Oct 20, 2026
@pablo-kitz
pablo-kitz marked this pull request as ready for review October 20, 2026 19:32
@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between fb5aceb and ba0ffc9.

Files selected for processing: 2
  • apps/web/src/browser/HostedBrowserWebview.tsx
  • apps/web/src/browser/hostedBrowserWebviewStyle.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Walkthrough

The hosted browser webview now uses server-driven state to resolve wrapper styling and set the preview-rendering attribute. When local rendering is inactive, server-driven webviews remain visible and paintable in the viewport if no active rectangle is available.

Changes: Server-Driven Webview Rendering

Layer / File(s) Summary
Resolve server-driven wrapper styles
apps/web/src/browser/hostedBrowserWebviewStyle.ts
The resolver accepts an optional serverDriven flag that defaults to false. When no active rectangle is available, it uses the in-viewport fallback if either renderingActive or serverDriven is true.
Apply server-driven rendering state
apps/web/src/browser/HostedBrowserWebview.tsx
The webview passes serverDriven to the resolver and sets data-preview-rendering to active when serverDriven is true, even if renderingActive is false.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related issues

Possibly related PRs

Suggested labels: bugfix

Suggested reviewers: maria-rcks

Merge Risk: Minimal · up to ba0ff

No actionable merge-blocking risk is established by the reviewed source changes.

Security architecture risk: Low · up to 89833

The change is confined to browser presentation and preserves existing authorization, guest identity, input controls, and cleanup ownership. No introduced security weakness was established. Keeping unattended tabs paintable has an unverified resource cost, and the reported cross-platform connection failure has not been validated with a patched desktop build.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The changed exposure is host-side composition of existing authorized server-driven guests, including unattended guests before viewer attachment. The inspected delta does not grant another environment or viewer access to their pixels or input controls.

Trust Boundaries and Controls

  • observed — The authorization wrapper still requires preview-operate access before mounting the guest. Remote stream access and controller-based input forwarding remain separate controls; keeping the guest paintable does not replace either check.

Resilience and Maintainability Implications

  • observed — Guest identity and desktop-tab lease ownership remain unchanged. Authorization loss unmounts the guest, effect cleanup releases its lease, and final release follows the existing stop-recording and close sequence. Viewer capture finalization remains separately responsible for stopping screencast capture and detaching its session.
Pre-merge checks: Passed 3 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Linked Issues check Warning For #22461, the patch keeps server-driven guests in the viewport and marks them paintable before the first capture. This addresses the reported compositor condition. The patch does not change `ServerB… Implement or otherwise verify the initialization failure path so attach or stream setup reaches the client as an actionable error. Add an automated regression for that path. Provide evidence that the remote connection completes or that fail…
Passed Passed checks: 3 passed
Check name Status Explanation
Title check Passed The title is concise, specific, and accurately describes the primary change: keeping remote browser host tabs paintable.
Description check Passed The description includes all required sections and clearly documents the problem, implementation, scope, approval status, verification results, and known verification gaps. It explicitly states that e…
Out of Scope Changes check Passed The whole-PR diff contains changes only in apps/web/src/browser/HostedBrowserWebview.tsx and apps/web/src/browser/hostedBrowserWebviewStyle.ts. The changes keep server-driven guests paintable and …
Full details: Description check

Explanation

The description includes all required sections and clearly documents the problem, implementation, scope, approval status, verification results, and known verification gaps. It explicitly states that end-to-end validation and screenshots are unavailable.

Full details: Out of Scope Changes check

Explanation

The whole-PR diff contains changes only in apps/web/src/browser/HostedBrowserWebview.tsx and apps/web/src/browser/hostedBrowserWebviewStyle.ts. The changes keep server-driven guests paintable and preserve suspended behavior for ordinary inactive local tabs. These changes directly support #22461. No unrelated product-area change is shown.

Full details: Linked Issues check

Explanation

For #22461, the patch keeps server-driven guests in the viewport and marks them paintable before the first capture. This addresses the reported compositor condition. The patch does not change ServerBrowser.attachViewer, WebSocket setup, or initialization-error handling. It adds no automated test for a completed connection or an actionable failure. The reported Mac-to-Windows flow remains unverified, so the indefinite-spinner requirement is not met.

Resolution

Implement or otherwise verify the initialization failure path so attach or stream setup reaches the client as an actionable error. Add an automated regression for that path. Provide evidence that the remote connection completes or that failure produces the actionable error.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@achose369

Copy link
Copy Markdown

I reviewed the two-file patch at fb5aceb against current upstream b16728a.

The change directly addresses one plausible cause of #23015: a server-driven native guest remains inside the host viewport even when no local panel displays it. The existing active local presentation, inactive pointer restriction, and component/desktop-tab cleanup are preserved. I did not identify a concrete code correction in this patch.

Our concrete case on 2026-10-26: the owner wanted to review features of their local AI/Game Overviews hub remotely using T3's collaborative browser through the intended T3 Connect workflow. This was a local web application, not an external SSO page. The Windows host's installed T3 Code (Beta) executable was version 0.1.2 (ProductVersion 0.1.2.0).

The agent opened http://127.0.0.1:41241/, which resolved to /#/studio/overview with the expected Studio Hub title. preview_open initially returned available:true, visible:false, loading:false; reopening the same tab with open:true, show:true returned visible:true. The owner nevertheless reported being stuck on “Connecting” and could not inspect the hub. Subsequent status still showed the correct page metadata. Two snapshots of that tab timed out with Preview automation snapshot timed out after 15000ms. Between attempts, a host-side HTTP request returned 200 with 1,927 bytes.

The practical failure was that neither the owner could use the preview for their feature review nor the agent could obtain a screenshot. Control still reported agent-owned; no successful takeover, click, or recovery was observed. Tab metadata and an HTTP response did not establish that a frame reached the owner.

The remote client/device and active route were not independently recorded, nor was the host's covered/minimized/locked state or selected thread. We have not run this workflow on the patched build or a local nightly. The nightly reproduction cited in #23015 belongs to another contributor. Our evidence supports a matching symptom, not a confirmed compositor root cause or successful fix.

This case also closely matches #23261's snapshot failures. That issue was closed as a duplicate of #23139, not as a verified fix (see #23261 (comment)). Its 0.1.1 report included successful evaluation, an observed locked Windows session, failures on example.com as well as a local page, and a later unavailable-host error. We did not establish those additional conditions in our 0.1.2 hub case. The earlier report also walked back locking as a confirmed cause. Please treat our case as related evidence, not a confirmed reproduction of the same covered/locked-window cause; host eviction remains separately tracked in #16921.

Please keep the completion claim narrow until a patched run demonstrates a first frame, continuing updates, remote input and an agent snapshot while the host shows another thread, followed by actual tab closure. Covered/minimized-host behavior should be reported separately. Keeping all open server-driven tabs paintable is broader than keeping only remotely viewed tabs active; it is an intentional resource tradeoff, not viewer-scoped suspension. Capture deadlines and already-stalled screenshot recovery remain separate work.

No merge approval or successful end-to-end verification is implied by this source review.

@github-actions github-actions Bot added size:XS 0-9 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Oct 26, 2026
@pablo-kitz pablo-kitz closed this Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Mac desktop to Windows remote browser stays on Connecting indefinitely

2 participants