Skip to content

fix(focus): keys typed right after a reopen wait until the restored page has loaded, then reach it in order (dogfood port of #32633) - #32684

Draft
lawrencecchen wants to merge 6 commits into
cp/dogfood-v2-2-12-optfrom
fix/p0-reopen-browser-plain-keys-dogfood
Draft

lawrencecchen wants to merge 6 commits into
cp/dogfood-v2-2-12-optfrom
fix/p0-reopen-browser-plain-keys-dogfood

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Dogfood port of #32633 (P0 reopen-browser-plain-keys, cycle B; journey kit cp/reopen-video-kit@4ff1d5e5ce6). After Cmd-Q (keep) and reopen, plain keys typed at once into a restored web page were lost. Lawrence's rule: a key typed before the restored content is ready is held and delivered in order, never dropped.

Cause (as on feat, REOPEN VIDEO 7493, 7660, 7710, 7801): the window key hold awaited a restored Chromium tab only until its pane showed the content. The tab shows before Chromium creates its browser, and its first loads are an empty document and documents that the same load replaces. Keys sent on at any of those points were lost.

Fix, same rule as #32633:

  • A shown Chromium tab is awaited until its page is ready for keys (AwaitedContent.Pane.shownPageReady, BrowserTab.pageReady). It is ready when Chromium created its browser and stopped loading (.loadingState(loading: false)) with a real (not blank) document loaded, or with an error page. An aborted load is no page, and a new commit forgets the document loaded before it (Chrome's DidStopLoading).
  • CEFTab.onReadyForKeys reports it once per browser and writes ready-for-keys to the lifecycle trace. TabContentCache forwards it to onBrowserReady. On this line onBrowserReady did not end a page hold (only a focus settle did), so it now calls the new CreationInputCoordinator.pageArrived, which flushes the holds that await that tab, each key once, in order.
  • Bound and end for a page that never gets ready: the hold ends at holdLimit (2 s) and its keys go on in order. This line lacked feat's CreationHoldLog.pageExpired (fix(focus): the reopen key hold also waits for a restored browser tab's page; Cmd-L reaches its address bar (REOPEN-F4 browser case) #32030), so with the new readiness rule the next key would open a new 2 s hold for the same page. This PR ports it: a page whose hold ended at its bound is not held again until it is ready.
  • Paid back the 5 app lines (arch ratchet) by folding two one-line if blocks in TabContentCache and the onBrowserReady line.

Cost: none per key. One flag check when a hold decides what it awaits; one callback per browser.

Testing

Fleet, 5 runs each, proof-step.py (step ids follow in a comment when done):

Observed / Not run

Changelog

Fixed: Keys you type at once into a web page that a reopen restores reach the page, in order

Proof

No capture: key routing; the proof is the tests and the journeys.


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes lost keystrokes after a reopen: keys typed right after Cmd-Q (keep) and reopen now wait until the restored Chromium page has actually loaded, then reach it in order.

After a reopen, a restored Chromium tab showed in its pane before Chromium created its browser, and its first loads were an empty document or documents the same load replaced, so keys sent immediately never reached the page.

  • A shown Chromium tab is awaited until its page is ready for keys: Chromium created its browser and stopped loading with a real document or an error page loaded; an aborted load is no page, and a new commit forgets the previously loaded document.
  • A page asked to show something waits for that document, so a reopen by address no longer sends keys to the empty document before its navigation; a page with nothing to load takes keys once Chromium creates it, and a blank target counts its blank document.
  • Cmd-L passes an empty page hold once the page exists, so the address bar does not wait for the restored document.
  • CEFTab.onReadyForKeys reports once per browser, and the hold's keys are flushed once each, in order, when the page arrives.
  • A page that never gets ready ends the hold at its 2 s bound, and is not held again until its page arrives (ports pageExpired from fix(focus): the reopen key hold also waits for a restored browser tab's page; Cmd-L reaches its address bar (REOPEN-F4 browser case) #32030).
  • Tests cover the readiness rule, the bound, the blank-tab and fresh-page cases, and that no held key is delivered twice or out of order.

Written for commit 2001f3b. Summary will update on new commits.

View guided diff Turn on auto-fix

…d loading on a real document or an error page; a page that never gets ready is not held again after its bound; two ready signals never send a held key twice (reopen-browser-plain-keys cycle B, dogfood port of #32633; red: the behavior is stubbed)
…age stopped loading on a real document, then reach it in order; a page that never gets ready ends the wait at its bound (reopen-browser-plain-keys cycle B, dogfood port of #32633)
@lawrencecchen lawrencecchen added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 2, 2026
…s document, a restored blank tab counts its blank one, and Cmd-L passes an empty page hold once the page exists (dogfood port of the #32633 review fix; red: stubs)
…a restored blank tab counts its blank one); a New Tab page and other new pages take keys once Chromium created them, and Cmd-L passes an empty page hold once the page exists (dogfood port of the #32633 review fix)
…that page, not the empty document before its navigation; a page with nothing to load is ready at once (dogfood port; lead on STATUS 7916; red)
…cument, a page with nothing to load is ready at once, and only a blank target counts a blank document, so a reopen by address no longer sends held keys to the empty document before its navigation (dogfood port; lead on STATUS 7916)
@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Not needed: the dogfood line is retired as a dogfood source; dogfood builds come from the feat tip (lead, STATUS 7979). The fix lands through the feat PR (link below) and reaches dogfood with the next feat dogfood build. Feat PR: #32633.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant