Repository navigation
cmux-next iOS: a drag in a TUI scrolls the app; groups stay collapsed; bottom bounce after a fling - #24081
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fresh Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es refreshes TUI mode (alternate screen): a vertical drag becomes precise wheel events through ghostty_surface_mouse_scroll, with momentum after a fling, so a mouse-reporting app gets SGR wheel reports at the finger and the alternate screen gets cursor keys (DECSET 1007, Ghostty's default). The page stays pinned; taps, long-press selection and handles keep working. Workspace groups: a collapse (or rename, color, delete, move) is held over tree refreshes until the Mac's list shows it (PendingGroupEdits), and a refused earlier tap no longer undoes a later one. The group header's tap target covers its row. Agent chat: a live thought closes on the first tap; a tool group's header wins over its first call; a running call's expansion no longer carries over to the next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ext-ios-tui-scroll
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
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)
|
|
Found 2 test failures on Blacksmith runners: Failures
|
|
Bead |
… bounce Review fixes: - group requests go to a Mac one after another, so quick taps land in tap order; - a new group supersedes an earlier pending move; - an edit the Mac never answers gives way after 30 s; - group edits reset at sign-in; - a tap that stops a TUI fling does not focus the terminal; - the wheel stays at the cell where the drag began; - a slow drag is judged by its translation; - surface tests cover 1002/1003 and the grid padding. Bottom bounce: a fling toward newer rows that reached the bottom stopped the deceleration dead (setContentOffset to itself) to switch to following, so it had no rubber band while a slow drag did. It now switches to following and lets UIKit finish the deceleration and its bounce. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Correctness review (fresh review subagent) and resolutionThe review covered the PR's own commits. It confirmed these are correct:
Also in this push, from the user: "sometimes the terminal doesn't have bottom content bounciness in its scroll."
Tests at 4d1d4ba on mini-cmux11s (iOS simulator) passed:
|
- A new-group edit leaves the table once answered. - Sign-in clears edits but keeps the generation counter. - A queued edit's unanswered window starts when its request is sent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot needs on-demand usage enabledBugbot 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. |
|
Re-review of 4d1d4ba by a fresh review subagent: SHIP at 4d1d4ba, with no must-fix findings. It confirmed:
Nits fixed in 1078673:
Not changed:
CmuxMobileModelTests, CmuxMobileLiveTests and CmuxMobileWorkspacesTests pass on mini-cmux11s. |
… swift test) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
CI at caf50f6:
|
…ow the Mac's rows on the mirror Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ws on the mirror less scrolls with a line feed on its last row and sets no margins. On the phone's taller mirror the alternate screen's default margins were the mirror's ~150 rows, so that line feed moved the cursor below the rows shown instead of scrolling: the Mac's less moved on while the phone kept its first page (drag or keys alike). Entering the alternate screen now sets the margins to the Mac's rows (cursor kept), and a TUI's margin reset there goes back to them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…c's rows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Live check finding: less (rig: a headless simulator plus the hidden mobilenaming Mac app on mini-cmux11s, over the real link, build 4d1d4ba).
The less re-check on this build runs next. |
… a full-screen app Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…k (TUI capability F1) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… full-screen apps; capability matrix - A tap in an app that asked for the mouse (vim mouse=a, htop's header, mc, tmux panes) is a left click at that cell through Ghostty's encoder, then focuses the terminal as before. - The composer's one-line draft is typed into a full-screen app (vim's normal mode took the bracketed paste of ':q' as text); several lines stay one paste. - verify/tui-capabilities.md: the full TUI capability run and its resolution. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t window; matrix re-verify Review of e03153a: a one-line Send typed into an agent on the alternate screen could hit Codex's paste-burst window (Codex QA F1) with Return 60 ms later. Typed text now waits 250 ms before Return. The vim demo uses the typed path. tui-capabilities.md records the live re-verify of e03153a. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TUI capability run (the user's expanded scope) and its fixesThe full matrix is in Passed on the first run:
Fixed in this PR, then re-verified live (all PASS on e03153a):
Review of e03153a (fresh subagent): it confirmed the Ghostty mouse semantics:
Its findings and what changed in a6d6f76:
Not fixed here, with reasons:
|
|
Final review (fresh subagent): SHIP at a6d6f76. It found no must-fix and checked:
Nits not changed:
CI at a6d6f76:
Merging (merge commit) per the user's direction for this work. |
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Summary
Two bugs the user reported in the cmux-next iPhone app.
1. "I can't scroll in TUI mode because the TUI app controls the scroll."
In alternate-screen mode (less, vim, htop, Codex, Claude Code) the page is pinned, and nothing turned a drag into input for the app. Now a vertical drag on the TUI scrolls the app the way a Mac trackpad does in Ghostty. The drag becomes precise wheel events through Ghostty's own
ghostty_surface_mouse_pos+ghostty_surface_mouse_scroll, 1:1 with the finger in the natural direction, with momentum after a fling (decay 0.95 per 1/60 s, stopped by a new touch). Ghostty's mirror surface already tracks the app's DEC modes, so it decides what the app gets:ESC [ A/B, orESC O A/Bin application cursor mode;The page never scrolls in this mode. Taps still focus the terminal. A long press still selects, and a drag clears the selection. Selection handles still move. Keyboard and composer behavior is unchanged. ACCEPTANCE.md T-SCROLL-12 and T-AGENT-08 now describe this.
2. "Disclosure groups not being properly closable."
PendingGroupEditsholds a group edit (collapse, rename, color, delete, move) overAppStore.replaceWorkspaces. It holds while the request is in flight, then after the Mac's yes until a refresh shows the edit or 10 s pass. After that the Mac's state wins again, since another device can change it. Only the latest edit of a workspace rolls back on refusal.Every DisclosureGroup or expandable section was surveyed. Feed, Settings and the sidebar showed no state-binding fault: Settings and sidebar chevrons navigate, and the Feed "Show more" is bound to a stable
Set<String>. CmuxTabsKit and CmuxConversation are untouched.3. "Sometimes the terminal doesn't have bottom content bounciness in its scroll."
setContentOffset(contentOffset, animated: false)) so the page could switch to following. A fling into the end had no rubber band; a slow drag past it did.TerminalScrollModel.flingReachedBottom()) and UIKit finishes the deceleration and its bounce. The end of the deceleration lands on the newest end, as before.The review fixes are listed in the review comment.
Tests
Swift tests ran on mini-cmux11s in the iOS simulator:
cmux-next-ios/verify/termqa/cmux_mobile_kit-test-ios.sh CmuxMobileTerminalTests CmuxMobileModelTests CmuxMobileAgentChatTests/DisclosureChoiceTests CmuxMobileWorkspacesTests.TerminalTUIScrollSurfaceTestsuses a real Ghostty mirror surface. It feeds the DEC modes, then checks the exact bytesonInputsends:ESC[<64;4;6M×3 with mouse reporting on;ESC[Aon the alternate screen;ESC OAin application cursor mode;TerminalTUIScrollTestscovers drag deltas, scroll mods packing, the vertical-only rule, and momentum decay, end and stop.WorkspaceGroupCreatorTestscovers a refresh during a collapse, an unconfirmed edit expiring, quick taps, and a refused collapse.DisclosureChoiceTestscovers the live thought row.Red on base:
TerminalTUIScrollandscrollWheelwere missing.groupEdits.applydisabled,aRefreshDuringACollapseKeepsTheGroupClosed,quickTapsEndOnTheLastTapandanUnconfirmedEditGivesWayToTheMacAfterAWhilefail. The first fails with "isCollapsed → false".Green on head: all four targets passed, including every new test.
Observed / Not run
scripts/cmux-next/prepush-gate.pyreported no new violations.Changelog
Fixed: In the iPhone app, dragging over a full-screen terminal app (less, htop, vim, Codex, Claude Code) now scrolls that app, workspace groups stay collapsed after a tap, and a fling into the bottom of a terminal bounces.
No capture: iOS app change (not the Mac app). Live simulator video and frames are in a PR comment.
🤖 Generated with Claude Code