You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(desktop): preview snapshots no longer stall on Chromium's legacy capture path - #32415
Desktop Browser snapshots intermittently fail with Preview automation snapshot timed out after 15000ms and can keep failing until the tab is replaced. The desktop browser host keeps a preview tab offscreen and makes it paintable only while Page.captureScreenshot is pending; on that path Chromium's legacy CDP capture can stop answering. Playwright turns on CDPScreenshotNewSurface whenever it launches Chromium or Electron itself, but T3 launches Electron on its own and attaches over CDP, so the desktop app never gets it.
Reproduced on main (83a3674) on Linux x86_64 under Xvfb with the reporter's native probe, which wires a real Electron <webview> through T3's createCdpRelayConnection and calls the real ServerBrowserPage.snapshot 100 times: every run stalled within the first 5 snapshots (with --disable-gpu and without) and failed with The page was too busy to capture a snapshot in time… after 10 s.
Change
Before Electron is ready, desktop startup appends --enable-features=CDPScreenshotNewSurface on every platform. The value is merged into any existing --enable-features list, because Chromium keeps only the last value of a features switch (the same reason the Linux --disable-features merge exists). Nothing is added when the feature is already enabled or when the user turned it off with --disable-features.
vp test run apps/desktop/src/app/DesktopPreReadyPlatform.test.ts apps/desktop/src/app/DesktopEarlyElectronStartup.test.ts: 29 passed. The new tests fail on main: on darwin, win32 and linux startup leaves no feature (expected [] to have the same members as [ 'CDPScreenshotNewSurface' ]), and an existing --enable-features list is not extended. A third test covers the --disable-features opt-out.
vp run check:changed: format, lint, knip, typecheck and tests pass.
Native probe, Electron 44.10.1 under Xvfb, --no-sandbox, startup through the real DesktopPreReadyPlatform.make of each side:
100/100 snapshots each, current pixels and accessibility text verified, median 63–64 ms, max 155 ms
After, launched with --enable-features=WebRTCPipeWireCapturer
WebRTCPipeWireCapturer,CDPScreenshotNewSurface
1
100/100, max 139 ms
Driver: the reporter's probe gist (build.mjs, host.html, reproduce.cjs), run unchanged with PROBE_PRODUCTION=1.
Before transcript, run 1 (main)
{"event":"startup","features":""}
{"event":"snapshot","iteration":0,"feature":false,"ms":121,"size":[500,300],"rgb":[255,0,0],"tree":true}
{"event":"snapshot","iteration":1,"feature":false,"ms":84,"size":[500,300],"rgb":[0,0,255],"tree":true}
{"event":"snapshot","iteration":2,"feature":false,"ms":3594,"size":[500,300],"rgb":[255,0,0],"tree":true}
{"event":"snapshot","iteration":3,"feature":false,"ms":82,"size":[500,300],"rgb":[0,0,255],"tree":true}
{"event":"failure","iteration":4,"feature":false,"ms":10010,"message":"The page was too busy to capture a snapshot in time. Wait for it to settle and take another snapshot."}
Independent run on a physical Linux x64 GNOME/Wayland desktop (GPU and sandbox on), reported in this PR's comments: with no feature enabled, the same probe stalled at snapshot 12 after 10,011 ms with the busy-page error; with CDPScreenshotNewSurface enabled through DesktopPreReadyPlatform.make, 100/100 passed. That after-run used the equivalent change in #32412, not this head.
Startup switches in a real Electron process
Ubuntu 24.04 x64, Electron 44.10.1, Xvfb 1920×1080×24 with Openbox. 44 Electron processes ran the real DesktopPreReadyPlatform.make of each side before ready; all assertions pass. C=CDPScreenshotNewSurface, W=WaylandWpColorManagerV1, E/D=enable/disable list, ∅=absent. L rows use a stubbed hyprctl to reach the Linux Hyprland merge; they prove the two merges compose, not compositor behaviour.
Real desktop app of each side under Xvfb (--no-sandbox --disable-gpu), fresh isolated T3 home, T3CODE_DEV_SEED=0, snapshots driven through the production preview MCP tools on a synthetic page.
Real desktop webview and IPC; hidden rect=(-100000,-100000), visible=false; reload loadId changes
R4 viewer + recording
5/5 fresh; viewer first JPEG 23 ms; recording seed JPEG 15 ms
5/5 fresh; viewer first JPEG 17 ms; recording seed JPEG 7 ms
Viewer still refresh and continued frames; four snapshots during recording; stop succeeds
R5 minimize → restore
3/3 fresh; median/max 47/64 ms
3/3 fresh; 39/43 ms
Native minimized=true, capture; restored minimized=false, two captures
R6 native macOS
cannot-verify macos
cannot-verify macos
No native macOS run; not attempted
R7 native Windows
cannot-verify windows
cannot-verify windows
No native Windows run; not attempted
The stall did not reproduce in the integrated app on either side under Xvfb, so these rows show the flag causes no regression across hide/show, reload, recording, the viewer and minimize; the stall fix itself rests on the native probe above. Viewer JPEG refreshes after the first capture took 12–28 ms before and 5–7 ms after.
What else changed: nothing beyond the three files in this diff. Both sides shared driver, page, flags and fresh-state recipe; ports, IDs, timestamps and encoder start-up time vary.
cannot-verify macos, cannot-verify windows: no native macOS or Windows run; those platforms are covered by the unit tests and by Playwright enabling the same feature by default on every platform. A minimized window was checked on Linux/Openbox only.
Verification log
Merged main (80e6261) without conflicts; vp run check:changed passes on 1b38b8c (format, lint, knip, typecheck, 29 tests).
Review round 1: two independent reviewers, both MERGE, no findings.
Proof audit: pass 1 derived a 21-row matrix; pass 2 checked every capture and recording, rebuilt one startup row independently (matching), and found all Linux rows covered; macOS and Windows unverified as above.
AI-assisted; verified with the tests and tools listed above.
…re surface
These tests reproduce #32410: the desktop app launches Electron without
Chromium's CDPScreenshotNewSurface feature, so Page.captureScreenshot on a
webview that is moved offscreen can stall. They assert that pre-ready
startup enables the feature on darwin, win32 and linux, and keeps any
features already passed in --enable-features.
…capture path
Preview snapshots call Page.captureScreenshot on a tab kept offscreen, and
Chromium's legacy capture path can stop answering there. Playwright avoids
this by enabling CDPScreenshotNewSurface when it launches Chromium, but T3
launches Electron itself and attaches over CDP.
Pre-ready startup now enables CDPScreenshotNewSurface on every platform,
merged into any existing --enable-features value, unless the user already
enabled it or turned it off with --disable-features.
Fixes#32410
Reviewing files that changed from the base of the PR and between 1b38b8c and 7e6c97c.
You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.
Use the checkbox below for a quick retry:
Trigger review
No actionable comments were generated in the recent review.
Walkthrough
Startup resolves CDPScreenshotNewSurface against existing enable and disable feature values. Pre-ready launch arguments include the resolved enable switch when applicable. Tests cover macOS, Windows, and Linux.
The resolver preserves existing feature entries. It returns null if the feature is already enabled or disabled; otherwise, it adds the feature to the enable value.
Pre-ready launch integration and tests apps/desktop/src/app/DesktopPreReadyPlatform.ts, apps/desktop/src/app/DesktopPreReadyPlatform.test.ts
Pre-ready startup appends the resolved enable switch when present. Tests cover three platforms, retained enable entries, and an existing disable entry.
pingdotgg/t3code#32412 — Both changes enable CDPScreenshotNewSurface before Electron is ready.
pingdotgg/t3code#28991 — It changes pre-ready configuration and boot timing, which affect when this change applies the screenshot switch.
pingdotgg/t3code#24133 — Both changes address desktop preview screenshot stalls, using different capture-path changes.
Suggested reviewers:maria-rcks
Merge Risk: Minimal · previous review ab788
No actionable merge-blocking issue was found in the startup switch change.
Pre-merge checks: 4
Check name
Status
Explanation
Title check
The title describes the desktop snapshot stall addressed by the change.
Linked Issues check
[#32410] Pre-ready startup enables CDPScreenshotNewSurface and preserves existing feature flags and explicit opt-outs. The current summary reports cross-platform enablement tests and tests for flag …
Out of Scope Changes check
[#32410] The startup changes and tests support the snapshot fix and preserve existing feature settings. No unrelated changes are identified in the whole-PR summary.
Description check
The description covers the required Problem, Change, Scope and approval, and Verification sections. It links the related issue and gives detailed test and probe results, including platforms that were …
Full details: Linked Issues check
Explanation
[#32410] Pre-ready startup enables CDPScreenshotNewSurface and preserves existing feature flags and explicit opt-outs. The current summary reports cross-platform enablement tests and tests for flag preservation and opt-out. The author reports a successful native snapshot probe. The incremental diff was unavailable; the current whole-PR evidence supports the assessment.
Full details: Description check
Explanation
The description covers the required Problem, Change, Scope and approval, and Verification sections. It links the related issue and gives detailed test and probe results, including platforms that were not verified. It notes AI assistance but does not name the model and harness as the template requests; this omission does not make the otherwise complete description fail.
Finishing Touches
Generate docstrings
Commit to this branch
Create a new PR
Generate unit tests (beta)
Commit to this branch
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.
Macroscope's review found this PR requires human approval — Desktop startup now enables Chromium's newer screenshot capture path by default to prevent preview snapshot stalls, while respecting explicit disables. Adopting this product-default change requires human review.
Notes:
No code objects were reviewed. Approvability was decided on eligibility alone.
No code changes detected at 7e6c97c. Prior analysis still applies.
You can add or adjust custom eligibility rules. Learn more.
Independent #32410 findings from corex's physical Linux x64 desktop, GNOME/Wayland, Electron 44.10.1, Playwright Core 1.60.0. Normal GPU rendering and sandbox remained enabled. The native probe used an embedded webview, the real createCdpRelayConnection and ServerBrowserPage.snapshot, with separate profile/state directories for each side. Its window used showInactive().
This tested the earlier fix in #32412 at 4fa36c54ae2e0d0e30db7983d4da716cfb358e3f, based on 83a3674ffd84ffb33de768210c806cb1ac53fd80, not this PR's head. With production startup bypassed and no enabled feature, 12 captures succeeded, then iteration 12 stalled for 10,011 ms and returned the busy-page error. Executing that fix's real DesktopPreReadyPlatform.make enabled CDPScreenshotNewSurface; all 100 captures passed checks for changing PNG pixels and current accessibility labels. I inspected the final blue image with button text Frame 99.
Retained transcript excerpts:
{"event":"failure","iteration":12,"feature":false,"ms":10011,"message":"The page was too busy to capture a snapshot in time. Wait for it to settle and take another snapshot."}
{"event":"startup","features":"CDPScreenshotNewSurface"}
{"event":"snapshot","iteration":99,"feature":false,"ms":45,"size":[500,300],"rgb":[0,0,255],"tree":true}
The per-capture feature:false field is the unused manual override, not the effective feature setting. vp test run apps/desktop/src/app/DesktopPreReadyPlatform.test.ts also passed all seven tests at the earlier head. Fresh Codex review found no blocking code findings there.
Limits: the probe bypasses DesktopBrowserHost and renderer IPC, so this is native capture-path evidence rather than a full packaged-app pass. Minimized windows and physical macOS/Windows were not tested. No tests were run against #32415. Test processes exited and temporary artifacts were cleaned up. Handing this job over to you; no duplicate PR or further changes.
The reason will be displayed to describe this comment to others. Learn more.
This mock-call assertion repeats the feature-switch test and makes the unrelated startup-order test depend on the exact switch list. Could it be removed?
The automated pipeline stopped on this pull request and will not merge it:
the capture step could not show the problem on the base commit, so there is nothing to prove fixed.
On each build, opened the same synthetic changing page. Repeated 120 cycles: hide the right panel, close the floating preview, wait 250 ms, update the numbered page revision, request a screenshot and accessibility snapshot while hidden, show the right panel, wait 250 ms, request another snapshot. Both builds returned 240 fresh snapshots without timeout or busy-page errors. Corresponding screenshot hashes matched across builds. Recorded each complete sequence. Final stills came from identical screenshot pairs 500 ms apart. Uploaded evidence, stopped all launched processes, and removed both worktrees and scratch files.
Thanks for this. #32412 makes the same change and is the one being kept.
#32412 enables the same screenshot surface and also handles the post-navigation “Unable to capture screenshot” failure reported after enabling it. That additional fix makes it the more complete change to carry forward.
Your feature-list handling and explicit opt-out coverage are useful refinements to preserve when consolidating the fixes.
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
bugfixFix PR opened by an issue lead; enters the PR looppr:gate-failedA land gate failedsize:S10-29 changed lines (additions + deletions).vouch:trustedAuthor is trusted by repo permissions or the VOUCHED list.
3 participants
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.
Problem
Desktop Browser snapshots intermittently fail with
Preview automation snapshot timed out after 15000msand can keep failing until the tab is replaced. The desktop browser host keeps a preview tab offscreen and makes it paintable only whilePage.captureScreenshotis pending; on that path Chromium's legacy CDP capture can stop answering. Playwright turns onCDPScreenshotNewSurfacewhenever it launches Chromium or Electron itself, but T3 launches Electron on its own and attaches over CDP, so the desktop app never gets it.Reproduced on main (83a3674) on Linux x86_64 under Xvfb with the reporter's native probe, which wires a real Electron
<webview>through T3'screateCdpRelayConnectionand calls the realServerBrowserPage.snapshot100 times: every run stalled within the first 5 snapshots (with--disable-gpuand without) and failed withThe page was too busy to capture a snapshot in time…after 10 s.Change
Before Electron is ready, desktop startup appends
--enable-features=CDPScreenshotNewSurfaceon every platform. The value is merged into any existing--enable-featureslist, because Chromium keeps only the last value of a features switch (the same reason the Linux--disable-featuresmerge exists). Nothing is added when the feature is already enabled or when the user turned it off with--disable-features.Scope and approval
Fixes #32410
Verification
vp test run apps/desktop/src/app/DesktopPreReadyPlatform.test.ts apps/desktop/src/app/DesktopEarlyElectronStartup.test.ts: 29 passed. The new tests fail on main: on darwin, win32 and linux startup leaves no feature (expected [] to have the same members as [ 'CDPScreenshotNewSurface' ]), and an existing--enable-featureslist is not extended. A third test covers the--disable-featuresopt-out.vp run check:changed: format, lint, knip, typecheck and tests pass.--no-sandbox, startup through the realDesktopPreReadyPlatform.makeof each side:enable-featuresCDPScreenshotNewSurface--enable-features=WebRTCPipeWireCapturerWebRTCPipeWireCapturer,CDPScreenshotNewSurfaceDriver: the reporter's probe gist (
build.mjs,host.html,reproduce.cjs), run unchanged withPROBE_PRODUCTION=1.Before transcript, run 1 (main)
Independent run on a physical Linux x64 GNOME/Wayland desktop (GPU and sandbox on), reported in this PR's comments: with no feature enabled, the same probe stalled at snapshot 12 after 10,011 ms with the busy-page error; with
CDPScreenshotNewSurfaceenabled throughDesktopPreReadyPlatform.make, 100/100 passed. That after-run used the equivalent change in #32412, not this head.Startup switches in a real Electron process
Ubuntu 24.04 x64, Electron 44.10.1, Xvfb 1920×1080×24 with Openbox. 44 Electron processes ran the real
DesktopPreReadyPlatform.makeof each side before ready; all assertions pass. C=CDPScreenshotNewSurface, W=WaylandWpColorManagerV1, E/D=enable/disable list, ∅=absent. L rows use a stubbedhyprctlto reach the Linux Hyprland merge; they prove the two merges compose, not compositor behaviour.80e62619f5
1b38b8ce40
Full inputs and results: startup-table.md, startup-before.ndjson, startup-after.ndjson.
Integrated desktop app
Real desktop app of each side under Xvfb (
--no-sandbox --disable-gpu), fresh isolated T3 home,T3CODE_DEV_SEED=0, snapshots driven through the production preview MCP tools on a synthetic page.80e62619f5
1b38b8ce40
The stall did not reproduce in the integrated app on either side under Xvfb, so these rows show the flag causes no regression across hide/show, reload, recording, the viewer and minimize; the stall fix itself rests on the native probe above. Viewer JPEG refreshes after the first capture took 12–28 ms before and 5–7 ms after.
Recordings: desktop-before.mp4, desktop-after.mp4, desktop-before-after.mp4, preview-before.mp4, preview-after.mp4. Transcripts: runtime-table.md, runtime-before.ndjson, runtime-after.ndjson. Drivers and stubs (not committed): integrated-run.mjs, build-startup.mjs, startup-matrix.mjs, hyprctl, all-drivers-and-stubs.tar.gz.
What else changed: nothing beyond the three files in this diff. Both sides shared driver, page, flags and fresh-state recipe; ports, IDs, timestamps and encoder start-up time vary.
cannot-verify macos, cannot-verify windows: no native macOS or Windows run; those platforms are covered by the unit tests and by Playwright enabling the same feature by default on every platform. A minimized window was checked on Linux/Openbox only.
Verification log
vp run check:changedpasses on 1b38b8c (format, lint, knip, typecheck, 29 tests).AI-assisted; verified with the tests and tools listed above.