fix(desktop): throttle hidden preview rendering - #7445
Conversation
Co-authored-by: maria <254055478+maria-rcks@users.noreply.github.com>
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 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.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR changes runtime behavior by dynamically managing background throttling for preview rendering rather than having it always disabled. The state management added is non-trivial and affects core desktop app functionality, warranting human review. You can add or adjust custom eligibility rules. Learn more. |
Co-authored-by: maria <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: maria <254055478+maria-rcks@users.noreply.github.com>
There was a problem hiding this comment.
Effect service conventions review: one finding on error modeling in apps/desktop/src/preview/Manager.ts. Everything else (namespace subpath imports, Effect.fn/Effect.fnUntraced usage, ref-based state handling, and the tests) matches the conventions.
Posted via Macroscope — Effect Service Conventions
Co-authored-by: maria <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: maria <254055478+maria-rcks@users.noreply.github.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 08bcce8. Configure here.
Co-authored-by: maria <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: maria <254055478+maria-rcks@users.noreply.github.com>
## What's Changed * fix(desktop): throttle hidden preview rendering by @t3-code[bot] in pingdotgg/t3code#7445 * fix(server): stop probing Grok, Cursor, and OpenCode unless turned on by @t3dotgg in pingdotgg/t3code#7459 * fix(desktop): boot the main window unthrottled so cold start paints at full speed by @t3dotgg in pingdotgg/t3code#7460 * fix(threads): a merged PR settles its thread only once by @t3dotgg in pingdotgg/t3code#7454 * feat(cli): npx t3 triage hands broken installs to your own coding agent by @t3dotgg in pingdotgg/t3code#6563 **Full Changelog**: pingdotgg/t3code@v0.0.34-nightly.20260819.1129...v0.0.34-nightly.20260819.1130 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.34-nightly.20260819.1130
pingdotgg#7437, pingdotgg#7459, pingdotgg#7460, pingdotgg#7445, pingdotgg#7122, pingdotgg#7317, pingdotgg#7381, pingdotgg#6563) Where upstream reworked something the fork had already built, upstream's version wins and the fork's extras ride on top: - Browser tab mute (pingdotgg#7252): upstream's rollback-on-refusal setAudioMuted and tabMuteMenuItem replace the fork's earlier copies; the fork's guest viewport override (setViewport/automationSetViewport) stays. - Passkey autofill (pingdotgg#7437): upstream's `passkeys` const replaces the fork's duplicate manualOnlyPasskeys. - Settle-once-on-merge (pingdotgg#7454): the sidebar now reports the whole change request (state + updatedAt) instead of a bare state, so the new rules can tell a fresh merge from inherited branch history. The fork's per-row reporting stays; upstream's semantics win. - Merge action labels (pingdotgg#7381): upstream's confirmation state object, extended with the fork's merge-stack action. Also: Clerk v6 moved `layout` into `options`, so the appearance override moves with it, and the connect-providers helper joins the web tsconfig include list. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com> Co-authored-by: maria <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com> Co-authored-by: maria <254055478+maria-rcks@users.noreply.github.com> (cherry picked from commit fe281c5)
* test(web): remove duplicate lookup assertion (pingdotgg#7364) * fix(mobile): show structured input option descriptions (pingdotgg#7321) * fix(orchestration): do not revive idle tasks from status-free progress (pingdotgg#7172) * refactor(server): simplify error transformation with Effect.mapError in GitHubPullRequestCli (pingdotgg#7385) Signed-off-by: aoright <102943475+aoright@users.noreply.github.com> * fix(preview): open local environment ports on localhost (pingdotgg#7300) * fix(desktop): prevent quit shortcut spillover (pingdotgg#7397) * fix(desktop): stop overwriting a custom dock icon on launch (pingdotgg#7125) * feat(web): show project location in new thread picker (pingdotgg#7392) Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com> * fix(packaging): install AUR launcher icons where icon themes look (pingdotgg#7421) * fix(web): label pull request merge actions (pingdotgg#7381) * fix(server): avoid PRs inherited from default upstreams (pingdotgg#7317) * fix(desktop): stop the passkey dialog from popping as soon as sign-in opens (pingdotgg#7437) * feat(desktop): mute a browser tab (pingdotgg#7252) * fix(web): improve disconnected composer placeholder (pingdotgg#7122) Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com> Co-authored-by: maria <254055478+maria-rcks@users.noreply.github.com> * fix(desktop): throttle hidden preview rendering (pingdotgg#7445) Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com> Co-authored-by: maria <254055478+maria-rcks@users.noreply.github.com> * fix(server): stop probing Grok, Cursor, and OpenCode unless turned on (pingdotgg#7459) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(desktop): boot the main window unthrottled so cold start paints at full speed (pingdotgg#7460) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(threads): a merged PR settles its thread only once (pingdotgg#7454) * feat(cli): npx t3 triage hands broken installs to your own coding agent (pingdotgg#6563) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(marketing): Safari gets the arm64 Mac download (pingdotgg#7473) * feat(web): add shortcuts to the surface dropdown (pingdotgg#7318) * fix(marketing): never serve the Intel build to Apple Silicon Macs (pingdotgg#7477) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(web): animate command palette when closing (pingdotgg#5169) * fix(desktop): upgrade Clerk OAuth transport (pingdotgg#7479) * feat(server): run the background service on macOS via launchd (pingdotgg#6286) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(web): align sidebar statuses with project names (pingdotgg#7491) Co-authored-by: GPT-5.6 <noreply@openai.com> * fix(desktop): close the window before quit cleanup (pingdotgg#6562) * fix(desktop): stop automatic passkey prompts (pingdotgg#7522) * docs(user): document phoenix triage and macOS background service The 2026-08-19 upstream sync added the triage command with no docs/user entry, and the docs index still called the background service Linux-only after launchd support landed. Found by PR #61 code review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Signed-off-by: aoright <102943475+aoright@users.noreply.github.com> Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com> Co-authored-by: Nick Anisimov <n.anisimov.23@gmail.com> Co-authored-by: Maslin Edwin <maslinje@gmail.com> Co-authored-by: aoright <102943475+aoright@users.noreply.github.com> Co-authored-by: Guilherme Barros <gbarros1095@gmail.com> Co-authored-by: Bilal Bakr <62337003+Bil0000@users.noreply.github.com> Co-authored-by: Rishet11 <154429365+Rishet11@users.noreply.github.com> Co-authored-by: Wout Stiens <71498452+StiensWout@users.noreply.github.com> Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com> Co-authored-by: Augie <augie@luebbers.email> Co-authored-by: Taras <Taras.Fomin@gmail.com> Co-authored-by: Gianmarco <gianmarcosimone89@gmail.com> Co-authored-by: Theo Browne <me@t3.gg> Co-authored-by: Chris Deeming <chris@xenforo.com> Co-authored-by: Inaya Yousfi <zied.essaber@gmail.com> Co-authored-by: maria <254055478+maria-rcks@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Rakshith Bhat <88523594+RakshithBhat03@users.noreply.github.com> Co-authored-by: GPT-5.6 <noreply@openai.com>

problem
the desktop window disabled electron background throttling for its entire lifetime. electron keeps that window and every hosted preview renderer drawing even when t3 code is hidden or occluded, which can leave preview tabs consuming substantial cpu and energy.
fix
runtime probe
on linux with electron 41.5.0, a hidden-window animation ran 240 frames over four seconds with the current global override, versus 0 frames with default throttling restored.
testing
vp test run apps/desktop/src/preview apps/desktop/src/window(204 passed)vp run --filter @t3tools/desktop typecheckvp check apps/desktop/src/preview/Manager.ts apps/desktop/src/preview/Manager.test.ts apps/desktop/src/window/DesktopWindow.ts apps/desktop/src/window/DesktopWindow.test.tsimplemented with gpt-5.6-sol through hermes agent.
request provenance
Note
Medium Risk
Changes preview frame-capture and main-window lifecycle timing; incorrect throttling could affect recording quality or background CPU, though behavior is heavily covered by new tests.
Overview
Stops forcing
backgroundThrottling: falseon the desktop main window at creation so hidden/occluded windows can idle normally again. PreviewManager now callssetBackgroundThrottling(false)when the first frame-capture consumer starts (recording or picture-in-picture) andtruewhen the last one stops, with retries and warnings if restore fails.Session start/stop and
setMainWindowreconciliation are made interruption-safe (uninterruptiblepaths). Replacing the main window re-applies unthrottled mode if captures are already running; staleclosedhandlers from old windows are ignored. On close, active recordings and PiP are torn down viastopAllRecordings.Starting capture after the main window has closed fails with
PreviewMainWindowClosedErrorinstead of continuing in a bad state. Tests cover multi-tab refcounting, failed throttle updates, window swap races, and shared capture between recording and PiP.Reviewed by Cursor Bugbot for commit 7281787. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Throttle main window background rendering only during active frame capture
backgroundThrottling: falsefromDesktopWindowcreation; throttling is now managed dynamically byPreviewManagerbased on capture state.setMainWindow, throttling is disabled on the new window if captures are active; close events from the replaced window are ignored.PreviewMainWindowClosedErrorso callers get a typed failure when attempting to start capture while the main window is closed.backgroundThrottlingforced tofalseat creation time; the setting defaults toundefinedand is toggled only during active capture.Macroscope summarized 7281787.