* Seed prev/back frames with full-size BLANK screens (rows×cols of empty * cells, not 0×0). In alt-screen mode, next.screen.height is always * terminalRows; if prev.screen.height is 0 (emptyFrame's default), * log-update sees heightDelta > 0 ('growing') and calls renderFrameSlice, * whos
()
| 982 | * matches the physical cursor after ENTER_ALT_SCREEN + CSI H (home). |
| 983 | */ |
| 984 | private resetFramesForAltScreen(): void { |
| 985 | const rows = this.terminalRows; |
| 986 | const cols = this.terminalColumns; |
| 987 | const blank = (): Frame => ({ |
| 988 | screen: createScreen(cols, rows, this.stylePool, this.charPool, this.hyperlinkPool), |
| 989 | viewport: { |
| 990 | width: cols, |
| 991 | height: rows + 1 |
| 992 | }, |
| 993 | cursor: { |
| 994 | x: 0, |
| 995 | y: 0, |
| 996 | visible: true |
| 997 | } |
| 998 | }); |
| 999 | this.frontFrame = blank(); |
| 1000 | this.backFrame = blank(); |
| 1001 | this.log.reset(); |
| 1002 | // Defense-in-depth: alt-screen skips the cursor preamble anyway (CSI H |
| 1003 | // resets), but a stale displayCursor would be misleading if we later |
| 1004 | // exit to main-screen without an intervening render. |
| 1005 | this.displayCursor = null; |
| 1006 | // Fresh frontFrame is blank rows×cols — blitting from it would copy |
| 1007 | // blanks over content. Next alt-screen frame must full-render. |
| 1008 | this.prevFrameContaminated = true; |
| 1009 | } |
| 1010 | |
| 1011 | /** |
| 1012 | * Copy the current selection to the clipboard without clearing the |
no test coverage detected