refactor(ui-tui): collapse xterm.js resize settle dance

Replace 28-line guard + nested queueMicrotask + pendingResizeRender flag-reuse with a named canAltScreenRepaint predicate and a single flat paint. setTimeout already drained the burst coalescer; the nested defer and flag dance were paranoia.
This commit is contained in:
Brooklyn Nicholson 2026-04-23 12:49:49 -05:00
parent 60d1edc38a
commit 7c4dd7d660

View file

@ -463,33 +463,21 @@ export default class Ink {
this.resetFramesForAltScreen() this.resetFramesForAltScreen()
this.needsEraseBeforePaint = true this.needsEraseBeforePaint = true
// xterm.js burst-drift healer: 160ms after the last resize, force one
// full reconcile so Yoga/React catch up to the final viewport. No flag
// dance — setTimeout already drained the burst coalescer; a concurrent
// render would be idempotent.
if (isXtermJs()) { if (isXtermJs()) {
this.resizeSettleTimer = setTimeout(() => { this.resizeSettleTimer = setTimeout(() => {
this.resizeSettleTimer = null this.resizeSettleTimer = null
if ( if (!this.canAltScreenRepaint()) {
this.isUnmounted ||
this.isPaused ||
!this.altScreenActive ||
!this.options.stdout.isTTY ||
this.currentNode === null ||
this.pendingResizeRender
) {
return return
} }
this.pendingResizeRender = true this.resetFramesForAltScreen()
queueMicrotask(() => { this.needsEraseBeforePaint = true
this.pendingResizeRender = false this.render(this.currentNode!)
if (this.isUnmounted || this.isPaused || !this.altScreenActive || !this.options.stdout.isTTY || this.currentNode === null) {
return
}
this.resetFramesForAltScreen()
this.needsEraseBeforePaint = true
this.render(this.currentNode)
})
}, 160) }, 160)
} }
} }
@ -513,6 +501,17 @@ export default class Ink {
this.render(this.currentNode) this.render(this.currentNode)
}) })
} }
private canAltScreenRepaint(): boolean {
return (
!this.isUnmounted &&
!this.isPaused &&
this.altScreenActive &&
!!this.options.stdout.isTTY &&
this.currentNode !== null
)
}
resolveExitPromise: () => void = () => {} resolveExitPromise: () => void = () => {}
rejectExitPromise: (reason?: Error) => void = () => {} rejectExitPromise: (reason?: Error) => void = () => {}
unsubscribeExit: () => void = () => {} unsubscribeExit: () => void = () => {}
@ -1970,6 +1969,7 @@ export default class Ink {
clearTimeout(this.drainTimer) clearTimeout(this.drainTimer)
this.drainTimer = null this.drainTimer = null
} }
if (this.resizeSettleTimer !== null) { if (this.resizeSettleTimer !== null) {
clearTimeout(this.resizeSettleTimer) clearTimeout(this.resizeSettleTimer)
this.resizeSettleTimer = null this.resizeSettleTimer = null