Skip to content

Browser: in a keyboard resize a Chromium page moves with its pane's top-left corner, never scaled (cmux-ad m6 1b) - #35195

Merged
lawrencecchen merged 21 commits into
feat-cmux-nextfrom
fix/frame-owner-browser-key-topleft
Nov 4, 2026
Merged

lawrencecchen merged 21 commits into
feat-cmux-nextfrom
fix/frame-owner-browser-key-topleft

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

cmux-ad m6 1b, the interim browser contract for key resizes (FRAME OWNER REFACTOR, STATUS 11198), until S5's layer hosting. Lawrence: "tabbar moves smoothly on ctrl shift hjkl but browsers/terminals do not anymore". Stacked on #35161 (the S3 switch delete, itself on #35140 S3d): its base is that branch, and it retargets to feat-cmux-next as they merge.

Frames (what a person sees in each frame of a keyboard resize, per content kind; before = feat with S3, after = this PR):

  • Frames: Chromium page. Before: the page kept its size and stood still at the pane edges that do not move. A pane whose left edge moved slid over it, so the page's left edge was off its pane's left edge in every motion frame (refactor owner's films on build 437f5a22, STATUS 11448: 0 of 190 frames aligned for held keys, up to 1504 device px inside the pane; 0 of 50 for single presses, up to 114 px; the top edge 0 of 48 on Ctrl-Shift-J/K, up to 76 px). After: the page keeps its size (never scaled) and its top-left corner is on its pane's page area in every frame, so it moves with the pane's left and top edges, as the tab strip does. The pane clips it on the right and bottom, and the page's own backdrop fills the area beyond it. Chromium still gets one new size per press, after the landing.
  • Frames: terminal, agent chat, tab strip. No change (terminals are FRAME OWNER S4's, frame-owner-s4).

How: CEFTabContentView.layoutContent places a key hold's page at the page frame's top-left corner, the corner a hold-mode divider drag already uses. It no longer rides S3's hold edges (PaneMotionHold.producerFrame on the edges that do not move). The page window follows its host view in each motion frame through the existing path (CEFHostView.pagesNeedUpdate: one geometry post per moved page, budget 0.2 ms), the one a hold-mode divider drag uses. This is way (a) of STATUS 11198, and it needs no new CEF API.

Switch: browserResize.keyResizeTopLeft (Debug Settings > Browser Resize), default on, latched when each key hold begins (CEFTabContentView.pageHoldTopLeft). A kill switch only: it goes once the refactor owner's off/on film passes. Off is exactly S3's placement.

Snapshot (contract item 1): CEFTabContentView.snapshotView (an NSImageView with .scaleAxesIndependently) was dead code: it was never added to a view and never given an image, so it never showed. It is deleted.

Area owners: PL-cef-layer (CEFHostView.swift, the tab container in it) and PL-motion-cef; told in STATUS 11449 and 11541.

Testing

Red first (its own commits before the fix): CEFDeferredTabShowTests.aKeyResizeHoldKeepsThePageOnThePageAreasTopLeft. A live page in its pane's container holds for a key resize whose trailing edge stays (S3's hold edges). The container's leading edge moves right 120 pt, left to -120 pt, and back. In every frame the page's top-left must be on the page area's top-left (0.5 pt) at its held size; the pane must clip it, the backdrop must be the page's own, and the page must take its area's size when the hold ends.

  • Red: step 8566def7396ab25b5fb418a1 at f7c8033: failed as expected. The page was at x -10, -20, -30 ... in its area, so its left edge was outside the pane. The other 13 CEF tests passed. (The first red, 619eb26, did not compile: the test's step list was too complex to type-check, step f4e4827a1e6a5a3eca7c65c1; f7c8033 types it.)
  • Green: step fcb1bb74cc4790d868503734 at this head dbf5c8b: 11 of 11 suites passed (CEFDeferredTabShowTests, BrowserChromePaneMotionParkTests, BrowserChromeSharedEdgeTests, BrowserPaneOneContainerTests, PaneGroundCoversPaneTests, PaneContentPolicyTests, KeyboardResizeContentHoldTests, KeyboardResizeReflowAfterLandingTests, PaneContentAreaHoldTests, FrameOwnerS1HoldPathsTests, InternalPageParkingTests).

GUI proof on a display worker (--display --label gui-session-v1) at this head: step 9e8883aba9a4de1b8cccddb6 (cmux12s-Mac-mini): 6 of 6 suites passed (CEFDeferredTabShowTests, BrowserChromePaneMotionParkTests, BrowserChromeSharedEdgeTests, BrowserPaneOneContainerTests, PaneGroundCoversPaneTests, PaneContentPolicyTests).

Review

Codex (gpt-6.1-sol, codex exec --sandbox read-only, no tools on this VM: the diff, the changed files and their callees in the prompt), round 1 at this head: SHIP, no findings. Receipt comment below.

Changelog

Fixed: In a keyboard pane resize, a browser page now moves with its pane's left and top edges in every frame, as the tab bar does, instead of standing still while the pane slides over it.

Proof

No capture: a motion change; the refactor owner's off/on 120 Hz films (px-keys-held-2-s1r, px-keys-single-3k-s1r: the page's left and top edges within 1 device px of its pane's in each frame, or the frame before) are the proof, on a Release build of this head.

Observed / Not run

Observed: the red and green steps above (fleet, owned Macs).
Not run or not observed by me: the 120 Hz films; the main-thread time per motion frame with a real Chromium page (unit tests have no Chromium runtime; the page window move uses the existing per-frame geometry post, measured by the films' pacing); a page with DevTools docked, a side panel or a device fit (they lay out live as before; read, not run).

lawrencecchen and others added 20 commits November 3, 2026 21:53
…k shows no shell (FRAME OWNER S3c, red)

The Claude re-review of #34170 at 7827a1f (P1, not a regression): a close of the
last column of a strip whose camera moves back shows the shell where the column was
(film P12: the close of a new column, about 700 -> 10 px over 22 frames). No pane
frame moves in reconcile, only the camera, which syncScroll sets after it: the
closing pane is hidden as one nothing closes over, and releaseRetired tears it down
before the camera starts.

New file PaneCloseCameraGroundTests: a full-width column and a 2/3 one, the camera
on the right one, Cmd-W on it. In every frame the window is covered by pane hosts
beyond the gaps at rest, and the closing pane's last frame shows no ground for the
landing to take away. Expected red at this commit; run on the fleet with --red.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…its gap in every frame of a close (FRAME OWNER S3d, red)

R-HARNESS's divider check on the refactor owner's films: during a close, a handle's rect was
up to 15 device px off the middle of the gap between its two panes, so a press on it could miss
by 7 pt. With S3 on, a closing pane shows its ground on its place; the gap a person sees beside
it must be the one whose handle stays.

PaneCloseKeptHandleTests closes a pane and checks, in the close's first frame, each spring frame
and at rest, that along the line through the kept handle's centre the run no pane host covers
(live, or closing with its ground) holds the centre, centred within a point:
- the divider on the closing pane's trailing side (p1 | p2 | p3 made by splitting p1 of
  p1 | p3, close p2): red now, the closing ground covers that gap;
- the divider below the closing pane (p1 | p2 over p3, close p2): red now;
- the edge of a column whose right split pane closes: red now;
- the edge before the strip's last column while the camera moves back: red now (the
  closing pane hides at once and the closed place shows the shell);
- guards, green now: the films' px-close-pane-3 (the divider on the leading side) and
  px-close-column-c3 (the edge before a closing middle column).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o its camera springs back (FRAME OWNER S3d, red)

Red step ef256026fc9d27421a89b2a0 at 9c25336: the two camera cases closed the second of two
columns. A strip left with one column becomes a split screen (LayoutModel.removingColumn):
there is no camera to move back and no column edge after the close, and the remaining pane
slides in on its own spring (S3c already covers that close). So PaneCloseCameraGroundTests
stopped at its SETUP check (the camera rests at once) and the kept-handle case found no
handle.

Both now use three half-width columns with the camera at the end and close the third: two
columns stay, no pane frame moves, only the strip camera springs back (as
ColumnCloseScrollMotionTests' columns(3)). The kept handle is the edge of the second column.

The other results of that step stay as the red evidence: 3 cases red as expected (the closing
ground covers the kept divider's gap on the trailing side, below, and beside a column edge),
2 guards green (the films' px-close-pane-3 and px-close-column-c3).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, and the strip's last column closes on the camera (FRAME OWNER S3d)

Two follow-ups of S3c (#34170), red first (PaneCloseCameraGroundTests, PaneCloseKeptHandleTests).

1. The gap that shows is the kept handle's. A closing pane used to keep the gap only on its
   leading side (when its trailing side had neighbours too). Where the handle that stays is on
   its trailing or bottom side (a split pane's right sibling closing, a column's right split pane,
   the pane above a kept divider, the strip's last column), the closing ground covered the gap
   under that handle, and the shell showed beside the gap whose handle had gone: the handle was
   off its gap by up to the closing pane's width. Now each side looks up the handle in its gap in
   the layout the pane left (split dividers, column edges, row edges, in the pane's own space) and
   keeps the gap if the new layout keeps that handle; where the handle goes it covers the gap. The
   pane still rests at zero size where its neighbours meet (they meet one kept gap apart).

2. The strip's last column. Closing it with two or more columns left moves no pane: only the
   strip camera moves back. S3c hid such a pane at once (nothing closes over it), so its place
   showed the shell while the camera moved (film P12). A closing pane now waits for the camera
   the change sets (ScreenContentView.settleClosing, in syncScroll before the change's first
   frame): a side with no neighbour, opposite one with neighbours, collapses on the share of its
   space's camera travel (the strip's, or its row column's scroll) when no neighbour moves, so the
   pane rests at zero size when the camera does. A pane that nothing moves over still hides at
   once, as before; with nothing moving at all the retired hosts still go in the change's turn.

No new owner, timer or hold: the closing pane's rect stays a function of its neighbours' springs
and its space's camera, read each frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rried panes; the last row of a scrolling column closes on its scroll (FRAME OWNER S3d, red)

Red step ca6953a3b97f1ff22fa99cdf at e8878b7: the column case still stopped at its SETUP
check. A column's removal clamps the strip camera to the new end at once (ColumnScrollReducer:
"the view carries the panes horizontally from where they showed"), so no strip camera springs
back: the neighbour's frame is carried and springs from where it showed, and starts moving
only in syncScroll (settleCarried), after reconcile decided under S3 that nothing moves beside
the closing pane. The kept-handle case at that step was red for the right reason (the handle
292 pt off the middle of the closed place's shell, 610...1200).

- PaneCloseCameraGroundTests: the column case checks that the close moves the strip (not that
  the camera springs) and reuses ColumnCloseScrollMotionTests.columns(3). New case: one column
  of four 400-permille rows scrolled to the fourth, Cmd-W on it; three rows still overflow, so
  the row column's scroll springs back (a row camera keeps its spring) and no pane frame moves.
  Both check every frame along the line across the closed place and the ground left for the
  landing.
- PaneCloseKeptHandleTests: the camera case reuses columns(3) and is named for the strip's shift.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…; the strip's shift is its carried panes' (FRAME OWNER S3d)

The strip camera never springs back for a close: a column's removal clamps it to the new end at
once and the view carries the panes from where they showed (ColumnScrollReducer), so the last
column's neighbour moves and its closing pane collapses on that neighbour's travel. The strip
camera share of 447bb3a had no case to serve: it is gone. What the strip's last column
needed is the other part of that commit: which closing panes nothing moves over is decided once
the change's cameras are set (settleClosing, after syncScroll's settleCarried), when the carried
neighbour already springs.

A row camera keeps its spring: closing the last row of a column whose rows still overflow moves
no pane, only the row column's scroll. That travel (ClosingPanes.Entry.rowTravel) collapses the
free side of a closing pane whose other y side rides a neighbour that does not move.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…OWNER S3d, red)

Codex review of 447bb3a (P1): a closing pane keeps the scroll travel it took at its close,
so a later change that takes the row scroll to another target leaves its collapse stale. The
same case shows a second hole: the first closing pane rides the second one, and closing panes
are placed in the order they closed, so the first reads where the second last was while the
second's free side moves away (the shell between them).

PaneCloseCameraGroundTests.twoLastRowClosesInARowLeaveNoHole: five 400-permille rows scrolled
to the fifth, the fifth closes, and six frames later the fourth (the row scroll takes another
target). Every frame along the column's middle shows no more shell than the rest gaps, and the
closing grounds leave under a point for the landing. The check closes a list of panes, and the
ground left for the landing is what only closing grounds cover.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…and rides a later close where it shows (FRAME OWNER S3d)

Red first: PaneCloseCameraGroundTests.twoLastRowClosesInARowLeaveNoHole.

- When its row column's scroll takes another target (a later change), a closing pane's travel
  starts again from where the scroll and its y sides show now (ClosingPanes.rects), so it still
  rests at zero size when the scroll lands; with no travel left it rests at once. The scroll's
  target is read every frame with its value (ScreenContentView.rowScrollTravel).
- Closing panes are placed from the last to close back to the first. A pane borders only panes
  live at its close, so no closing pane rides one that closed before it; one that closed earlier
  now reads where the later one shows in this frame instead of where it last was. The first of
  two closes in a row no longer leaves the shell between them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…aves no ground (FRAME OWNER S3d, red)

Codex review of 02de7be (P1): close the fourth of four 400-permille rows, then the third
before the first lands. The two rows left fit, so the row scroll goes and the second row
springs to its rest. The fourth closing pane rides the third, a closing pane, so it has no
rest to collapse toward (a rest is read from live neighbours only) and no scroll travel left:
its free side freezes and its ground stays for the landing to take away in one frame.

PaneCloseCameraGroundTests.aSecondLastRowCloseThatMakesTheRowsFitLeavesNoGround checks every
frame along the column's middle and the ground only closing panes cover before the landing.
Red step 03270980560f5bd06b1d21bc at 7fdf9f7 already showed the first two-closes case red
for its reason (up to 109 pt of shell between the two closing panes, frames 7 on).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s where that one rests (FRAME OWNER S3d)

Red first: PaneCloseCameraGroundTests.aSecondLastRowCloseThatMakesTheRowsFitLeavesNoGround
(Codex review of 02de7be, P1).

- ClosingPanes.rects keeps, for each pane it places, where it rests (zero size where its sides
  meet: a side on its neighbours' rest, a free side on the rest of the side opposite). A side
  that rides a closing pane (one that closed after it, placed earlier in the pass) reads that
  rest, as a side on a live pane reads its target frame. The free side opposite it then
  collapses toward where that pane rests, and still reaches zero size when the row scroll that
  drove it is gone (the rows fit).
- A free side's travel now remembers its end (Side.end). When the end moves (a later change, a
  neighbour that closed too) or the row scroll takes another target, the travel starts again from
  where both sides and the scroll show now: the free side never jumps when its driver changes. A
  coordinate change (carry, shiftY) moves the end with the side.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…part from the live panes (FRAME OWNER S3d, red)

R-HARNESS pair C judges each divider rect against the gap between the panes beside it, and its
judge reads closing panes as rows of the trace ("any pane row counts, a closing one too"). The
trace has none: the sampler skips every host that shows a closing ground (S3, so the live-pane
judges do not take a ground for a pane whose content is gone). So on an S3 build the judge
sees the closed place as the gap and reports the kept divider off its middle, as on a base
build.

PaneCloseKeptHandleTests.theTraceReportsAClosingPaneApartFromTheLivePanes: in a close's first
frame, the sample lists the closing pane under `closing` with the rect its ground shows at, and
not under `panes`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ng` (FRAME OWNER S3d)

Red first: PaneCloseKeptHandleTests.theTraceReportsAClosingPaneApartFromTheLivePanes.

ScreenContentView.motionSample (DEBUG and bench hooks only) now reports each shown closing pane's
ground as `[pane, x, y, width, height, alpha, z]` under a new `closing` key, apart from `panes`,
whose rows also say how live content is laid out (a closing ground lays out none). A trace judge
that centres a handle on the gap between its panes can now read the closing ground beside it
(R-HARNESS pair C); the live-pane judges read `panes` as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…st the strip (FRAME OWNER S3d, red for d369376)

The red for d369376 (a closing pane that rides another closing pane rests where that one
rests). af48fab's row case passed without that fix (step cadeb2ac05f197c36580c860): rows
that fit fill their column, so the frozen free edge of the old code was already at its rest.
That case stays as a guard.

PaneCloseCameraGroundTests.twoLastColumnClosesInARowLeaveNoGroundPastTheStrip: four 0.3-wide
columns (new columns keep their width), the camera at the end on the fourth; the fourth closes,
and six frames later the third. The strip fits after the first close and has an empty end
after the second. Without the fix the fourth closing pane rides the third with no rest to
collapse toward, so its free edge freezes in the strip's empty end, and its ground there goes
only with the landing. Every frame along the window's middle and the ground left for the
landing are checked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…iteral (release build)

The release build of d369376 refused ClosingPanes.rects (bench step 8bba1189a5d3b22e2fcbde55,
ClosingPanes.swift:175 and :178): "sending 'edge' risks causing data races": `shown[$0].map(edge)`
and `rests[$0].map(edge)` hand the task-isolated parameter `edge` to `map` from a main-actor
closure. Both now call it in a closure literal (`map { edge($0) }`), as the live-frame reads
beside them already do. No behaviour change; the debug build accepted both forms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…does (optimized build)

bd5a6a3 did not fix the optimized build: the release bench at that head (step
2f0db46a9eef5daf04d69e09) still refused ClosingPanes.swift:175 and :178, "sending 'edge' risks
causing data races" (a main-actor closure that captures both the task-isolated `edge` and the
pass's mutable `shown`/`rests`). The unoptimized release compile-check passed
(a3509913ec2ae257a046938c), so it does not catch this.

Now `facing(_:_:)` (where a neighbour's edge shows) and `restingEdge(_:_:)` (where it rests) are
nested functions that read `shown` and `rests`, and `place` calls them with `edge`, the shape
S3's merged code has (feat's optimized dogfood builds compile it). No behaviour change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ners always follow and a closing pane always keeps its ground (FRAME OWNER S3)

FRAME OWNER REFACTOR stage S3, the switch deletion. S3 landed with `motion.frameOwner.contentPolicy`
default on (#34170, squash a08c406). The gate passed: the refactor owner's films, typing GO,
and the first FEAT DOGFOOD BUILD with S3 judged 10/10 (f1c3ebfd, feat cf86f55, STATUS 11111).
The rule for a stage: once its gate passes, the switch and the old path go. No behaviour change with
the default on.

Removed:
- `LayoutTunables.frameOwnerContentPolicy` (Debug Settings `motion.frameOwner.contentPolicy`) and its
  entry in `LayoutTunables.all`.
- `LayoutViewContext.contentPolicyOverride` and `followsContentPolicy`.
- `PaneMotionHold.containersFollow`: a content area's hold always lets its containers
  (`PaneMotionHoldFollowing`: a terminal's host, a browser's chrome) follow it; other subviews keep
  their frames, as with S1 (FrameOwnerS1HoldPathsTests).
- PaneHostView: `heldAreaFollows` is gone; a key hold whose content has a held area always follows
  (`heldArea != nil`: the surface stays at the pane edge that does not move, the rest size is
  announced and a press reversed in one hold announces its zero change).
- ScreenContentView.retireClosing: a springing close always keeps the closing host with its ground
  (still hidden on a canvas, as before).
- Doc comments that named the switch.

Tests:
- Deleted the OFF pins: PaneContentPolicyTests.aSwitchFlipMidSpringAppliesFromTheNextMotion, the
  `false` cases of CloseTeardownAfterLandingTests (2 tests) and of
  KeyboardResizeContentHoldTests.theProducerResizesOnceAndTheContainersFollowEveryFrame.
- Every `contentPolicyOverride = true` pin is gone (the rig, the S3 and S3d suites), so they prove the
  S3 path is the only path.
- PaneContentPolicyBench runs the one path; the off/on numbers stay in its doc (step
  4b4b80b33807e84dbb37cbfc).
No new test: nothing changes with the default on.

`schemas/defaults/cmux-next.json` is not edited by hand: the base autofix regenerates it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…left in every frame (cmux-ad m6 1b, red)

The interim browser contract for key resizes (FRAME OWNER REFACTOR, STATUS 11198; Lawrence:
"tabbar moves smoothly on ctrl shift hjkl but browsers/terminals do not anymore"). S3 holds a
Chromium page through a key resize on the pane edges that do not move, so a pane whose leading
edge moves slides over a page that stands still: on the refactor owner's films (build 437f5a22,
STATUS 11448) the page's left edge is on its pane's in 0 of 190 motion frames of held keys, up to
1504 device px inside, and 0 of 50 for single presses.

CEFDeferredTabShowTests.aKeyResizeHoldKeepsThePageOnThePageAreasTopLeft: a live page in its pane's
container holds for a key resize whose trailing edge stays (S3's hold edges); the container's
leading edge moves right 120 pt (the pane shrinks), then left 240 pt (it grows), then back. In
every frame the page's top-left corner must be on the page area's top-left (0.5 pt), its size the
held one; the pane clips it, its backdrop is the page's own, and it takes its area's size when the
hold ends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…6 1b, red)

Red step f4e4827a1e6a5a3eca7c65c1 at 619eb26 did not compile the test: "the compiler is
unable to type-check this expression in reasonable time" on the one-line sum of three mapped
ranges, and an inference error after it. The steps are now three typed arrays (right 120 pt, left
to -120 pt, back to the start). The test is otherwise the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…op-left corner, never scaled (cmux-ad m6 1b)

Red first: CEFDeferredTabShowTests.aKeyResizeHoldKeepsThePageOnThePageAreasTopLeft.

The interim browser contract for key resizes (FRAME OWNER REFACTOR, STATUS 11198), until S5's
layer hosting:
1. The page shows the newest frame Chromium presented at its own size: never scaled.
2. Its top-left corner is on the pane's page area's top-left in each frame, so it moves with the
   pane's leading and top edges, as the tab strip does (S1, S3).
3. The pane clips it, and the page's own backdrop fills the rest of the area.
4. Chromium hears one new size per press, after the landing (unchanged).

Only item 2 changes. CEFTabContentView.layoutContent places a key hold's page at the page frame's
top-left corner, the corner a divider drag's hold already uses. It no longer rides S3's hold
edges (the pane edges that do not move). The page window follows its host view in each motion
frame through the existing path (CEFHostView.pagesNeedUpdate: one geometry post per moved page,
budget 0.2 ms), the one a hold-mode divider drag uses.

Behind `browserResize.keyResizeTopLeft` (Debug Settings > Browser Resize), default on, latched
when each key hold begins. A kill switch only: it goes once the refactor owner's off/on film
passes.

Item 1's snapshot part: CEFTabContentView.snapshotView (NSImageView, .scaleAxesIndependently) was
dead code. It was never added to a view and never given an image, so it never showed. It is
deleted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lawrencecchen lawrencecchen added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 4, 2026
@cursor

cursor Bot commented Nov 4, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Review (codex): SHIP at dbf5c8b

Reviewer: Codex (gpt-6.1-sol), codex exec --skip-git-repo-check --sandbox read-only. The reviewer had no tools on this VM (it cannot run commands here): the prompt held the PR's diff from its base a348d07, CEFTabContentView+PaneMotion.swift and BrowserChromeView+PaneMotion.swift in full, and numbered excerpts of CEFHostView.swift (the tab container's hold, layout and drag paths), PaneMotionHold, CEFPaneHost+Show and CEFDeferredTabShowTests.

Round 1 verdict, verbatim: VERDICT: SHIP / no findings.

lawrencecchen added a commit that referenced this pull request Nov 4, 2026
…ts for browserResize.keyResizeTopLeft (the interim browser contract, #35195)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lawrencecchen added a commit that referenced this pull request Nov 4, 2026
…ach film (main-thread time per frame while the page moves; hand edit of the two generated switch variants, a regeneration drops it)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lawrencecchen added a commit that referenced this pull request Nov 4, 2026
…), to show the backdrop, not the shell, beside a held page smaller than its pane

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Base automatically changed from fix/frame-owner-s3-delete-content-policy to feat-cmux-next November 4, 2026 12:14
…wner-browser-key-topleft

# Conflicts:
#	Packages/macOS/CmuxNext/Tests/CmuxNextAppTests/KeyboardResizeReflowAfterLandingTests.swift
@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Review (codex): SHIP at 077479c

Reviewer: Codex (gpt-6.1-sol), codex exec --skip-git-repo-check --sandbox read-only. The reviewer had no tools on this VM (it cannot run commands here): the prompt held this head's diff against the feat commit it merged, 7807516 (its merge base: the 4 browser files this PR lands), and the round-1 diff for comparison.

Round 2, after #35140 and #35161 merged, the retarget to feat-cmux-next and the merge of feat (one conflict in KeyboardResizeReflowAfterLandingTests.swift, which this PR does not touch, resolved to feat's version). Verdict, verbatim: VERDICT: SHIP / no findings.

My error, recorded: a first round-2 prompt diffed the head against a newer feat tip (c29e44b, two commits later), so feat's newer commits showed as reverse hunks and Codex returned FIX for them. That pack was wrong; the head merges clean with c29e44b, and neither newer commit touches the browser files.

@lawrencecchen
lawrencecchen merged commit 225692c into feat-cmux-next Nov 4, 2026
182 of 285 checks passed
@lawrencecchen
lawrencecchen deleted the fix/frame-owner-browser-key-topleft branch November 4, 2026 12:31
@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Checks at 077479c, classified at the merge (none caused by this PR):

@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

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

Default changes

This pull request changes 2 defaults at 077479c1c878 (what everyone gets without configuring anything):

  • tunable-source.CmuxNextBrowser/Core/BrowserResizeTunables.swift:keyResizeTopLeft: (none) -> "193b05abe6108e339e570d48352b341a6165f3385ea9939b6a062612faaf3193"
  • tunable.browserResize.keyResizeTopLeft: (none) -> true

Signed off on this commit by review (codex).

Merge receipt: merged as 225692cd5b2f with these defaults changed, signed off by review (codex).

Regenerate the snapshot with python3 scripts/ci/defaults_guard.py snapshot.

Shipped in:

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 077479c1 Deployed Nov 4, 2026 by lawrencecchen via wait for same-key tree publisher #111561
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