Skip to content

fix(tui): pin header to absolute top row — fix macOS title centering (#1834)#2255

Open
Hmbown wants to merge 1 commit into
mainfrom
fix/1834-macos-header-top-align
Open

fix(tui): pin header to absolute top row — fix macOS title centering (#1834)#2255
Hmbown wants to merge 1 commit into
mainfrom
fix/1834-macos-header-top-align

Conversation

@Hmbown
Copy link
Copy Markdown
Owner

@Hmbown Hmbown commented May 27, 2026

Problem

On macOS Terminal.app, the TUI header bar appears vertically centered with large blank space above and below (reported in #1834).

Root cause

While Constraint::Min(1) with ratatui's default Flex::Start should place the header at row 0, some flex/constraint interactions can produce unexpected centering on certain terminal sizes.

Fix

Restructure the render layout into a defensive two-pass system:

  1. First pass: split terminal into header (Length(1)) + body (Min(1)) with explicit Flex::Start, pinning the header to the absolute top row.
  2. Second pass: split the body area for chat, preview, composer, footer.

This guarantees the header is never vertically centered regardless of ratatui Flex defaults or terminal dimensions.

Verification

  • cargo check --workspace
  • Layout is structurally defensive — header area is computed independently of body constraints

Closes #1834

Greptile Summary

This PR restructures render() in ui.rs into a defensive two-pass layout to fix macOS Terminal.app header centering (#1834). Instead of one 5-slot layout, the header is pinned in a dedicated first-pass split with Flex::Start and Length(1), and the remaining body area is passed to a second split for chat, preview, composer, and footer.

  • The header is isolated into header_area via [Length(1), Min(1)] with explicit Flex::Start, guaranteeing it always occupies row 0 regardless of ratatui flex defaults or terminal size.
  • chunks[0..4] is replaced by header_area + body_chunks[0..3]; all render call sites are updated consistently, and composer_max_height arithmetic is adjusted to account for the fact that body_area.height now includes the footer row.

Confidence Score: 4/5

Safe to merge; the change is a structural refactor of the layout pass with no logic changes to rendering logic itself.

All chunk index remappings are consistent throughout the function, and the composer_max_height arithmetic produces an identical result before and after. The two-pass layout correctly isolates the header from body flex interactions. Edge cases at very small terminal heights are handled by existing saturating_sub and max guards. No render path is left unreachable and no overlay logic is broken since they still use the full size rect for absolute positioning.

No files require special attention; the single changed file is self-contained and all call sites were updated in the same commit.

Important Files Changed

Filename Overview
crates/tui/src/tui/ui.rs Restructures render() into a two-pass layout: header is pinned via a separate Flex::Start split before the body split, removing it from the body_chunks array and adjusting all chunk indices accordingly; composer_max_height arithmetic is updated equivalently.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[render called with full terminal Rect size] --> B

    subgraph Pass1[Pass 1 - pin header]
        B[Layout Vertical + Flex::Start\nLength 1 and Min 1 split on size]
        B --> C[header_area = split 0\nalways row 0]
        B --> D[body_area = split 1\nremainder below header]
    end

    D --> E

    subgraph Pass2[Pass 2 - body split]
        E[Layout Vertical + Flex::Start\nMin 1 + preview + composer + footer\nsplit on body_area]
        E --> F[body_chunks 0 - Chat area]
        E --> G[body_chunks 1 - Pending preview]
        E --> H[body_chunks 2 - Composer]
        E --> I[body_chunks 3 - Footer]
    end

    C --> J[HeaderWidget render]
    F --> K[ChatWidget]
    G --> L[PendingPreview]
    H --> M[ComposerWidget]
    I --> N[render_footer]
Loading

Reviews (1): Last reviewed commit: "fix(tui): pin header to absolute top row..." | Re-trigger Greptile

The header bar was reported to appear vertically centered on macOS
Terminal.app with large blank space above and below. While the existing
Constraint::Min(1) layout with default Flex::Start should place the
header at row 0, some ratatui/flex interactions can produce unexpected
centering on certain terminal sizes.

Restructure the render layout into a defensive two-pass system:
1. First pass: split the terminal into header (Length(1)) + body (Min(1))
   with explicit Flex::Start, pinning the header to the absolute top.
2. Second pass: split the body area for chat, preview, composer, footer.

This guarantees the header is never vertically centered regardless of
ratatui Flex defaults or terminal dimensions.

Fixes #1834
Copilot AI review requested due to automatic review settings May 27, 2026 04:54
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[UI Bug] macOS 终端标题悬浮居中,布局未贴顶

2 participants