Skip to content

Stale cell data visible on new rows after scrolling with default cursor style #138

Description

@darrinm

Description

When repeatedly writing escape-heavy output (SGR sequences, 256-color, truecolor) to the terminal followed by scrolling, new rows can display stale cell data from previously used page memory. This manifests as content from old rows appearing horizontally merged into current rows.

Root cause

In Screen.zig, cursorDownScroll() only clears new row cells when the cursor has a non-default background color (bg_color != .none). When programs reset attributes with ESC[0m (which sets bg_color = .none), pages.grow() extends existing pages by appending rows whose cell memory still contains data from previously erased rows. These stale cells are never cleared and become visible on lines that aren't fully overwritten (e.g., empty lines from bare \r\n sequences with default cursor style).

Symptoms

  • Content from previous rows appears merged horizontally into current rows
  • Bug is transient — self-corrects on the next write to that row
  • Bug is periodic — frequency depends on column width (e.g., ~every 11 writes at cols=160)
  • Affects all column widths at different frequencies

Reproduction

  1. Create a terminal (any reasonable size, e.g. 160x39)
  2. Repeatedly write escape-heavy output containing SGR color sequences followed by ESC[0m resets
  3. After enough repetitions to trigger pages.grow(), inspect viewport rows
  4. Some rows will contain horizontally concatenated content from two different terminal lines

Expected behavior

New rows created during scrolling should always have clean/empty cells regardless of cursor style.

Fix

Draft PR with fix and regression tests: #134

Metadata

Metadata

Assignees

Labels

acceptedHuman-approved for implementationbugConfirmed or likely defecttriage:doneMux triage report has been posted

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions