Skip to content

Renderer has no awareness of absolute terminal position #148

@bananabot9000

Description

@bananabot9000

Summary

The three-layer rendering architecture (PR #147) enforces the zone invariant: the renderer never writes more rows than screen.rows, preventing scrollback corruption. However, the renderer operates entirely on relative cursor movement -- it knows how many rows it wrote (zoneHeight) but not where those rows are in the terminal.

The Gap

Nothing in the renderer tracks the absolute position of the zone in the terminal. The render cycle is:

  1. Move cursor up by zoneHeight (relative)
  2. Clear and redraw the zone
  3. Track zoneHeight for next cycle

This works when the relationship between the cursor and the zone start is stable. But the terminal can mutate the visual layout of previously written content without notifying the application. When this happens, the tracked zoneHeight no longer reflects the actual visual row count, and relative cursor movement operates from the wrong position.

Observable behaviour

  • The zone gets rendered in the wrong location (too high or too low)
  • Previous zone content remains visible as a "ghost" -- not corruption, but visual duplication
  • The severity depends on where the zone started in the terminal (fresh terminal vs mid-screen)
  • The current narrow/widen heuristic in notifyResize() mitigates the most common cases but is based on comparing old vs new zone heights, not on actual position knowledge

Root cause

The renderer has a relative model (I wrote N rows, move up N to erase) but operates in an absolute space (the terminal's row/column grid). There is no mechanism to reconcile the two when external factors change the mapping between them.

Constraints

  • Scrollback history must be preserved (no alternate screen buffer, no scrollback clearing)
  • The terminal owns the history -- the renderer only manages a dynamic zone at the bottom
  • The zone invariant (never write more than screen.rows) must be maintained
  • Any solution should work in both bare terminals and tmux

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions