Skip to content

fix(desktop): suspend hidden previews, open OAuth popups from the preview - #165

Merged
rynfar merged 3 commits into
pylonfrom
upstream/2026-08-29-desktop
Aug 29, 2026
Merged

fix(desktop): suspend hidden previews, open OAuth popups from the preview#165
rynfar merged 3 commits into
pylonfrom
upstream/2026-08-29-desktop

Conversation

@rynfar

@rynfar rynfar commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Two clean cherry-picks from the f94a0d646..bcb855a63 upstream review, plus one security fix found in review.

#8567 — hidden browser previews kept rendering and drained battery. Rendering is now suspended unless the surface is active, has background activity, is picture-in-picture, or is recording.

#8435 — scripted window.open from a preview now opens a real popup instead of navigating the preview away, so OAuth flows complete.

New: popups no longer inherit the preview guest's preload. Upstream's POPUP_WINDOW_OPTIONS overrides contextIsolation, nodeIntegration, and sandbox — but preload is a webPreference too, and an unset one is inherited from the opener. Preview guests load Pylon's pick/annotation preload, which imports ipcRenderer and registers pick, annotation-theme, human-input, and mouse-navigate channels. That was written for the trusted preview surface, not a third-party sign-in page. contextIsolation keeps the page out of the preload's world, so this is defence in depth rather than a live escape.

Two upstream regressions to preview automation, documented not fixed

Both are upstream's design, both survive here, and both affect the preview browser agents drive:

  1. preview_status drops viewport for any non-rendering tab. It is the only automation op that does not take the render lease, so readRenderedViewport is skipped and the key is simply omitted (viewport is Schema.optional, so it decodes clean). An agent asking for pixel dimensions on a background tab silently gets nothing and falls back to the CSS setting — wrong on a zoomed or fitted surface.
  2. Screenshots can capture a guest that has not painted since resume. captureAutomationSnapshot calls capturePage() with no retry, while startFrameCapture 500 lines earlier retries with a comment naming exactly this failure ("Chromium can return UnknownVizError while a hidden guest is warming its first compositor frame"). Result is a failed preview_snapshot or a 0×0 image returned with no error.

Neither is confirmable without a running Electron build. A follow-up is proposed: the automation path already holds a CDP debugger session (Manager.ts:1162, used for Runtime.evaluate and Accessibility.getFullAXTree), so moving screenshots to Page.captureScreenshot over that same session would decouple them from window visibility entirely.

Verification

Both commits are byte-identical to upstream and Pylon never diverged in the preview subsystem; the one divergence in the touched set, Pylon's persist:pylon-code-preview- partition names, is preserved. Manager.test.ts 66/66 pass. Web browser suites 26/26. Desktop and web typechecks clean. Adversarial review confirmed every acquire has a matching release and that recording and picture-in-picture stay covered by the new lease terms.

Model: Claude Opus 5. Harness: Claude Code.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Bil0000 and others added 3 commits August 28, 2026 23:38
(cherry picked from commit ff1761012af46ceb5f1ecc9b2be00aae288a1691)
Co-authored-by: Julius Marminge <julius0216@outlook.com>
(cherry picked from commit 0e2905eb783fd2385f358a95f0b25bbf07ff7122)
`POPUP_WINDOW_OPTIONS` from pingdotgg/t3code#8435 overrides contextIsolation,
nodeIntegration, and sandbox, but `preload` is a webPreference too and an unset
one is inherited from the opener. Preview guests load Pylon's pick/annotation
preload, which imports `ipcRenderer` and registers pick, annotation-theme,
human-input, and mouse-navigate channels. That was written for the trusted
preview surface, not a third-party sign-in page.

contextIsolation keeps the page out of the preload's world, so this is
defence in depth rather than a live escape.
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 29, 2026
@github-actions

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.3 KiB 13.3 KiB +3 B (+0.0%) 15.1 KiB
Codex Thread snapshot wire 6.9 KiB 6.9 KiB +4 B (+0.1%) 7.3 KiB
Codex Live turn WebSocket wire 6.4 KiB 6.4 KiB −1 B (−0.0%) 7.8 KiB
Codex Live turn WebSocket decoded 55.5 KiB 55.5 KiB 0 B (0.0%) 66.4 KiB
Codex Live turn messages 9 9 0 (0.0%) 21
Claude Total thread wire 13.4 KiB 13.3 KiB −107 B (−0.8%) 15.1 KiB
Claude Thread snapshot wire 6.9 KiB 6.9 KiB −17 B (−0.2%) 7.3 KiB
Claude Live turn WebSocket wire 6.5 KiB 6.4 KiB −90 B (−1.4%) 7.8 KiB
Claude Live turn WebSocket decoded 56.4 KiB 56.3 KiB −88 B (−0.2%) 66.4 KiB
Claude Live turn messages 11 9 −2 (−18.2%) 21

Baseline: 6a31ea8 · PR result: 1544202 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@rynfar
rynfar merged commit fa24eb0 into pylon Aug 29, 2026
14 checks passed
@rynfar
rynfar deleted the upstream/2026-08-29-desktop branch August 29, 2026 08:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants