Skip to content

Keep TUI tab bars visible at minimum pane heights - #8765

Merged
lawrencecchen merged 5 commits into
mainfrom
feat-cmux-tui-min-tabbar-height
Jul 24, 2026
Merged

lawrencecchen merged 5 commits into
mainfrom
feat-cmux-tui-min-tabbar-height

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • clamp mouse and keyboard vertical resizing to each subtree's ratio-aware tab-bar minimum
  • reserve a tiny pane's first row for its tab bar when the terminal is smaller than the feasible layout
  • cover nested splits, ancestor ratios, and one-row pane fallback with regression tests

Verification

  • cargo test -p cmux-tui -- --test-threads=1 (435 unit tests and 8 CLI integration tests)
  • cargo clippy -p cmux-tui --all-targets -- -D warnings
  • cargo fmt --all -- --check
  • Computer Use preflight in a separate cmux window: three nested vertical panes retained all tab bars at both resize extremes

The first commit contains the regressions without the fix; the second commit implements the behavior.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Keep TUI tab bars visible when panes hit minimum heights. Vertical resizing now clamps ratios with subtree-aware minimums, and falls back to bar-only when full minima aren’t possible.

  • Bug Fixes
    • Clamp vertical split ratios using subtree tabbed minimums; honors nested descendant ratios and bar-only fallback for infeasible layouts.
    • For 1–2 row panes, reserve the first row for the tab bar; hide content and omit the scrollbar.
    • Apply clamping to both keyboard and mouse resize paths in cmux-tui; regression tests cover constrained panes, nested drags, and fallback behavior.

Written for commit 2113517. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Improved pane resizing and edge-drag behavior to keep tab bars visible in deeply nested layouts.
    • Fixed rendering for extremely small (non-zero height) panes by reserving tab-bar space and preventing invalid terminal content display.
    • Enhanced vertical split ratio constraints so nested ancestors/descendants respect tab-bar preservation.
  • Tests
    • Expanded coverage for nested split dragging, split sizing constraint correctness, and tiny-pane rendering behavior.

@cursor

cursor Bot commented Jul 23, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Pane layout sizing now preserves nested tab bars during split resizing, reserves tab-bar rows in tiny panes, and hides terminal content when no content height remains. Tests cover nested ratio clamping, dragging, and tiny-pane rendering.

Changes

Tab-bar-aware pane sizing

Layer / File(s) Summary
Minimum-height and pane rendering rules
cmux-tui/crates/cmux-tui/src/app.rs
Defines minimum tabbed-pane heights, recursively computes nested split requirements, and reserves tab-bar rows in tiny panes.
Tab-bar-aware split resizing
cmux-tui/crates/cmux-tui/src/app.rs
Applies tab-bar-aware ratio clamping to focused and direct split resizing and updates zoomed-pane layout construction.
Layout regression coverage
cmux-tui/crates/cmux-tui/src/app.rs
Adds coverage for nested split dragging, ancestor and descendant ratio constraints, and tiny-pane tab-bar reservation.

Estimated code review effort: 4 (Complex) | ~45 minutes

🚥 Pre-merge checks | ✅ 25
✅ Passed checks (25 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed Diff only touches cmux-tui/src/app.rs (Rust); no Swift files or actor-isolation-related code changed, so the Swift 6 isolation check is not applicable.
Cmux Swift Blocking Runtime ✅ Passed Diff touches only cmux-tui/crates/cmux-tui/src/app.rs (Rust); no .swift files changed, so Swift blocking-runtime rules are not applicable.
Cmux Browser Automation Off-Main ✅ Passed Diff only changes cmux-tui/crates/cmux-tui/src/app.rs; it does not touch the browser-automation files or paths covered by the rule.
Cmux Expensive Synchronous Load ✅ Passed PR only changes cmux-tui/crates/cmux-tui/src/app.rs (Rust); no Swift code or agent-history loader paths were added or moved, so the Swift-specific load rule is not applicable.
Cmux Cache Substitution Correctness ✅ Passed Not applicable: the diff is Rust TUI layout logic, and it doesn't replace any fresh persistence/history/snapshot read with a cached value.
Cmux No Hacky Sleeps ✅ Passed Only cmux-tui Rust layout code changed; no new sleeps, timers, or polling appeared in the diff, and the rule scope excludes Rust.
Cmux Algorithmic Complexity ✅ Passed New pane-tree helpers do one linear traversal per resize; no batch rescans, repeated sorts/filters, or nested scalable scans were introduced.
Cmux Swift Concurrency ✅ Passed This PR only changes Rust in cmux-tui; no Swift files or Swift concurrency patterns were introduced or expanded.
Cmux Swift @Concurrent ✅ Passed PR only changes Rust cmux-tui/src/app.rs; no Swift files or Swift concurrency annotations are involved, so the Swift-specific rule is not applicable.
Cmux Swift Package Boundaries ✅ Passed Only cmux-tui/crates/cmux-tui/src/app.rs changed; no Swift production code, so the Swift package-boundary rule is not applicable.
Cmux Swiftpm Lockfiles ✅ Passed Only cmux-tui/src/app.rs changed; no SwiftPM/Xcode/.gitignore/dependency files or Package.resolved diffs are present, so the lockfile rule isn’t implicated.
Cmux Swift Logging ✅ Passed The diff only changes Rust code in cmux-tui; no Swift files or Swift logging statements are added or modified.
Cmux User-Facing Error Privacy ✅ Passed The PR only adds tab-bar layout logic and regression tests; the diff shows no new user-facing errors or vendor/provider-sensitive text.
Cmux Full Internationalization ✅ Passed The PR only changes Rust TUI layout logic/tests in app.rs; it adds no new user-facing Swift/web copy or locale data, so the i18n rule isn’t implicated.
Cmux Swiftui State Layout ✅ Passed PASS: The PR only modifies Rust cmux-tui/src/app.rs; HEAD^..HEAD shows no SwiftUI files or state/layout patterns covered by the rule, so it’s out of scope.
Cmux Architecture Rethink ✅ Passed Not applicable: the commit only changes Rust cmux-tui/crates/cmux-tui/src/app.rs, and the Swift architectural-rethink rule applies only to Swift changes.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed No Swift files or window-ownership code changed; the PR only modifies cmux-tui/crates/cmux-tui/src/app.rs, so this rule is not applicable.
Cmux Source Artifacts ✅ Passed Only cmux-tui/crates/cmux-tui/src/app.rs changed; it contains hand-written source/tests and no logs, temp dirs, screenshots, build output, or caches.
Cmux No Test Or Debug Seam In Production Source ✅ Passed Only cmux-tui/crates/cmux-tui/src/app.rs changed; no Swift files or production Sources/ paths were modified.
Cmux No Ambient Global State ✅ Passed PASS: the diff only touches a Rust file; no Swift file, singleton, or file-scope mutable global was introduced.
Title check ✅ Passed The title is concise and accurately reflects the main change: preserving TUI tab bars at minimum pane heights.
Description check ✅ Passed The description is mostly complete with summary and verification, but the template’s Demo Video, Review Trigger, and Checklist sections are missing.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-cmux-tui-min-tabbar-height

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmux-tui/crates/cmux-tui/src/app.rs`:
- Around line 3134-3200: The resize path repeatedly traverses the layout tree
and recomputes split minimum heights for every drag sample. Build and retain a
SplitId-to-(u16, u16) minimum-height index whenever the screen layout changes,
then update clamp_split_ratio_for_tab_bars and its callers to use the cached
lookup in O(1) during resizing while preserving the existing ratio clamping
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f5827666-037e-4c05-88e3-a52574ede19e

📥 Commits

Reviewing files that changed from the base of the PR and between 5dc99c6 and 2d78e81.

📒 Files selected for processing (1)
  • cmux-tui/crates/cmux-tui/src/app.rs

Comment thread cmux-tui/crates/cmux-tui/src/app.rs Outdated
@greptile-apps

greptile-apps Bot commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes tab bars disappearing when panes are resized to very small heights in the cmux TUI. It adds ratio-aware minimum height clamping for vertical splits and a fallback rendering path for 1–2 row panes.

  • Adds minimum_tabbed_height / minimum_split_height (binary search) to compute per-subtree height floors that account for nested split ratios, then applies them in both keyboard and mouse resize paths via clamp_split_ratio_for_tab_bars.
  • Extends pane_parts_for_rect with a new branch for height 1–2: reserves the first row for the tab bar and returns zero-height content, preventing the terminal surface from overwriting the bar.
  • Adds four regression tests covering nested drag extremes, ancestor/descendant ratio constraints, bar-only fallback under infeasible full minimums, and the tiny-pane rendering path.

Confidence Score: 5/5

Safe to merge. The change is narrowly scoped to resize clamping and fallback rendering for small panes; it cannot corrupt session or layout state.

The binary search in minimum_split_height is mathematically sound — the lower bound first_minimum + second_minimum is provably ≤ the true minimum, fits(u16::MAX) is validated before the loop, and the monotone fits predicate guarantees convergence. clamp_ratio_to_minimum_heights correctly returns None for infeasible ranges and the two-tier fallback (full → bar_only) is well-reasoned. The pane_parts_for_rect new branch only fires for height 1–2, where the omnibar path already short-circuits. The four new regression tests cover nested drag extremes, ancestor ratio constraints, bar-only fallback, and tiny-pane rendering. No correctness issues found.

No files require special attention.

Important Files Changed

Filename Overview
cmux-tui/crates/cmux-tui/src/app.rs Adds ratio-aware minimum height computation, split-ratio clamping on both resize paths, a tiny-pane rendering branch in pane_parts_for_rect, and four regression tests. Logic is sound and tests pass per the PR verification steps.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User drags / keyboard resize] --> B[resize_split / set_split_ratio]
    B --> C[clamp_split_ratio_for_tab_bars]
    C --> D{vertical split?}
    D -- No --> E[return 0.05-0.95 clamp]
    D -- Yes --> F[vertical_split_minimum_heights]
    F --> G[minimum_tabbed_height per child subtree]
    G --> H{Down split?}
    H -- Yes --> I[minimum_split_height binary search]
    H -- No / Leaf --> J[fixed constants: full=3, bar_only=1]
    I --> K[clamp_ratio_to_minimum_heights full minimums]
    J --> K
    K --> L{feasible?}
    L -- Yes --> M[return clamped ratio]
    L -- No --> N[clamp_ratio_to_minimum_heights bar_only minimums]
    N --> O{feasible?}
    O -- Yes --> M
    O -- No --> E
    M --> P[session.set_split_ratio]
    P --> Q[pane_parts_for_rect]
    Q --> R{height > 2?}
    R -- Yes --> S[full box: bar + content + scrollbar]
    R -- No, height > 0 and width > 2 --> T[tiny pane: bar row 0, content height=0]
    R -- No --> U[no bar: full rect as content]
Loading

Reviews (3): Last reviewed commit: "fix(tui): preserve bars under infeasible..." | Re-trigger Greptile

@cursor

cursor Bot commented Jul 24, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@lawrencecchen
lawrencecchen merged commit a73714c into main Jul 24, 2026
9 checks passed
@lawrencecchen
lawrencecchen deleted the feat-cmux-tui-min-tabbar-height branch July 24, 2026 00:30
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.

1 participant