Repository navigation
fix(core): refresh dimensions after resize debounce - #1363
dajiaohuang wants to merge 4 commits into
Conversation
114d884 to
7f983e5
Compare
7f983e5 to
28c0435
Compare
|
Rebased onto current main and kept the upstream invalid-dimension guard after refreshing the chosen TTY stream (28c0435). Added a regression for zero dimensions. Both resize/console suites pass: 87 tests; core typecheck and library build pass. The full core suite initially reported 5,579 passing tests, 36 skipped and one missing generated parser.worker.js asset. After restoring the local bunx launcher and running the library build, the previously failing Node asset test file passes (2/2). No source change was needed for that setup failure. |
|
Another data point from an Electron + xterm.js host, in case it helps this land. Environment: Orca (Electron, xterm.js terminal over a local PTY), macOS 15 / Apple Silicon, opencode 1.18.31 (current latest). Users hit this constantly, because switching worktrees/tabs in the IDE changes the pane geometry while the TUI is in the background. What I measured. I drove a live opencode session over CDP and resized only the PTY, holding the visible xterm grid fixed, to isolate the two directions:
The recovery asymmetry matches what #42225 describes: growing is the only thing that reliably produces a complete frame. Every workaround our users have found (drag a panel wider, change tab zoom) is a grow in disguise. One question about the scope of this fix. Refreshing the cached dimensions before sampling should fix the case where the re-layout happens at the wrong width. It is less clear to me whether it also covers the case where the re-layout happens at the correct, smaller width but the region that is no longer part of the grid is never cleared. If OpenTUI's damage tracking only repaints cells inside the current grid, a shrink would still leave the out-of-range cells from the larger previous frame on screen. If that is already handled elsewhere, ignore this; if not, a full clear on shrink may be needed alongside the dimension refresh. Happy to test a build against our host and report back. We have a reproducible harness on this side. |
|
Thanks — that distinction is valid. I checked the current head: That matches the outcome of #1240: forcing a full logical repaint was tested and the artifact still reproduced, so a remaining shrink-only symptom would need a separate physical-terminal scrub rather than another buffer repaint. Please try this head with your harness; if the out-of-range fragments remain, the next focused change should target the ANSI scrub on width shrink. I have not changed this PR speculatively. |
|
Cross-referencing some user-side results on the real opencode v2.0.18 binary: anomalyco/opencode#42225 (comment) Summary for this branch:
Read on its own that is a good argument for refreshing dims after the debounce (the stale read is real), but the frozen case we observe seems to sit below the handler. Harness (PTY driver + in-process probe plugin): https://gist.github.com/angeloper86/15f078cfb853b531dc0f89b77d4795d7 |
|
Thanks for the detailed harness and version correction. I checked this branch: it is still on @opentui/core 0.5.10, and the change refreshes and samples the selected TTY after the debounce; the added tests cover stale dimensions, piped stdout, and invalid dimensions. Your v2.0.18 result is a different signal: the probe timers stop, and injecting the handler semantics at runtime still freezes. That experiment did not run a build of this PR head, so it does not establish whether the checked-in change addresses the freeze. I’m keeping this PR limited to the stale-dimension path instead of adding an unlocalized event-loop change. If you can run the harness against a build of this head (or a rebased equivalent), that will tell us whether a separate OpenTUI investigation is needed. |
|
Thanks for keeping this scoped to the stale-dimension path. That part is still needed. While reproducing on opencode 2.1.2 / Windows 11 we found a second half that sits right
So I ported your approach to the current Tests, run locally on Windows 11 + Bun 1.4.2: including "repaints when a terminal resize signal reports the current size" and If you would rather keep #1363 as the single place for the re-sample change, I can drop |
|
Thanks for offering to keep the scopes clear. Comparing the diffs, I recommend keeping both pieces together in #1738 for the current renderer path: #1363’s resampling change uses the older |
|
Makes sense — I'll keep the resampling and the same-size repaint together in #1738. Thanks for checking. |
|
This pull request is replaced by #1738. #1738 adds the same stdout size refresh after the resize debounce. It uses the current |
Summary
SIGWINCHis handledstdinas the size source when it is the TTY andstdoutis pipedBrowser-hosted PTY bridges can deliver a resize signal before the runtime's cached
stdout.columnsandstdout.rowsreflect the new kernel window size. The existing resize path captured those cached values immediately, so initial attach and shrink events could keep rendering at the previous width.OpenTUI also always read dimensions from
stdout, but some launchers pipe stdout while keeping stdin attached to the controlling terminal. In that setup the resize signal arrives, yet stdout has no terminal dimensions. The resize handler now refreshes and samples the active TTY stream after the debounce expires.This keeps the existing debounce behavior and is related to anomalyco/opencode#42225.
Closes #1344
Testing
bun run test:js(5,397 passed, 23 skipped)bun run test:js:nodewith Node.js 26.4.0 (4,664 passed, 6 skipped)bun run build:libbun run fmt:checkbun run lint