Reported by
@blixt
Description
When scrolling up a few lines (e.g., 5 lines to read a paragraph), new output arrives and the user must scroll down past hundreds of lines of duplicate screen content to get back to the bottom. The ratio is severely disproportionate: scroll up 5 lines, scroll down 300+ lines.
This makes scrollback essentially unusable for quick reference during active terminal sessions.
Steps to reproduce
- Have a workstream with Claude Code actively working (tmux mode)
- Scroll up ~5 lines to read recent output
- Wait for Claude to produce new output (TUI redraws)
- Try to scroll back to the bottom
- Observe: must scroll past large amounts of duplicate content
Root cause
The issue is a chain of architectural decisions:
1. Alternate screen is disabled
TmuxSession.swift (lines 20-39) configures tmux with:
set -g alternate-screen off
set -ga terminal-overrides ',*:smcup@:rmcup@'
alternate-screen off disables alternate screen at the tmux pane level
smcup@ / rmcup@ strips the enter/exit alternate screen escape sequences for all terminal types
- This was intentionally added in commit a455855 ("fix: restore native mouse behavior in tmux terminals") so Ghostty handles mouse events directly
2. Claude Code's TUI redraws the entire screen
Claude Code uses a full-screen TUI that redraws on every update. Normally, TUI apps use the alternate screen buffer, which isolates redraws from scrollback. With alternate screen disabled, every redraw dumps ~50-80 lines (full terminal height) into the normal scrollback buffer.
3. The interaction
- User scrolls up 5 lines in scrollback
- Claude produces output, triggering a TUI redraw
- The redraw writes the entire screen (~80 lines) into the scrollback buffer
- Multiple rapid redraws compound this (Claude updates frequently)
- Result: 300+ lines of duplicate content between the user's scroll position and the bottom
Scope
- Tmux mode: Directly affected (alternate screen explicitly disabled)
- Non-tmux mode: Likely unaffected (Ghostty manages alternate screen normally)
- Controlled by
@AppStorage("factoryfloor.tmuxMode") in TerminalContainerView.swift
Possible approaches
- Re-enable alternate screen but find another way to handle mouse passthrough. The original commit suggests this was a tradeoff for native mouse behavior.
- Use tmux's
terminal-overrides more selectively to only strip capabilities that conflict with mouse handling, not smcup/rmcup entirely.
- Auto-scroll to bottom on new output when the user is within N lines of the bottom (doesn't fix the duplication, but mitigates the symptom).
References
Sources/Models/TmuxSession.swift lines 20-39 (tmux config)
Tests/TmuxSessionTests.swift lines 13-19 (testConfigDisablesPaneAlternateScreen)
- Commit a455855 ("fix: restore native mouse behavior in tmux terminals")
Sources/Views/TerminalContainerView.swift lines 226-237 (tmux mode toggle)
Reported by
@blixt
Description
When scrolling up a few lines (e.g., 5 lines to read a paragraph), new output arrives and the user must scroll down past hundreds of lines of duplicate screen content to get back to the bottom. The ratio is severely disproportionate: scroll up 5 lines, scroll down 300+ lines.
This makes scrollback essentially unusable for quick reference during active terminal sessions.
Steps to reproduce
Root cause
The issue is a chain of architectural decisions:
1. Alternate screen is disabled
TmuxSession.swift(lines 20-39) configures tmux with:alternate-screen offdisables alternate screen at the tmux pane levelsmcup@/rmcup@strips the enter/exit alternate screen escape sequences for all terminal types2. Claude Code's TUI redraws the entire screen
Claude Code uses a full-screen TUI that redraws on every update. Normally, TUI apps use the alternate screen buffer, which isolates redraws from scrollback. With alternate screen disabled, every redraw dumps ~50-80 lines (full terminal height) into the normal scrollback buffer.
3. The interaction
Scope
@AppStorage("factoryfloor.tmuxMode")inTerminalContainerView.swiftPossible approaches
terminal-overridesmore selectively to only strip capabilities that conflict with mouse handling, not smcup/rmcup entirely.References
Sources/Models/TmuxSession.swiftlines 20-39 (tmux config)Tests/TmuxSessionTests.swiftlines 13-19 (testConfigDisablesPaneAlternateScreen)Sources/Views/TerminalContainerView.swiftlines 226-237 (tmux mode toggle)