Skip to content

terminal/tmux: resize existing panes on layout changes#12146

Open
h3nock wants to merge 1 commit intoghostty-org:mainfrom
h3nock:fix/tmux-resize-pane-on-layout-change
Open

terminal/tmux: resize existing panes on layout changes#12146
h3nock wants to merge 1 commit intoghostty-org:mainfrom
h3nock:fix/tmux-resize-pane-on-layout-change

Conversation

@h3nock
Copy link
Copy Markdown

@h3nock h3nock commented Apr 6, 2026

What

Resize existing panes when a layout_change updates pane geometry.

Why

Today, layout_change updates the window layout tree and handles pane add/remove, but existing panes with the same pane ID are copied forward without reconciling their terminal cols/rows against the new layout width/height.

That can leave local pane terminal geometry stale after a split/resize operation.

This change keeps pane terminal geometry aligned with authoritative tmux layout geometry for reused pane IDs.

Changes

  • add a small PendingPaneResize list in the tmux viewer
  • in initLayout, if a pane ID already exists:
    • compare current terminal cols/rows with layout width/height
    • queue a resize if the size changed
  • in syncLayouts:
    • build the temporary pane map as before
    • commit windows/panes
    • clear the temporary panes variable after ownership moves to self.panes (panes = .empty)
    • apply queued resizes to the committed panes
  • replace unchecked size casts with std.math.cast(...) and return
    error.InvalidLayoutSize when layout dimensions are out of range
  • update test "layout change" to verify pane sizes after split:
    • existing pane 0 is 83x22
    • new pane 2 is 83x21

AI disclosure: Claude Code Opus 4.6 and Codex 5.4 xhigh were used for research, understanding and helping me write Zig.


@h3nock h3nock requested a review from a team as a code owner April 6, 2026 18:34

// No more errors after this point. We're about to replace all
// our owned state with our temporary state, and our errdefers
// above will double-free if there is an error.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Was this caveat addressed? It doesn't look like it to me. The error handling looks unsafe...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

i think double free is fine, no? cause after self.panes = panes, i immediately set panes = .empty so the top-level errdefer cleanup in syncLayouts iterates an empty map

on the atomic commit point, i removed errdefer comptime unreachable because adding terminal.resize made the post-handoff path fallible. and currently if resize fails, the error propagates and nextCommand moves the viewer to defunct. not happy with that path, open to a better error handling here.

also tried moving the resize block before the errdefer comptime unreachable line but changed my mind for two reasons 1) reused panes are shallow-copied, so pre-handoff resize still mutates the same terminal objects and can still leave partial state on failure. no way to recover that in place. 2) we'd be mutating terminal state while old (self.panes) and new (panes) maps still coexist, instead of mutating through a single authoritative map after handoff. so i went with the current version to keep mutation on a single authoritative map

happy to revisit if you'd prefer a different shape

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.

2 participants