Fix iOS terminal sizing priority across background resume
Summary
Backgrounding the iOS terminal no longer clears the phone's confirmed viewport lease by default, so the host keeps the last rendered grid through resume instead of briefly letting the Mac choose a different size. A persisted Settings toggle, Hand Off Terminal Sizing When Inactive, opts into the earlier phone/computer handoff behavior when users want the Mac to own sizing while the phone is inactive.
The change keeps CMUXMobileShellStore's reported viewport and generation as the source of truth, threads the persisted preference through WorkspaceDetailView into the terminal coordinator, and applies the preference before inactive lifecycle cleanup. Enabling the toggle while already inactive releases the lease immediately; disabling it leaves the current lease intact until the next foreground mount.
Fixes https://github.com/manaflow-ai/cmux/issues/18624
Testing
- Added
MobileDisplaySettingsTestscoverage for the default-without-write behavior and cross-instance persistence. - Added
TerminalSurfaceMountOwnershipTestscoverage for default background/resume lease preservation, explicit opt-in handoff release, and foreground recovery when the output stream has been torn down. - Addressed the Cursor Bugbot finding: foreground reconciliation now uses the persisted handoff preference when stopping stale mounted tasks, so transient stream recovery cannot release the phone lease unless handoff is enabled.
- Regression-first commits:
4c7ea19b466records the original behavioral expectation,4e3dafcb78records the foreground-recovery regression, and the following fix commits implement each behavior. - Focused local command:
swift test --package-path Packages/iOS/CmuxMobileShellUI --filter 'MobileDisplaySettingsTests|TerminalSurfaceMountOwnershipTests'. The pre-fix and fixed attempts in this checkout could not start becauseswiftis unavailable (/bin/bash: swift: command not found), so zero local tests executed. - Portable verification:
git diff HEAD~2..HEAD --checkpassed and the changed XCStrings resource parses withpython3 -m json.tool. The Swift syntax verifier reportedswiftc is unavailable; native compilation and app launch were not checked locally. - The iOS connectivity soak was not run: this lifecycle change needs a tagged app/device build, while the request explicitly prohibits reproducing on the user's machine. No user-device reproduction or app install was performed.
- CI run 38662110144 built the iOS simulator product. Its first package-test attempt exposed one unrelated flaky
IrohMacSwitchRecoveryTests.macSwitchDuringRecoveryKeepsTheSwitchedMacfailure; the failed jobs were rerun and the iPhone, iPad, package, and aggregate iOS checks passed.
Changelog
Fixed: iOS terminal sizing keeps its confirmed viewport across background and resume, with an opt-in Mac handoff setting.
Proof
CI-only for this pass. Native app launch and screenshots were intentionally skipped under the no-user-machine-reproduction constraint.
Issue lifecycle
- Pickup comment: https://github.com/manaflow-ai/cmux/issues/18624#issuecomment-6068346064
- Resolution comment: pending until this PR merges.
Impact map
- Source of truth and owner:
CMUXMobileShellStore's reported viewport and generation;GhosttySurfaceRepresentable.Coordinatorowns the viewport lease and inactive lifecycle transition;MobileDisplaySettingspersists the opt-in handoff choice. - Direct callers and sibling entrypoints inspected:
WorkspaceDetailView.terminalArtifactSurface, the representable coordinator factory/update path,didChangeWindowAttachment,detach, viewport report/clear methods, and existing terminal mount ownership tests. - Cross-surface effects: the Settings toggle is localized in all 9 supported iOS locales; desktop sizing policy remains host-owned, and SSH/local terminal surfaces continue through the same coordinator lifecycle.
- Tests and evidence: persistence tests cover relaunch-style settings instances; lifecycle tests cover default lease retention, generation stability, and explicit handoff release.
- Residual risk: a native iOS build and suspended-app visual check remain for CI/device verification because the local SwiftPM package target cannot run on macOS 12 with its macOS 14 dependencies, and user-machine reproduction was explicitly excluded.
Mergeability
- Base SHA: fba804b1bf5af8d67a4f36d18faf3583fcff746a
- Head SHA: d308b17b44c91d750ca1b3214a6b1c21fd48111f
- Conflict-only gate: PASS; no conflicted paths (gate ref gate/task-18624-ios-resize-priority-1791493114)
HIG
The Apple Human Interface Guidelines Settings page was consulted for the persisted toggle placement and explanatory footer: https://developer.apple.com/design/human-interface-guidelines/settings