Skip to content

S5: the gap beside a lagging Chromium page shows the page's color in every motion frame - #36520

Merged
lawrencecchen merged 3 commits into
feat-cmux-nextfrom
lane/frame-owner-s5-pages-gap2
Nov 5, 2026
Merged

lawrencecchen merged 3 commits into
feat-cmux-nextfrom
lane/frame-owner-s5-pages-gap2

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

m20 item 1: in a key resize, a divider drag or a spring, a Chromium page can still show its last, smaller frame for a few refreshes. Until now the gap beside that frame showed the pane ground, and the page's own color appeared there only during the window's live resize. Now the host view under the page paints the page's background color whenever that color is known. At rest the page covers the host view, so nothing changes there.

Unchanged: see-through pages (cmux pages), and pages before their first real page, which keep the pane ground.

Testing

Command (fleet): cmux-ci run --class light --script scripts/ci/package-test-lane.sh --ref SHA --arg=suite --arg=Packages/macOS/CmuxNext --arg=CEFPageFrameOwnerTests --env CMUX_CI_XCODE_APP=/Applications/Xcode_26.6.app

  • RED (fails as expected): the test commit (621e7fe on the old stack, e8e7e7a here). Step f4e4a0f8289ab01da40b73e6: theGapBesideASmallerPageShowsThePagesColorOutsideALiveResize fails because the host view shows the pane ground.
  • GREEN at the head: PENDING.

Observed / Not run

  • Observed: the fleet red run above.
  • Not run: a film of this head. Films run after merge (m19).

Changelog

Fixed: While a pane is resized, the space beside a Chromium page that is still drawing shows the page's own background color instead of the pane color.

Proof

No capture: the change is a fill color that shows only while a page lags its pane. A pane-resize film shows it after merge.


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


Summary by cubic

Fixes the gap beside a Chromium page that lags its pane during a resize so the page's own background color appears there in every motion frame.

Until now the host view under the page painted the pane ground except during the window's live resize, so a key resize, divider drag, or spring showed the wrong color. It now paints the page's background whenever that color is known; at rest the page covers it. See-through pages and pages before their first real frame keep the pane ground.

The S5 tests now pin browserResize.layerHosting off, since #36311 made it default on and would otherwise keep pages hosted when the S5 switch is off.

Written for commit 534c153. Summary will update on new commits.

View guided diff Turn on auto-fix

lawrencecchen and others added 2 commits November 5, 2026 12:02
…lor in every motion frame (m20 item 1)

The host view under a Chromium page takes the page's backdrop only during the
window's live resize, so a key resize, a divider drag or a spring shows the pane
ground beside a page that is still at its last, smaller frame.
… every motion frame

m20 item 1. The host view under a Chromium page took the page's own background
only during the window's live resize, so a key resize, a divider drag or a
spring showed the pane ground beside a page still at its last, smaller frame.
It now takes the page's color whenever one is known; at rest the page covers
it. See-through pages and pages before their first real page are unchanged.

Red: 621e7fe, fleet step f4e4a0f8289ab01da40b73e6.

Co-authored-by: Austin Wang <austinwang115@gmail.com>
Co-authored-by: Leo <cheerleaderleo@outlook.com>
@lawrencecchen lawrencecchen added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 5, 2026
@lawrencecchen lawrencecchen added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 5, 2026
@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 534c153: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr36520 -f ref=lane/frame-owner-s5-pages-gap2 -f platform=macos -f backend_mode=local

red: cmux-next checks (god files, concurrency, crash safety, l10n); NEW: red check: Tier routing is not red on the base 33a7105; do not merge until green; see lane-rules

@blacksmith-sh

blacksmith-sh Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Found 11 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmp7tbw9r8r/summary-fail.json (live):/summary-fail.json (live): View Logs
/tmp/tmppdcu7hqa/summary-missing.json (live):/summary-missing.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs
main.DeveloperIdAppTests.test_download_prints_the_active_profile_only/
test_download_prints_the_active_profile_only
View Logs
stubs: /System/Library/Frameworks/Security.framework/Versions/A/Security has no stub/
Security has no stub
View Logs
stubs: CoreFoundation.tbd: install-name /System/Library/Frameworks/
CoreFoundation.framework/Versions/A/CoreFoundation, missing 1: ['_CFRetain']/
CoreFoundation, missing 1: ['_CFRetain']
View Logs
stubs: CoreFoundation.tbd: install-name /System/Library/Frameworks/
CoreFoundation.framework/Versions/A/CoreFoundation, missing 1: ['_log2']/
CoreFoundation, missing 1: ['_log2']
View Logs

...and 1 more test failures. View all on Blacksmith

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

…ault since #36311)

CEFPageFrameOwnerTests.flippingTheSwitchHostsAShownPageAtOnce failed on feat
after #36311 made layerHosting default on: hosting is wanted when either
switch is on, so turning motion.frameOwner.pages off kept the page hosted
(steps 03c819d014597a248f63de0c, 8d2c8b66b55f172e80f98bfc). The suite now
pins layerHosting off whenever it sets the S5 switch.
@lawrencecchen
lawrencecchen merged commit 09d1234 into feat-cmux-next Nov 5, 2026
183 of 187 checks passed
@lawrencecchen
lawrencecchen deleted the lane/frame-owner-s5-pages-gap2 branch November 5, 2026 12:55
lawrencecchen added a commit that referenced this pull request Nov 5, 2026
…e frame; the gap shows the page's color

Lawrence 2026-11-05: "we need to try to resize webviews (both chrome and webkit) more often so it is smoother.
make sure it gets merged."

- WebKitPageContainer conforms to BrowserPagePaneMotionHolding and never holds: the browser chrome follows its pane's
  content area in every key-resize frame (FRAME OWNER S3 PaneMotionHoldFollowing), Auto Layout gives the container the
  page area in that frame's layout pass and the WKWebView takes it at once (autoresizing). Before, a WebKit page could
  not follow, so the area held the whole chrome at its start size until the spring landed.
- One per-frame size source with Chromium S5 (agreed with the RESIZE OWNER and S5): the chrome's page area in the
  motion frame's layout pass; no engine computes its own size, only the newest frame per display frame, no wait, no
  skipped frame. Divider drags already laid WebKit out live; no change there.
- The gap where WebKit has not drawn the new size shows the web view's own layer background. WebKit paints it white
  (or the dark control color); it now takes the document's background (WebKit's _setBackgroundColor: SPI, checked
  first), read when a document finishes and when a key resize starts, reset at each commit (WebKitTab+ResizeBackdrop,
  the WebKit half of #36520). browserResize.pageBackdrop off keeps WebKit's default.

ON by default, no switch. Red test: WebKitPagePaneMotionTests (d512810).
lawrencecchen added a commit that referenced this pull request Nov 6, 2026
…p shows the page's color (#36590)

* test(browser): WebKit red: a WebKit page takes its pane's size in every key-resize frame, and its gap shows the page's color

Lawrence 2026-11-05: "we need to try to resize webviews (both chrome and webkit) more often so it is smoother."
In every frame of a key resize (and of a divider drag) a WebKit page's web view must be at its pane's page area,
inside the pane, and the web view's own background (what shows where WebKit has not drawn the new size yet)
must be the page's background color.

Fails on feat today: a WebKit page cannot follow a key hold (FRAME OWNER S3), so the pane's content area holds
the whole browser chrome at its start size until the spring lands; the web view's background is WebKit's
default control color. The divider-drag case is green today (regression cover).

* feat(browser): WebKit pages take their pane's size in every key-resize frame; the gap shows the page's color

Lawrence 2026-11-05: "we need to try to resize webviews (both chrome and webkit) more often so it is smoother.
make sure it gets merged."

- WebKitPageContainer conforms to BrowserPagePaneMotionHolding and never holds: the browser chrome follows its pane's
  content area in every key-resize frame (FRAME OWNER S3 PaneMotionHoldFollowing), Auto Layout gives the container the
  page area in that frame's layout pass and the WKWebView takes it at once (autoresizing). Before, a WebKit page could
  not follow, so the area held the whole chrome at its start size until the spring landed.
- One per-frame size source with Chromium S5 (agreed with the RESIZE OWNER and S5): the chrome's page area in the
  motion frame's layout pass; no engine computes its own size, only the newest frame per display frame, no wait, no
  skipped frame. Divider drags already laid WebKit out live; no change there.
- The gap where WebKit has not drawn the new size shows the web view's own layer background. WebKit paints it white
  (or the dark control color); it now takes the document's background (WebKit's _setBackgroundColor: SPI, checked
  first), read when a document finishes and when a key resize starts, reset at each commit (WebKitTab+ResizeBackdrop,
  the WebKit half of #36520). browserResize.pageBackdrop off keeps WebKit's default.

ON by default, no switch. Red test: WebKitPagePaneMotionTests (d512810).

* bench(pane-perf): --browser-engine webkit and a held key-resize action (keys)

To measure WebKit pages in key resizes and drags, before and after (RESIZE OWNER check 2): main-thread layout
work per motion frame, CA commits and missed refreshes, light and heavy layouts. --browser-engine webkit opens the
probe page and the --pages pages as WebKit pages; keys presses resizePaneRight 12 times at key-repeat pace,
then resizePaneLeft 12 times, through the action path that takes the key-resize hold. Report only.

* fix(browser): review: parked WebKit pages resize once when shown; gap color from the isolated world, WebKit default when the page has none

Review of #36590 (independent subagent, SHIP with should-fix items):
- A parked WebKit page (hidden in its pane's page area) no longer takes a frame in every key-resize or drag frame:
  WebKitPageContainer defers its subviews' resize while hidden and applies it once when it shows (no view work the
  person cannot see).
- The gap color read runs in the isolated world, and a page with no background of its own keeps WebKit's default
  (white, or dark with the page's color scheme) instead of the CEF script's white fallback.
- Tests: the key resize reads the page's color again (a page that changed its background after load); a parked page
  takes no frame during a key resize and its page area's size when shown. The drag test is marked as a guard.
- Bench keys: 4 presses each way (5% each), so the split comes back between rounds; key names fixed.

* fix(browser): review: crash-allow reason on the guarded _setBackgroundColor: selector; the color re-read test waits for the load's read first

* crash ratchet: record the reviewed crash-allow waiver for the guarded _setBackgroundColor: selector (CmuxNextBrowser dynamic_dispatch.waived 11 -> 12)

* fix(browser): the WebKit resize gap always shows the page's color (#36862 deleted browserResize.pageBackdrop)

* fix(browser): a parked WebKit page keeps its pane's size again; the color re-read test checks the stored color

Focused step 4ade61d1 at a368f6c failed 2 of 5 WebKitPagePaneMotionTests:
- aParkedWebKitPageResizesOnceWhenItShows: a parked page shown again stayed at its parked width (600 pt in a 480 pt
  page area). The deferral of a hidden page's resize until it shows (a781cbc, from the first review's cost note) did
  not catch up. It is removed: a parked page follows its page area through autoresizing again, as in a divider drag.
  The test now checks only that the page has its page area's size when it shows (renamed
  aParkedWebKitPageHasItsPaneSizeWhenItShows).
- aKeyResizeReadsThePagesColorAgain: its setup polled the web view's layer color with no display pass. It now waits
  for the stored color of the read at load (pageBackdropARGB) before it changes the page's color.

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 534c1532 Deployed Nov 5, 2026 by lawrencecchen via cmux-tui tree preflight #116101
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