Skip to content

Keep the mouse working in OpenCode panes after reattach, and let Option-drag select text - #222

Merged
pallaoro merged 1 commit into
mainfrom
for-opencode-i-am-not-able
Sep 5, 2026
Merged

pallaoro merged 1 commit into
mainfrom
for-opencode-i-am-not-able

Conversation

@pallaoro

@pallaoro pallaoro commented Sep 5, 2026

Copy link
Copy Markdown
Member

Why

OpenCode takes over the mouse at startup (DEC modes 1000-1006). Two things broke in Ateam's terminal because of that.

Scrolling stopped after any reattach. Reopening the task panel, a second window, or an app restart rebuilds the pane from the PTY daemon's serialized snapshot. @xterm/addon-serialize replays mouse tracking (?1003h) but has no way to replay the mouse encoding (?1006h, not in terminal.modes). The fresh xterm fell back to the legacy X10 encoding, which xterm emits on onBinary; the views only forward onData, so every wheel, click and drag was dropped until the app restarted.

Text selection never worked while an app owned the mouse: on macOS xterm offers no bypass unless macOptionClickForcesSelection is set.

What

  • packages/server/src/pty/snapshot-modes.ts: track ?1006/?1016 requests through the headless terminal's own parser (split chunks handled for free, RIS resets it) and append the active encoding to every snapshot. Wired in daemon.ts. Covers desktop, box and mobile panes since they all replay the same snapshot.
  • Terminal.tsx: macOptionClickForcesSelection: true. Option+drag selects, plain drag still goes to the app (VS Code / iTerm2 convention).
  • altClickMovesCursor: false. With forced selection on, xterm's default Option+click "move cursor here" runs, and on OpenCode's alt screen its moveToCellSequence loop diverged and grew a string until the renderer died out of memory (reproduced at ~20 GB). Disabled; no agent wants those arrow keys anyway.

Verified

  • Live in the dev app with OpenCode 1.18.29: wheel (mouse and trackpad deltas) scrolls; Option+drag selects; plain drag does not; Option+click stays harmless with memory flat.
  • Scratch daemon built from this branch: OpenCode's snapshot now replays both ?1003h and ?1006h.
  • bun test (server): 260 pass. Typecheck and biome clean.

Left for later (parked in the repo sidenotes)

  • onBinary still unforwarded for apps that enable tracking without SGR (none today).
  • iOS: touch gestures never become mouse reports for a mouse-owning TUI.
  • Upstream xterm.js bug report for the moveToCellSequence loop.

…on-drag select text

OpenCode owns the mouse (modes 1000-1006), which broke two things in the terminal:

- Scrolling died after any reattach (reopening the task, a second window, app
  restart). The daemon rebuilds a pane from a serialized snapshot, and the
  serialize addon replays mouse tracking (?1003h) but not the SGR encoding
  (?1006h). The fresh xterm fell back to the legacy X10 encoding, which it emits
  on onBinary; the views only forward onData, so every wheel/click/drag was
  dropped. The daemon now tracks the encoding through xterm's own parser and
  appends it to every snapshot (unit-tested; verified against a real OpenCode
  session on a scratch daemon).

- Text selection never worked while an app owned the mouse: on macOS xterm
  offers no bypass unless macOptionClickForcesSelection is set. Option+drag now
  selects (same convention as VS Code and iTerm2); plain drag still goes to the
  app. altClickMovesCursor is disabled alongside it: with it on, one
  Option+click on OpenCode's alt screen sent the renderer into an unbounded loop
  in xterm's moveToCellSequence and killed the window (out of memory).
@pallaoro
pallaoro enabled auto-merge (squash) September 5, 2026 18:07
@pallaoro
pallaoro merged commit cd13ac4 into main Sep 5, 2026
1 check passed
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