Skip to content

fix(web-ui): prevent terminal output flicker on expansion - #1886

Merged
wsp1911 merged 1 commit into
GCWing:mainfrom
wsp1911:dev2
Jul 30, 2026
Merged

fix(web-ui): prevent terminal output flicker on expansion#1886
wsp1911 merged 1 commit into
GCWing:mainfrom
wsp1911:dev2

Conversation

@wsp1911

@wsp1911 wsp1911 commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Prevent terminal output from oscillating between adjacent pixel heights after expanding an ExecCommand card.
  • Keep the normalized fallback output visible until xterm has rendered its first content frame.
  • Share terminal text normalization, font metrics, and height calculation between the lazy fallback and xterm renderer.
  • Add regression coverage for normalized fallback rows.

Type and Areas

Type:

Regression fix / UI/UX

Areas:

Web UI, Flow Chat, terminal output rendering

Motivation / Impact

  • Expanded ExecCommand cards could flicker indefinitely because xterm's rounded cell height was written back into the React container from its ResizeObserver.
  • After fixing that loop, a one-time flash remained while the lazy fallback was replaced by an initially empty and differently sized xterm renderer.
  • Terminal output now remains visually stable throughout expansion.
  • The xterm runtime remains lazily loaded, preserving the existing startup performance boundary.

Verification

  • pnpm run type-check:web
    • Passed.
  • pnpm --dir src/web-ui run test:run src/tools/terminal/components/LazyTerminalOutputRenderer.test.tsx src/flow_chat/tool-cards/ExecProcessToolCardView.test.tsx src/app/startup/startupPerformanceContract.test.ts
    • 3 test files passed.
    • 54 tests passed.
  • git diff --check
    • Passed.
  • Manually expanded the affected ExecCommand card.
    • Confirmed that continuous and one-time output flicker no longer occurs.

Reviewer Notes

  • The shared presentation helper mirrors xterm's font-metric and device-pixel-ratio calculations without importing the xterm runtime.
  • ResizeObserver still refits xterm when the container changes, but no longer feeds rounded cell heights back into React state.
  • The plain-text fallback remains mounted until xterm reports a rendered content frame.
  • No user-facing strings, migrations, or compatibility changes are included.

Checklist

  • This PR is focused and does not include secrets, temporary prompts, generated scratch files, or unrelated artifacts.
  • Relevant verification is recorded above, or skipped checks are explained.
  • User-facing strings, docs, and locales are updated where applicable. No copy changes were required.

- Prevent xterm row-height feedback loops during resize.
- Keep fallback output visible until xterm renders its first content frame.
- Share output normalization and height calculation between fallback and xterm.
- Add regression coverage for normalized fallback rows.
@wsp1911
wsp1911 merged commit 77fbe0b into GCWing:main Jul 30, 2026
7 checks 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