iOS: make terminal picker a native Menu (tap + press-drag-release)
What
The top-right terminal picker on the iOS workspace detail screen (the terminal button that lists all terminals in the workspace) used a Button toggling a custom .popover. A Button + .popover is two separate hit-test sessions: you tap the button to present the popover, then tap an item. It never supported the standard iOS menu gesture, where you press-and-drag from the button straight onto an item and release to select it.
This replaces it with a native SwiftUI Menu. On iOS, Menu renders as a UIMenu, which gives both interaction modes for free: single tap to open then tap an item, and press-drag-release-to-select, exactly like any native nav-bar menu.
Behavior preserved
- The menu lists all terminals in the workspace; selecting one switches to it via
selectTerminalFromChrome(keyboard suppressed on attach, same as before). - Selected terminal still shows a checkmark.
- "New Workspace", "New Terminal", and the DEBUG-only "Copy Debug Logs" / "Send to agent" entries are kept, grouped into
Sections. - All existing accessibility identifiers (
MobileTerminalDropdown,MobileTerminalMenuItem-*,MobileNewTerminalMenuItem,MobileNewWorkspaceMenuItem) are kept on the same buttons.
Only behavior change
Menu has no will-open hook, so the keyboard is no longer dismissed when the menu opens (the menu floats over the live keyboard like any nav-bar menu). The keyboard still clears on selection, since the action handlers call dismissTerminalKeyboardForChrome().
Verification
- Clean iOS simulator build of the
cmux-iosworkspace scheme (arm64 simulator, build-only, no device, no test, no launch): BUILD SUCCEEDED. - iOS UI tests that drive the picker (
testTerminalDropdownSwitchesToAlternateScreenSnapshot,testWorkspaceToolbarCreatesWorkspaceAndTerminal,testTUITerminalUsesAvailableViewportAndResizes) run on theiOS simulator testsworkflow, which gates this PR.
š¤ Generated with Claude Code
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.
[!NOTE]
Low Risk
Localized SwiftUI toolbar change on iOS with preserved accessibility IDs and selection logic; minor keyboard-on-open behavior change only.
Overview
Replaces the workspace toolbar terminal picker from a Button + custom .popover to a native SwiftUI Menu (iOS UIMenu), so users get standard tap-to-open and press-drag-release selection instead of two separate tap sessions.
The menu content is reorganized into Sections (terminals, new workspace/terminal actions, DEBUG tools) with less custom padding/layout; accessibility identifiers and selection via selectTerminalFromPicker / selectTerminalFromChrome are unchanged. New Workspace from the menu now uses createWorkspaceFromToolbar directly (duplicate picker-only helper removed).
Only UX delta: the keyboard is no longer dismissed when the menu opens (Menu has no will-open hook); it still dismisses when an item is chosen because actions call dismissTerminalKeyboardForChrome().
Reviewed by Cursor Bugbot for commit 99c3d85f05333f66c244f4fe919a992909da756b. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Replaced the terminal picker popover with a native SwiftUI Menu in the iOS workspace toolbar, enabling tap and press-drag-release selection and preserving existing items/accessibility IDs. The "New Workspace" action now uses createWorkspaceFromToolbar; the keyboard stays up on open and still dismisses on selection.
Summary by CodeRabbit
-
UI/UX Improvements
- Terminal picker in the workspace detail view now uses the native menu for improved accessibility and consistency.
- Menu groups terminals, New Workspace, and New Terminal actions for a clearer flow.
-
Bug Fixes
- Keyboard reliably dismisses when launching or selecting terminals/workspaces from the menu.
- Debug and feedback actions no longer interfere with terminal selection or picker behavior.
-
New Features
- Debug-only options (Copy Debug Logs, Send to agent) available in debug builds for easier testing and reporting.