Bug: Terminal display width wobble - inconsistent width measurement #25

Closed
opened 2026-03-18 08:14:38 +00:00 by david · 1 comment
Owner

Description

Terminal display has inconsistent width measurement causing rendering to "wobble" - content shifts horizontally on each frame.

Symptoms

  • Content appears to shift left/right between frames
  • Visually disorienting ("higglty pigglty")
  • More noticeable with bordered output or images

Root Cause Analysis Needed

Potential sources:

  1. os.get_terminal_size() being called inconsistently
  2. Multiple code paths calling tw() vs get_terminal_size() vs cached values
  3. ANSI escape codes affecting perceived width
  4. Race condition between display.get_dimensions() and actual render

Files to Investigate

  • engine/terminal.py - tw() function
  • engine/viewport.py - tw() function
  • engine/display/backends/terminal.py - init() and get_dimensions()
  • engine/app.py - dimension handling in run_pipeline_mode()

Status

Open - Root cause TBD

## Description Terminal display has inconsistent width measurement causing rendering to "wobble" - content shifts horizontally on each frame. ## Symptoms - Content appears to shift left/right between frames - Visually disorienting ("higglty pigglty") - More noticeable with bordered output or images ## Root Cause Analysis Needed Potential sources: 1. `os.get_terminal_size()` being called inconsistently 2. Multiple code paths calling `tw()` vs `get_terminal_size()` vs cached values 3. ANSI escape codes affecting perceived width 4. Race condition between display.get_dimensions() and actual render ## Files to Investigate - `engine/terminal.py` - `tw()` function - `engine/viewport.py` - `tw()` function - `engine/display/backends/terminal.py` - `init()` and `get_dimensions()` - `engine/app.py` - dimension handling in run_pipeline_mode() ## Status Open - Root cause TBD
david closed this issue 2026-03-18 10:36:29 +00:00
Author
Owner

Root Cause Analysis

The terminal display "wobble" was caused by multiple issues:

1. Missing Screen Clear (Primary Cause)

TerminalDisplay.show() was appending new content without clearing the previous frame, causing old content to remain and creating visual jumping.

Fix: Added \033[H\033[J (cursor home + erase down) before each frame in engine/display/backends/terminal.py.

2. CameraStage AttributeError (Secondary)

CameraStage tried to set read-only viewport_width/viewport_height properties (they're computed from canvas_size / zoom), causing an AttributeError each frame.

Fix: Changed to use set_canvas_size() method in engine/pipeline/adapters.py.

3. Glitch Effect Issues (Tertiary)

  • Used cursor positioning (\033[row;1H) which conflicted with HUD and border rendering
  • Changed line lengths randomly, causing viewport jumping

Fix: Removed cursor positioning, pad to original visible width in effects_plugins/glitch.py.

4. Fade Effect Bug

Returned empty string when fade=0 instead of preserving original line.

Fix: Return original line when fade=0 in effects_plugins/fade.py.

5. Noise Effect Bug

Used terminal_width instead of input line length, causing dimension mismatches.

Fix: Use len(original_line) in effects_plugins/noise.py.

Tests Added

  • tests/test_glitch_effect.py - 12 tests for effect dimension stability
  • tests/test_display.py - screen clear regression tests
  • tests/test_pipeline.py - CameraStage regression test
## Root Cause Analysis The terminal display "wobble" was caused by multiple issues: ### 1. Missing Screen Clear (Primary Cause) `TerminalDisplay.show()` was appending new content without clearing the previous frame, causing old content to remain and creating visual jumping. **Fix:** Added `\033[H\033[J` (cursor home + erase down) before each frame in `engine/display/backends/terminal.py`. ### 2. CameraStage AttributeError (Secondary) CameraStage tried to set read-only `viewport_width`/`viewport_height` properties (they're computed from `canvas_size / zoom`), causing an AttributeError each frame. **Fix:** Changed to use `set_canvas_size()` method in `engine/pipeline/adapters.py`. ### 3. Glitch Effect Issues (Tertiary) - Used cursor positioning (`\033[row;1H`) which conflicted with HUD and border rendering - Changed line lengths randomly, causing viewport jumping **Fix:** Removed cursor positioning, pad to original visible width in `effects_plugins/glitch.py`. ### 4. Fade Effect Bug Returned empty string when fade=0 instead of preserving original line. **Fix:** Return original line when fade=0 in `effects_plugins/fade.py`. ### 5. Noise Effect Bug Used `terminal_width` instead of input line length, causing dimension mismatches. **Fix:** Use `len(original_line)` in `effects_plugins/noise.py`. ### Tests Added - `tests/test_glitch_effect.py` - 12 tests for effect dimension stability - `tests/test_display.py` - screen clear regression tests - `tests/test_pipeline.py` - CameraStage regression test
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: klubhaus/sideline#25