Skip to content

Terminals scroll under a finger on a phone, Claude Code's own view included - #311

Open
rivshughes wants to merge 1 commit into
AgentSystemLabs:mainfrom
rivshughes:touch-scroll-terminal
Open

rivshughes wants to merge 1 commit into
AgentSystemLabs:mainfrom
rivshughes:touch-scroll-terminal

Conversation

@rivshughes

Copy link
Copy Markdown

What

On the 2D view (/lite) a worker's terminal can't be scrolled by touch: dragging a finger over it does nothing, slow or fast, in Safari and Chrome on iOS alike.

Two things combine:

  • xterm.js 6 has no touch scrolling. It bundles VS Code's gesture handling, but nothing ever registers the viewport as a gesture target, so touches never turn into scrolling.
  • Claude Code tracks the mouse. With a wheel, xterm doesn't scroll its own buffer; it sends the program a mouse report (ESC[<64;col;rowM) and Claude Code scrolls its own view. Its buffer has nothing to scroll in that mode, so scrolling xterm itself wouldn't have helped anyway.

How

touchScroll in src/client/ui/terminal.ts: a drag over the terminal is a mouse wheel, a notch per row of travel.

  • When term.modes.mouseTrackingMode isn't none, each notch is dispatched to xterm as a wheel event (DOM_DELTA_LINE, ±1), which xterm turns into exactly the report a real wheel notch produces, so the program scrolls its view.
  • Otherwise term.scrollLines(notches) scrolls the buffer, as for a shell.
  • touchmove is claimed with preventDefault so the 2D page doesn't scroll under the terminal; a tap and a second finger (zoom) are left to the browser.

Docs: a sentence in docs/controls.md (phone paragraph) and docs/features.md (the 2D view bullet).

Checks

  • npm run typecheck, npm test (606 passing), npm run build.
  • An emulated iPhone (Playwright + CDP touch events):
    • a standalone xterm 6 terminal with 300 lines: a drag moves the viewport 277 → 263 and back; without the change it stays at 277.
    • a live Claude Code worker on the 2D view: a half-screen drag sends 13 ESC[<64;…M wheel-up reports over the WebSocket, one per row, where before it sent nothing.
  • Confirmed by hand on an iPhone, in Safari and Chrome, over the office's HTTPS address.

🤖 Generated with Claude Code

…cluded

On the 2D view a worker's terminal couldn't be scrolled by touch at all: xterm.js 6 ships
touch-gesture code but never attaches it to its viewport, so a finger over the terminal did
nothing, however slowly it moved.

A drag over the terminal is now a mouse wheel: a notch per row of travel. When the program in the
terminal tracks the mouse, as Claude Code does, each notch is handed to xterm as a wheel event,
which it reports to the program the same way a real wheel is, and the program scrolls its own
view; xterm's buffer has nothing to scroll in that mode. Otherwise the buffer scrolls. A tap, or a
second finger, is left to the browser.

Checked with an emulated iPhone: on a plain terminal with scrollback the viewport moves and
returns; on a Claude Code worker a half-screen drag sends one wheel report per row, exactly what
the same number of wheel notches sends.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
muguetdev added a commit to muguetdev/agent-office that referenced this pull request Oct 9, 2026
…roll

Terminals scroll under a finger on a phone (from Agent Office AgentSystemLabs#311)
muguetdev added a commit to muguetdev/agent-office that referenced this pull request Oct 9, 2026
…roll

Terminals scroll under a finger on a phone (from Agent Office AgentSystemLabs#311)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant