This repository has been archived on 2026-07-17. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
codespace/web/src
tao.chen c647bb98a9 fix(web): break the terminal resize loop properly
The previous 'stabilize useMutation results' fix addressed one cause
of /shell/resize being spammed (the mutation object identity), but
not the actual root cause: a closed loop between xterm's onResize
callback, ResizeObserver, and the backend.

The full loop:
  1. ResizeObserver fires
  2. fitAddon.fit() runs
  3. fit() calls terminal.resize(cols, rows)
  4. terminal.onResize(cb) fires the listener
  5. cb calls resize.mutate() — POSTs to /shell/resize
  6. server calls pty.Setsize
  7. bash receives SIGWINCH and redraws the prompt
  8. the new output writes to the terminal, which can shift a
     scrollbar / padding by a few pixels
  9. ResizeObserver fires again
  -> repeat

Fixes applied to TerminalPanel's terminal-init useEffect:

  - Drop the terminal.onResize subscription entirely. Per the xterm
    + FitAddon pattern, the right way to push size to the backend
    is: from the ResizeObserver path, call fit(), then read
    terminal.cols/rows synchronously and call resize.mutate().

  - Dedupe by (cols, rows) — if the size hasn't changed since the
    last reported size, skip the mutation.

  - Dedupe the ResizeObserver callback by container
    getBoundingClientRect — sub-pixel changes (e.g. a scrollbar
    appearing) won't trigger a redundant fit().

  - Depend on the stable sendResize function (the destructured
    mutate from useMutation) rather than the whole resize object,
    so unrelated render churn can't tear down and re-create the
    terminal.

  - Run an initial fit() at mount so the backend learns the real
    size before the user starts typing.

The 100ms debounce was a band-aid that didn't actually break the
loop — it only slowed it down.
2026-07-06 18:23:11 +08:00
..
2026-07-02 17:23:48 +08:00
2026-07-02 17:23:48 +08:00
2026-07-02 16:48:19 +08:00