P0 RESIZE KEYS K3: a keyboard resize holds pane content through its spring and lays it out once after the landing
Summary
P0 RESIZE KEYS K3 (cmux-ad; lead decision 2026-11-02 21:1xZ: "hold pane content during a key resize spring, one reflow at the landing"). With a browser page and an agent chat right of the moving divider, every Ctrl-Shift-H/L lost 4-8 refreshes of its spring (film rk-browser-agent).
Profile (xctrace on the app clock, rk-xtpa-browser-agent): no single item over 8.3 ms. Each dropped frame (9-26 ms of main thread) was the pane contents laid out at the spring's live size: the CA commit (2-8 ms: tracking areas over every subview, window drag regions, the tab label glyphs drawn again, constraint updates), the agent chat's SwiftUI graph, the CEF content view and its child window frame, BrowserChromeView, the tab strip and toolbar.
Fix, in three red-first steps (the third after review):
PaneResize.presstells the screen (LayoutRootView.keyboardResizeWillChange); the screen's hosts hold their content through the spring (thePaneHostViewcontent hold agent chats already use). After films: drops 4-8 -> 0-2 per press. The after profile named the rest: the one content layout still ran in the key turn (growing panes, 10-24 ms) or in the landing frame (shrinking panes, 11-17 ms).- A key resize now holds each pane's content at its START size, growing or shrinking (clipped where the pane is smaller, beside the pane background where it is larger, pinned at the edge nearer its rest), keeps it through retargets, and releases it after the landing frame's commit (
LayoutViewContext.afterCommit), when nothing moves: one layout per press, outside every motion frame.
Splits, closes and zooms keep their live resize (motion.pane.holdContent, Lawrence 2026-10-23); the agent chat's own hold is unchanged.
Testing
On the fleet (scripts/ci/package-test-lane.sh suite Packages/macOS/CmuxNext ...), compile-checks first:
-
Red 1, b4915efa1c5 (
KeyboardResizeContentHoldTests): stepfd8b8ee8192f0a3e01ed3b99FAILED (content resized 16-17 times per press). Fix 1, 3e14e9205bb: green + GUI stepae755250d956d31e9c9d7df1(cmux9s) PASSED, 13 cases, 0 skipped. -
Red 2, 30053696eb8 (
KeyboardResizeReflowAfterLandingTests): step0c9a480d1edf51301c6fac89(aws-m4pro-8) FAILED (each content laid out once inside the motion). Fix 2, fcd7cf32995: compile-check356b12cd572dc3927ea5679bPASSED; green + GUI proof (display worker gui-session-v1, CMUX_TEST_REQUIRE_GUI=1) at the exact head fcd7cf32995ee72813219e525cfb8eb96c42f218: step6eb3bf74690f4029f9834aa5(cmux8s) PASSED: ReflowAfterLanding 2/2, ContentHold 2/2, ShownLimit 2/2, Rows 2/2, PaneResizeGesture 4/4; 15 cases, 0 skipped. -
Films (120 Hz 2x, real HID keys, before = base ddcaf92 build fddf4464, same minis per STATUS 7645): fix 1 + #32626 (build f44441a2): H/L drops per press before 4-8, after 0-2 (cmux22, cmux24, 4+4 runs). Fix 2 films: below.
-
Red 3, b05cb877472 (
KeyboardResizeHoldLifetimeTests): step78d0cb77b1a0ce031797ff22(aws-m4pro-9, headless) FAILED: 4 tests, 19 issues (held edge moves 59-60 pt before the landing; the flag stays set after a press with no spring and afterlandMotion; a split's new pane is 0x0 during a key spring). Fix 3, 593effbd3d7: compile-checks8823c28f48d638b216a3a21c(fix) and5991c58acd19270310ecb9c8(red) PASSED; green + GUI proof (display worker gui-session-v1, CMUX_TEST_REQUIRE_GUI=1) at the exact head 593effbd3d7d3092b3ecb38b3f0b606f7125ace9: step2bdfcdd669fdc9dc7f9d0163(cmuxs-Mac-mini-4): HoldLifetime 4/4, ReflowAfterLanding 1/1, ContentHold 1/1, ShownLimit 2/2, Rows 2/2, PaneResizeGesture 4/4, PaneMotionContentHold 11/11, HiddenScreenMotion 2/2, EarlyTerminalGrid 3/3, 0 failed. PaneMotionWorkTests skipped its 4 tests there (gated onCMUX_PANE_BENCH=1); its own run with that env: stepcd4911f149e8302844c180d4(cmux9s, GUI) PASSED 4/4 (5 cases), 0 skipped. -
Red 4, 2ed1779f521 (
KeyboardResizeHoldTakeoverTests, second review FIX FIRST at 593effbd3d7, comment 6591798082): step60347dfc474b93a39e7eb409(aws-m4pro-4, headless) FAILED: 2 tests, 96 issues.onA2xScreenTheHeldContentKeepsItsEdgeThroughTheLanding(both directions, 18 issues): the held edge moves 60 pt on a 2x screen.aSplitDuringAKeySpringResizesThePanesThatWereMovingLive(78 issues): p1 and p2 keep their 600 x 801 pre-press content through the split's spring (bounds 583.5 x 801, 616.5 x 792). Fix 4, 72e02cae39e: compile-checks87d3e9049aa87bced05e5cbd(fix) andb7f46bf5e50c9bbf200ce2ec(red) PASSED; green + GUI proof (display worker gui-session-v1, CMUX_TEST_REQUIRE_GUI=1, CMUX_PANE_BENCH=1) at the exact head 72e02cae39ecddbcca5d17060f1dd1f8909f2d58: step4ac262b45fd49891347ea683(cmux14; the first try29dd1371failed at checkout on cmux10s, DNS, no test ran) PASSED 11 of 11 suites, 0 skipped: HoldTakeover 2/2, HoldLifetime 4/4, ReflowAfterLanding 1/1, ContentHold 1/1, ShownLimit 2/2, Rows 2/2, PaneResizeGesture 4/4, PaneMotionContentHold 11/11, PaneMotionWork 4/4, HiddenScreenMotion 2/2, EarlyTerminalGrid 3/3.
Films, kit v5 (cp/resize-keys-kit, each press with the core tier it started on), before3 = feat 11e5aeaa (build 2b9d7c93), after3 = this head merged on that feat (build b44fc869), in turn on cmux24, H/L dropped refreshes per press:
- before3: browser-agent [5,6,0,0,5,6,0,0], [4,4,0,0,2,1,0,1], [5,5,0,0,2,1,1,1]; idle (all H/L) [6,6,7,6,8,6], [4,5,4,4,4,5], [6,6,7,5,5,6].
- after3: browser-agent [0,0,0,0,0,1,0,0], [1,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0]; idle [1,1,1,1,1,0], [0,0,0,0,0,0], [0,0,0,0,0,0].
- Every press of both builds started on S or P cores (none on E). H/L per press: before3 2-8 dropped refreshes (median 5), after3 0-1.
Fix-2 films (build 46062c0d, without the tier probe): H/L 5-7 dropped refreshes before, 0-1 after, on cmux22 and cmux24.
Observed / Not run
- Observed: the steps and films above; gallery https://cmux-orchestrator-1.tail137216.ts.net/resize-videos/.
- The films are of fix 3 (593effbd3d7). Fix 4 (72e02cae39e) changes only the 2x edge choice and a structural takeover; it is not filmed again.
- Not in this PR: a press that starts on E cores (a main thread woken from idle) still misses the next refresh: its key turn takes 11-14 ms there against 4-5 ms on S (rk-a2i-xi). That is a follow-up (drag-margin and tracking-area work in the commit, the presentation pass in the key turn).
No capture: motion, filmed by the RESIZE KEYS kit.
Changelog
- Fixed: Ctrl-Shift-H/J/K/L and Ctrl-Cmd-arrows no longer stutter when a browser page or an agent chat is beside the divider; each pane lays out once when the motion ends.
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Fixes keyboard resizes (Ctrl-Shift-H/J/K/L) stuttering when a browser page or agent chat sits beside the moving divider.
- Each key press laid out pane contents on every spring frame — browser chrome, CEF views, chat graphs, tab strips — dropping 4-8 frames per press.
- The screen now holds each pane's content at its start size through the spring, clipped where the pane is smaller, and lays it out once after the landing frame's commit.
- Held content stays pinned at the edge nearer its rest through the landing so it does not jump, and the hold clears on every path (Reduce Motion, a motion landing at once, a split or zoom taking over, or a new spring during the previous hold's tail).
- Splits, closes, and zooms keep their live resize behavior; the agent chat's own content hold is unchanged.