Repository navigation
perf(next): closing the last tab of a split pane removes the pane at once, not after the program read - #32898
Conversation
…y's turn (red: it waits for the daemon's read) Leo 2026-10-25: "closing the right pane seems be like... waiting". The emptied pane stays on screen until TabCloseGuard's process read answers. Adds a measuring test (Cmd-W -> pane gone, 15 rounds, p50/p95). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ed9226b71907d8aaa0b6
…y's turn; a running program brings it back TabCloseGuard hid the closing tabs in the key's turn (#31875) only when their pane kept another tab: closing the last terminal of a split (the right pane) kept the pane on screen until the daemon's process read answered (up to 1 s). Now a pane the close empties leaves its window at once too (PaneController.showPaneClose), when the layout can show it leaving (never the screen's last pane) and it holds no browser page. The read decides as before: no program, the hide lifts and the close's own intent shows the pane close again in the same turn (no frame between); a program, the pane comes back with its tab, selection and focus before the question. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ed9226b71907d8aaa0b6
…h the coordinator's Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ed9226b71907d8aaa0b6
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Default changesThis pull request changes 4 defaults at
Signed off on this commit by Merge receipt: merged as Regenerate the snapshot with Shipped in:
|
|
Review (codex, router-review): SHIP at cea57c4 Reviewer: codex gpt-6-astra high, fast tier. Follow-ups: 2. Each lands as an issue in this repo that links this receipt; the lane that opened the PR fixes it forward. SHIP at cea57c4
Follow-ups:
|
…se of the pane's last other tab hid it (review of #32898) (#32973) Two quick Cmd-Ws in one pane, the first on a running program: the second emptied the pane, which hid; the first's rollback brought its tab back into a hidden pane, so its question showed with no pane. A rolled-back tab now withdraws whichever close hid its pane. Agent-Session: https://cmux.com/deeplink/agent?id=aid-ed9226b71907d8aaa0b6 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
Swift logic follow-up (tip watcher swift-logic row, STATUS 13027 "SWIFT LOGIC CULPRITS"; lead order). This PR raised
plans/cmux-next/layer-ownership.md says Rust owns every state, list and rule and Swift is the platform shell. Please move the new logic of this PR in a follow-up: to Rust (the crate that owns the area; the owner lists in STATUS 12147-12165 name the target per area), or at least out of the app into its package. If a declaration above is platform code (AppKit, Core Animation, OS calls, strings, tokens, DEBUG tooling), reply here and the table gets a PLATFORM row with your reason instead. The swift-logic row is a report, not a gate: nothing blocks on this comment. |
Leo, 2026-11-03: "it's so slow to open and close idk if there's some sort of threading issue but it's nigh instant for claude and codex so we nede to be at least as fast". Leo, 2026-10-25: "closing the right pane seems be like... waiting for the right tab's closing animation to play before closing".
leo-named-fix
What was slow
Cmd-W (or a tab's close button) on the last terminal of a split's pane (the right pane, the usual case) kept the pane on screen until the daemon's process read answered (
TabCloseGuard: does a program still run in it? up to 1 s per terminal). #31875 already hid the closing tab in the key's turn, but only when its pane kept another tab; a pane the close emptied waited for the read and only then left (prepareClose->showPaneClose).Fix
TabCloseGuard.close: a pane the close empties now hides with its tabs in the key's turn too, when its layout can show it leaving (LayoutModel.canShowPaneClose: a split's pane or a column's only pane; never the screen's last pane, which would show empty) and it holds no browser page (asking a page starts its close; the browser path is perf(browser): closing a Chromium tab, or a pane's last one, takes effect on the click (beforeunload still asks) #32876). The terminal stays alive: the read still decides.HiddenTabClose.liftruns the newliftedhooks:LayoutModel.withdrawPaneClosedrops the hold unshown), so nothing is drawn in between.TabStripModel.cmdWTarget(_:closing:skipped:): the pure Cmd-W target pick moved from the App into CmuxNextTabs (no behavior change), which pays for the App lines this adds.Design spec: plans/cmux-next/close-animation/DESIGN.md (the pane leaves in the key's frame); this extends it to a close the daemon's read still decides.
Risk
risk:normal. Close-path state: the hide/restore of an emptied pane while the read decides. A rolled-back close shows the pane again through the same cancel path a refused daemon close uses. Not covered: the screen's last pane (nothing to show in its place) and the warnings-off path where only the undo-toast decision reads (
CloseUndoToasts.decideFirst, follow-up). A pane in a column with rows is #32907.Performance
CmdWEmptiedSplitPaneLeavesInItsTurnTests.measureCmdWToEmptiedPaneGone; before at 83ba468 (fleet step 2c8b77668d07787212926acb), after at cea57c4The before is an idle same-tree daemon on an idle Mac; under load the read waits up to its 1 s bound, while the after does not depend on the read at all. The two runs landed on different fleet Macs (the controller picked them).
Tests
CmdWEmptiedSplitPaneLeavesInItsTurnTests(same-tree daemon, held read): the emptied pane leaves in the key's turn and its close lands; withsleep 600running, the pane, tab and focus come back before the question and Cancel keeps it.cmux-ci run --class light --script scripts/ci/package-test-lane.sh --ref SHA --arg=suite --arg=Packages/macOS/CmuxNext --arg=CmdWEmptiedSplitPaneLeavesInItsTurnTests,CmdWIdleTerminalClosesInItsTurnTests,CmdWTargetTests --env CMUX_CI_XCODE_APP=/Applications/Xcode_26.6.appCmdWIdleTerminalClosesInItsTurnTests(11, the perf(next): Cmd-W on an idle terminal closes in its key's turn (the program is read before the key) (SHORTCUT LATENCY SL-3) #31875 suite),CmdWTargetTests.PaneCloseControllerTests,PaneCloseApplyTests: every Swift Testing test passed at 191b5ab and cea57c4. Their step reports failure because the XCTest leg (no XCTest tests selected) aborts with signal 6 after about 650 s on some workers. The same abort shows up at the test-only base commit 83ba468, and not at all on the worker that ran the cea57c4 suites above.Observed / Not run
Ran:
compile-check --package CmuxNextat 191b5ab (passed, 213 s); the suites above. Not run: a STRESS burst-bench row, a DEV build by hand.Changelog
Fixed: Closing the last tab of a split pane (the right pane) removes the pane at once instead of after a short wait.
No capture: timing only.
Agent session: agent session
🤖 Generated with Claude Code