Fix: Pending-Wrap-Kaskade in iTerm2 behoben
render() schrieb pro Nicht-Letzte-Zeile exakt self.cols Zeichen → Cursor landet in Pending-Wrap-Zustand. In iTerm2 löscht ein Cursor-Positionierungs- befehl (_go) diesen Zustand NICHT: das erste Zeichen der nächsten Zeile triggert den Wrap → Zeile r+1 landet auf r+2 usw. → Kaskade. Folgen: Zeilen ohne Überschreibung zeigen alte Zeichen (Fragmente oberhalb der Wasserlinie), Unterwasserinhalt verschiebt sich aus dem sichtbaren Bereich (nichts unter der Wasserlinie sichtbar). Fix: letztes Zeichen jeder Zeile grundsätzlich auslassen (col_limit = cols - 1, für alle Zeilen). Pending-Wrap tritt nie auf. Letzte Spalte bleibt leer, was für die Animation völlig akzeptabel ist.
This commit is contained in:
parent
66671eda8b
commit
d87088eff0
1 changed files with 11 additions and 7 deletions
|
|
@ -119,18 +119,22 @@ class Canvas:
|
|||
self._ck[row][col] = ck
|
||||
|
||||
def render(self) -> str:
|
||||
# \033[H homes the cursor; every cell is rewritten below so \033[2J is
|
||||
# not needed and would push content into the scrollback on every frame.
|
||||
# The very last cell (bottom-right corner) is intentionally skipped:
|
||||
# writing to it would trigger auto-wrap and scroll the terminal.
|
||||
last_row = self.rows - 1
|
||||
last_col = self.cols - 1
|
||||
# \033[H homes the cursor; every cell is rewritten so \033[2J is not
|
||||
# needed (it would push content into the scrollback on every frame).
|
||||
#
|
||||
# The last column of EVERY row is intentionally skipped (not just the
|
||||
# last row). Writing to the last column triggers "pending-wrap" state.
|
||||
# In iTerm2, cursor-position commands (_go) do NOT clear pending-wrap,
|
||||
# so the first character of the next row triggers a wrap, placing it one
|
||||
# row too low. This cascades: row r+1 lands at r+2, row r+2 at r+3, …
|
||||
# Content below the waterline shifts off-screen; skipped rows show stale
|
||||
# characters. Staying one column short prevents pending-wrap entirely.
|
||||
col_limit = self.cols - 1
|
||||
parts = ["\033[H", RESET]
|
||||
sentinel = object()
|
||||
last_ck: object = sentinel
|
||||
for r in range(self.rows):
|
||||
parts.append(_go(r, 0))
|
||||
col_limit = last_col if r == last_row else self.cols
|
||||
for c in range(col_limit):
|
||||
ck = self._ck[r][c]
|
||||
if ck is not last_ck:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue