fix(tui): full redraw on terminal width/height resize\n\ncloses #1844

This commit is contained in:
Mario Zechner 2026-03-05 20:27:37 +01:00
parent bb85cad0ba
commit dabcda0db3
4 changed files with 45 additions and 5 deletions

View file

@ -202,6 +202,7 @@ export class TUI extends Container {
public terminal: Terminal;
private previousLines: string[] = [];
private previousWidth = 0;
private previousHeight = 0;
private focusedComponent: Component | null = null;
private inputListeners = new Set<InputListener>();
@ -425,6 +426,7 @@ export class TUI extends Container {
if (force) {
this.previousLines = [];
this.previousWidth = -1; // -1 triggers widthChanged, forcing a full clear
this.previousHeight = -1; // -1 triggers heightChanged, forcing a full clear
this.cursorRow = 0;
this.hardwareCursorRow = 0;
this.maxLinesRendered = 0;
@ -871,8 +873,9 @@ export class TUI extends Container {
newLines = this.applyLineResets(newLines);
// Width changed - need full re-render (line wrapping changes)
// Width or height changed - need full re-render
const widthChanged = this.previousWidth !== 0 && this.previousWidth !== width;
const heightChanged = this.previousHeight !== 0 && this.previousHeight !== height;
// Helper to clear scrollback and viewport and render all new lines
const fullRender = (clear: boolean): void => {
@ -897,6 +900,7 @@ export class TUI extends Container {
this.positionHardwareCursor(cursorPos, newLines.length);
this.previousLines = newLines;
this.previousWidth = width;
this.previousHeight = height;
};
const debugRedraw = process.env.PI_DEBUG_REDRAW === "1";
@ -908,15 +912,15 @@ export class TUI extends Container {
};
// First render - just output everything without clearing (assumes clean screen)
if (this.previousLines.length === 0 && !widthChanged) {
if (this.previousLines.length === 0 && !widthChanged && !heightChanged) {
logRedraw("first render");
fullRender(false);
return;
}
// Width changed - full re-render (line wrapping changes)
if (widthChanged) {
logRedraw(`width changed (${this.previousWidth} -> ${width})`);
// Width or height changed - full re-render
if (widthChanged || heightChanged) {
logRedraw(`terminal size changed (${this.previousWidth}x${this.previousHeight} -> ${width}x${height})`);
fullRender(true);
return;
}
@ -958,6 +962,7 @@ export class TUI extends Container {
if (firstChanged === -1) {
this.positionHardwareCursor(cursorPos, newLines.length);
this.previousViewportTop = Math.max(0, this.maxLinesRendered - height);
this.previousHeight = height;
return;
}
@ -996,6 +1001,7 @@ export class TUI extends Container {
this.positionHardwareCursor(cursorPos, newLines.length);
this.previousLines = newLines;
this.previousWidth = width;
this.previousHeight = height;
this.previousViewportTop = Math.max(0, this.maxLinesRendered - height);
return;
}
@ -1144,6 +1150,7 @@ export class TUI extends Container {
this.previousLines = newLines;
this.previousWidth = width;
this.previousHeight = height;
}
/**