Repository navigation
THI-449: recycle the webview when you leave periscope, without looping or stealing focus - #54
Merged
tdody merged 26 commits intoNov 2, 2026
Conversation
…already exists' rebuild counts as success, a per-check sweep kills leftover renderers (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nimum age and 2 GB threshold, one rebuild channel, no focus theft, sweep only with a fresh pid (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…; notifications reads it (THI-449) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…0 min of a rebuild, above 2 GB (THI-449) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…takes focus when periscope had it (THI-449) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ith a freshly read live pid; the after-recycle reaper goes (THI-449) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ld and sweep (THI-449) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…us question, each sweep kill re-checks, bad knobs fall back (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…p rechecks against the live state before each kill (THI-449) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ou were in — wry's per-webview activate() is honoured (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… --env (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… frontmost, and logs what it did (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tions record the test results and what stays untested (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…focus was what pulled focus on a rebuild; the explicit restore, set_focus and focus hand-back go (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…any other one over 256 MB; no pid is None, not 0 (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s, and a test shows a failed recheck stops further kills (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…jected submit, tested for a late Ok, an old window still registered, and giving up (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…OPE_RECYCLE_GB, and 1e30/NaN for the second knobs (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…knobs (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…r both the gate and the waiting line (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…th the two invariants on their own; recycle.rs comments drop log dates and counts (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…vation and there is no hand-back, the sweep targets renderers seen live, tests and assumptions updated (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tems_after_test_module) (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s the crash-reload gap as milliseconds (THI-449) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
The Tauri shell recycles the leaking WKWebView (destroy + rebuild the window) to free graphics memory WebKit never gives back. Until now it only did so after 5 minutes of no input to any app, so while you worked the renderer grew unchecked, to 7.7 GB at peak (THI-449).
recycle.rs), recycle when all hold:PERISCOPE_RECYCLE_GB, default raised from 1 to 2 GB. A freshly loaded dashboard is already 1.1–1.6 GB, and the old 1 GB gate looped: 62 recycles came under 90 s apart.PERISCOPE_RECYCLE_MIN_AGE_S(30 min) since the last rebuild, so no gate can loop;PERISCOPE_RECYCLE_UNFOCUSED_S(30 s), or input has been idle ≥PERISCOPE_RECYCLE_IDLE_S(300 s).focus.rs, new): one locked source for the window's focus state and how long it has been lost. Notification banners and the recycle gate both read it.on_window_readyhook restored VISIBLE on every new window, which callsset_focus(activateIgnoringOtherApps: YES). That is what pulled the user out of their app, and keystrokes typed meanwhile could reach a restored terminal pane.activate()is cooperative, and macOS declines it while another app is frontmost.await_rebuild). An attempt that timed out but did build the window counts as success; on 10-28 the loop gave up in exactly that case and leaked a 1.1 GB renderer.docs/tauri-shell.md's recycling section and thepersist.jsheader are updated. Design:docs/superpowers/specs/2026-11-01-webview-recycle-gate-design.md. Plan:docs/superpowers/plans/2026-11-01-webview-recycle-gate.md(historical; the spec is current).Test plan
cargo testinsrc-tauri/: 45 passed, covering the gate, the knob fallbacks, the focus snapshot, the sweep selection (kills only renderers seen live and never the live one), the per-kill recheck, and the rebuild loop (a late Ok, "already exists" then Ok, give-up).cargo buildandcargo clippy --testsare clean.open --env PERISCOPE_RECYCLE_GB=0.2 --env …_MIN_AGE_S=60 --env …_UNFOCUSED_S=10:Assumptions to challenge
NSApplication::activateis declined while another app is frontmost. Verified on macOS 27 only. An OS that honoured it would bring back focus theft.open --env.launchctl setenvfrom the agent's shell did not..app, not the server. The prod app needs acargo tauri buildin the prod checkout and a relaunch after merge.🤖 Generated with Claude Code