Skip to content

Layout is only re-run on a terminal resize: showing an element, changing text, or a host-assigned root size are never laid out #133

Description

@matt-edmondson

What's wrong

UIApplication.SyncRootToConsole (TUI/Services/UIApplication.cs:~272-290) runs ArrangeTree only when the root has no dimensions yet or the console was resized. Invalidate() (UIElementBase.cs:321-326) raises Invalidated but never causes a re-arrange. So any change to the tree after the first frame keeps the stale layout.

Reproduction (ran, using RecordingConsoleProvider)

  • A: showing a hidden element
    1. The root is StackPanel { a, b }, where b.IsVisible = false.
    2. Call app.Render(), then set b.IsVisible = true, then call app.Render().
    3. Actual: b's text is never drawn, because b still has its default position and empty dimensions.
    4. Expected: b is drawn on row 1.
  • B: a host-assigned root size
    1. var root = new StackPanel { new TextElement("abc") }; root.Dimensions = new(20, 5);
    2. Call app.Render().
    3. Actual: nothing is drawn, because the root has a size so the arrange step is skipped and the child has no dimensions.
    4. Expected: abc is drawn.
  • Other cases: the same applies to any Text or size change that should move its siblings.

Why it matters

Dynamic UIs, where elements appear or disappear or text length changes, render with stale geometry until the user happens to resize the terminal.

Suggested fix / acceptance criteria

  • Re-arrange the tree on every Render(). Each pass already clears and redraws the whole screen (CLAUDE.md, step 3), so an arrange pass is cheap in comparison.
  • Alternatively, track a layout-dirty flag that Invalidate / IsVisible / Text changes set, and arrange when it is set.
  • Add tests for both repro cases.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't workingreadyFully specified; implement as written

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions