Repository navigation
Keep the mobile shell stable across tab changes - #30
Merged
Merged
Conversation
New tabs now inherit the active tab's viewport mode. The shell hugs the mobile viewport for as long as a mobile-emulated tab is active, so a desktop-mode new tab snapped the window back to the desktop frame on every Cmd+T / + click. Adoption records the inherited mode synchronously (the shell and the tab's container lay out from it in the same turn) and posts the DevTools overrides to the next UI-thread turn: calling ExecuteDevToolsMethod on a browser still inside its own OnAfterCreated dereferences null in CEF 151 and takes the process down. Activating a desktop tab from the mobile shell also left the tab strip overlapping itself. The activation spring animates pill frames through the animator; the window resize that follows re-laid the strip with plain `frame` sets, which do not stop an animation already in flight, so those pills sprang back to the targets computed for the 512pt strip inside a 1200pt window. Only pills whose slot happened not to move came out right. Unanimated layouts now go through the animator inside a zero-duration group, which lands the frame and cancels the spring. Also in this branch: the Reading Mode crash gate moves to ImmersiveReadAnything (the earlier "ReadAnything" name is not a base::Feature in CEF 151, so that switch was a silent no-op), and the tab strip gains horizontal scrolling with a pinned search control. Co-Authored-By: Claude Opus 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.
What
Two viewport-mode bugs, both reported from the running app.
1.
+/ ⌘T in mobile mode snapped the window back to desktop.OnTabCreatedended withUpdateWindowForViewportMode(TabIsMobile(browser_id), …), and a brand-new tab is always desktop — so adopting it animated the 512×896 mobile shell back to the saved desktop frame and re-laid the chrome on every new tab. New tabs now inherit the outgoing active tab's viewport mode (the outgoing tab is still the active one during adoption;OnAfterCreatedpromotes the new browser only after adoption returns).The overrides are applied a UI-thread turn later, via
BroHandler::AdoptTabMobileEmulation. CallingExecuteDevToolsMethodon a browser still inside its ownOnAfterCreatedis a deterministic SIGSEGV in CEF 151 (EXC_BAD_ACCESSon CrBrowserMain,OnAfterCreated → SetTabMobileEmulation → CefBrowserHostCToCpp::ExecuteDevToolsMethod) — hit while developing this, so the mode is recorded synchronously (the shell lays out from it in the same turn) and only the DevTools calls are deferred.2. Activating a desktop tab from the mobile shell scrambled the tab strip. The activation spring moves pill frames through the animator; the window resize that follows re-laid the strip with plain
framesets, which do not stop an in-flight animation. Those pills kept springing to the targets computed for the 512pt strip inside a now-1200pt window and overlapped each other. Unanimated layouts now assign through the animator inside a zero-durationNSAnimationContextgroup, which both lands the frame and cancels the spring.Measured pill geometry, 5 tabs, after switching from the mobile shell to a desktop tab:
Pills 4–5 were already correct because their slots didn't move on activation, so no animation was in flight for them — that asymmetry is what identified the cause.
Also in this branch
Uncommitted work that was already in the workspace, included here rather than stranded:
ImmersiveReadAnything; the previousReadAnythingname is not abase::Featurein CEF 151 (verified against the shipped framework), and Chromium silently ignores unknowndisable-featuresnames, so that switch was a no-op.Testing
Driven through the accessibility API against a renamed copy of the build on an isolated profile, with page state read over CDP:
+in mobile mode: window holds 512×896, toggles read Mobile, four consecutive new tabs, no crash reports.W=390 DPR=2 TOUCH=5 UA=iphone.+from a desktop tab stays 1200×800.🤖 Generated with Claude Code