Skip to content

Disable terminal reflow during resize for cmux stability#3

Open
lawrencecchen wants to merge 1 commit intomainfrom
cmux-ssh-resize-no-reflow
Open

Disable terminal reflow during resize for cmux stability#3
lawrencecchen wants to merge 1 commit intomainfrom
cmux-ssh-resize-no-reflow

Conversation

@lawrencecchen
Copy link

@lawrencecchen lawrencecchen commented Mar 2, 2026

Summary

Disable primary-screen reflow on resize in Ghostty's terminal core for cmux builds.

Why

In SSH sessions under aggressive split resize churn, reflow can corrupt or erase previously drawn content from scrollback. Disabling reflow preserves command output and keeps resize behavior stable (tmux-style).

Change

  • Set Screen.resize call in Terminal.resize to reflow = false
  • Keep prompt redraw disabled on resize (prompt_redraw = .false) to avoid prompt-region wipes under churn

Validation

Validated from cmux integration side with:

  • tests_v2/test_ssh_remote_resize_scrollback_regression.py (PASS)
  • tests_v2/test_pane_resize_preserves_ls_scrollback.py (PASS)
  • tests_v2/test_pane_resize_preserves_visible_content.py (PASS)

Summary by CodeRabbit

  • Bug Fixes
    • Improved terminal stability during pane resizing operations, with better preservation of scrollback content during aggressive resizes.

@coderabbitai
Copy link

coderabbitai bot commented Mar 2, 2026

📝 Walkthrough

Walkthrough

Terminal resize behavior is simplified by disabling reflow and prompt redraw handling during resize operations for both primary and alternate screens. This modification prioritizes content stability and scrollback preservation during aggressive pane resizing.

Changes

Cohort / File(s) Summary
Terminal Resize Logic
src/terminal/Terminal.zig
Modified resize semantics: disabled reflow and removed prompt-based redraw handling for both primary and alternate screen resize operations to enhance content stability during pane resizes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 Hop, hop, resize with care,
No reflow, no prompt despair,
Scrollback safe, content stays true,
Panes dancing, fresh and new!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Disable terminal reflow during resize for cmux stability' directly and clearly describes the main change: disabling reflow during resize operations to improve stability in cmux environments.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cmux-ssh-resize-no-reflow

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

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 015b822df2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// cmux: preserve terminal content stability across aggressive pane
// resize churn (especially for SSH-driven shells). Prefer tmux-style
// no-reflow semantics over potential history loss.
.reflow = false,

Choose a reason for hiding this comment

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

P1 Badge Preserve reflow when wraparound mode is enabled

Hard-coding reflow = false in Terminal.resize removes the existing DECAWM-dependent behavior and makes primary-screen resize always use no-reflow semantics. This regresses normal terminal behavior outside the cmux scenario: when wraparound is enabled, shrinking or expanding columns no longer reflows soft-wrapped lines (the repository already encodes this expectation in test "Terminal: resize with wraparound on" in src/terminal/Terminal.zig).

Useful? React with 👍 / 👎.

.reflow = false,
// cmux: prompt redraw on resize can blank substantial history under
// repeated split-resize churn. Preserve scrollback over prompt cleanup.
.prompt_redraw = .false,

Choose a reason for hiding this comment

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

P2 Badge Honor negotiated prompt redraw capability on resize

Setting prompt_redraw = .false unconditionally bypasses the OSC 133 redraw negotiation stored in self.flags.shell_redraws_prompt (set in semanticPrompt), effectively disabling prompt-redraw support for all shells. In sessions where the shell advertises redraw support, resize will no longer clear prompt/input lines before redraw, which can leave stale or duplicated prompt content instead of the intended clean repaint.

Useful? React with 👍 / 👎.

Copy link

@coderabbitai coderabbitai bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@src/terminal/Terminal.zig`:
- Around line 2729-2735: The patch unconditionally disables reflow and
prompt_redraw in Terminal.zig (the .reflow and .prompt_redraw fields) even
though the comments say this should be cmux-specific; add a compile-time build
option and gate these settings: declare a boolean build option (e.g.,
enableCmux) in src/terminal/build_options.zig, expose it as a comptime/config
constant, and wrap the Terminal.zig assignment so .reflow and .prompt_redraw are
set to false only when that build option is enabled (otherwise keep current
defaults); alternatively, if the intent is global, update the comment and the
tests to reflect that reflow is globally disabled.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 80d3fa0 and 015b822.

📒 Files selected for processing (1)
  • src/terminal/Terminal.zig

Comment on lines +2729 to +2735
// cmux: preserve terminal content stability across aggressive pane
// resize churn (especially for SSH-driven shells). Prefer tmux-style
// no-reflow semantics over potential history loss.
.reflow = false,
// cmux: prompt redraw on resize can blank substantial history under
// repeated split-resize churn. Preserve scrollback over prompt cleanup.
.prompt_redraw = .false,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for cmux-related build options and reflow/prompt_redraw patterns
rg -n "cmux|resize_no_reflow|prompt_redraw.*reflow" src/

Repository: manaflow-ai/ghostty

Length of output: 277


🏁 Script executed:

#!/bin/bash
# Check for build options file structure
fd -t f "build" . --max-depth 3 | head -20

Repository: manaflow-ai/ghostty

Length of output: 631


🏁 Script executed:

#!/bin/bash
# Examine the full context of the resize function around lines 2729-2735
cat -n src/terminal/Terminal.zig | sed -n '2700,2750p'

Repository: manaflow-ai/ghostty

Length of output: 1955


🏁 Script executed:

#!/bin/bash
# Search for resize tests or test patterns
rg -n "test.*resize|resize.*test" src/terminal/Terminal.zig | head -10

Repository: manaflow-ai/ghostty

Length of output: 696


🏁 Script executed:

#!/bin/bash
# Check build.zig for cmux-related options
cat -n build.zig | grep -i "cmux\|option" | head -30

Repository: manaflow-ai/ghostty

Length of output: 262


🏁 Script executed:

#!/bin/bash
# Look for build_options import or usage in Terminal.zig
rg -n "build_options|@import.*build" src/terminal/Terminal.zig | head -10

Repository: manaflow-ai/ghostty

Length of output: 663


🏁 Script executed:

#!/bin/bash
# Examine the actual reflow test implementation to see if it expects reflow to work
sed -n '12043,12090p' src/terminal/Terminal.zig

Repository: manaflow-ai/ghostty

Length of output: 1582


🏁 Script executed:

#!/bin/bash
# Search for any conditional check before the resize call on the primary screen
sed -n '2710,2740p' src/terminal/Terminal.zig | rg -n "if|cmux|build_options"

Repository: manaflow-ai/ghostty

Length of output: 434


🏁 Script executed:

#!/bin/bash
# Search for any cmux-related build option definition in build.zig or terminal_options
rg -n "cmux|no_reflow" build.zig build.zig.zon src/

Repository: manaflow-ai/ghostty

Length of output: 277


🏁 Script executed:

#!/bin/bash
# Look for terminal_options definition/generation
find . -name "*terminal_options*" -o -name "*options*" | grep -v node_modules

Repository: manaflow-ai/ghostty

Length of output: 123


🏁 Script executed:

#!/bin/bash
# Search for the terminal_options import source
rg -n "pub const cmux\|pub const reflow\|pub const prompt_redraw" src/ build.zig

Repository: manaflow-ai/ghostty

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Check if the reflow test is expected to pass or skip
rg -B5 "test.*resize with reflow and saved cursor" src/terminal/Terminal.zig | head -20

Repository: manaflow-ai/ghostty

Length of output: 349


🏁 Script executed:

#!/bin/bash
# Examine the terminal build_options file
cat -n src/terminal/build_options.zig

Repository: manaflow-ai/ghostty

Length of output: 2416


🏁 Script executed:

#!/bin/bash
# Search for all available build options in the terminal module
rg -n "pub const" src/terminal/build_options.zig

Repository: manaflow-ai/ghostty

Length of output: 124


🏁 Script executed:

#!/bin/bash
# Check if there's any reference to cmux anywhere in build configuration
rg -n "cmux" build.zig build.zig.zon src/

Repository: manaflow-ai/ghostty

Length of output: 277


Scope mismatch: no-reflow is applied globally without a cmux-specific build option.

This change unconditionally hard-disables reflow and prompt redraw for all primary-screen resizes. The comments reference cmux behavior, but no cmux build option exists in the codebase to gate this. This will alter default Ghostty resize semantics globally rather than only for a cmux-specific mode.

The reflow tests ("resize with reflow and saved cursor", etc.) will now silently run with reflow disabled despite their names implying reflow should be active, making them misleading.

To align with the stated cmux-only intent, either:

  1. Create a cmux build option in src/terminal/build_options.zig and gate the resize behavior conditionally, or
  2. Clarify that the global behavior change is intentional.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/terminal/Terminal.zig` around lines 2729 - 2735, The patch
unconditionally disables reflow and prompt_redraw in Terminal.zig (the .reflow
and .prompt_redraw fields) even though the comments say this should be
cmux-specific; add a compile-time build option and gate these settings: declare
a boolean build option (e.g., enableCmux) in src/terminal/build_options.zig,
expose it as a comptime/config constant, and wrap the Terminal.zig assignment so
.reflow and .prompt_redraw are set to false only when that build option is
enabled (otherwise keep current defaults); alternatively, if the intent is
global, update the comment and the tests to reflect that reflow is globally
disabled.

@greptile-apps
Copy link

greptile-apps bot commented Mar 2, 2026

Greptile Summary

This PR modifies the Terminal.resize function to unconditionally disable reflow and prompt redraw during terminal resize operations. While the PR description states this is "for cmux builds" to improve stability during SSH sessions, the implementation affects all Ghostty builds without any conditional compilation or runtime configuration.

Key concerns:

  • Breaking change: Previously, reflow behavior was controlled by self.modes.get(.wraparound) (user configurable), now it's hardcoded to false
  • Missing conditional: No build-time flag or runtime option distinguishes cmux builds from standard Ghostty builds
  • Ignored user preferences: Users who configured shell_redraws_prompt or enabled wraparound mode will have their settings ignored
  • Potential test failures: Existing tests like "resize with reflow and saved cursor" (lines 12043, 12085) expect reflow behavior to work

Recommendation: Either add a cmux-specific build flag, make this a runtime configuration option, or clarify that this is the new default for all users and update documentation/tests accordingly.

Confidence Score: 2/5

  • This PR has significant issues - it breaks existing functionality for all users instead of targeting cmux builds specifically
  • The hardcoded behavior change affects all builds unconditionally, ignoring user configuration and contradicting the PR description's claim of being "for cmux builds". This could break existing workflows and tests that rely on reflow behavior.
  • src/terminal/Terminal.zig requires immediate attention - the resize logic needs either conditional compilation or runtime configuration to avoid breaking non-cmux users

Important Files Changed

Filename Overview
src/terminal/Terminal.zig Hardcodes reflow and prompt_redraw to false for ALL builds instead of just cmux, ignoring user configuration and breaking existing behavior

Last reviewed commit: 015b822

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

1 file reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

// cmux: preserve terminal content stability across aggressive pane
// resize churn (especially for SSH-driven shells). Prefer tmux-style
// no-reflow semantics over potential history loss.
.reflow = false,
Copy link

Choose a reason for hiding this comment

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

This hardcoded reflow = false breaks existing behavior for all Ghostty builds, not just cmux. Previously, reflow was conditional on self.modes.get(.wraparound), respecting user configuration. The PR title mentions "for cmux builds" but there's no build-time or runtime conditional here.

Consider either:

  1. Adding a build option for cmux and conditionally disabling reflow: reflow = if (comptime build_options.cmux) false else self.modes.get(.wraparound)
  2. Adding a runtime config option that cmux users can set
  3. If this is intended for all builds, update the PR description and verify existing tests still pass (e.g., "resize with reflow" tests at lines 12043 and 12085)

.reflow = false,
// cmux: prompt redraw on resize can blank substantial history under
// repeated split-resize churn. Preserve scrollback over prompt cleanup.
.prompt_redraw = .false,
Copy link

Choose a reason for hiding this comment

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

Same issue as above - prompt_redraw = .false is hardcoded for all builds. Previously this was conditional on self.flags.shell_redraws_prompt. Users who configured their terminal to redraw prompts on resize will now have that setting ignored.

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