Disable terminal reflow during resize for cmux stability#3
Disable terminal reflow during resize for cmux stability#3lawrencecchen wants to merge 1 commit intomainfrom
Conversation
📝 WalkthroughWalkthroughTerminal 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
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
💡 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, |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
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.
| // 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, |
There was a problem hiding this comment.
🧩 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 -20Repository: 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 -10Repository: 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 -30Repository: 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 -10Repository: 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.zigRepository: 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_modulesRepository: 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.zigRepository: 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 -20Repository: manaflow-ai/ghostty
Length of output: 349
🏁 Script executed:
#!/bin/bash
# Examine the terminal build_options file
cat -n src/terminal/build_options.zigRepository: 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.zigRepository: 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:
- Create a cmux build option in
src/terminal/build_options.zigand gate the resize behavior conditionally, or - 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 SummaryThis PR modifies the Key concerns:
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
Important Files Changed
Last reviewed commit: 015b822 |
| // 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, |
There was a problem hiding this comment.
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:
- Adding a build option for cmux and conditionally disabling reflow:
reflow = if (comptime build_options.cmux) false else self.modes.get(.wraparound) - Adding a runtime config option that cmux users can set
- 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, |
There was a problem hiding this comment.
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.
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
Screen.resizecall inTerminal.resizetoreflow = falseprompt_redraw = .false) to avoid prompt-region wipes under churnValidation
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