When multiple xterm.js instances share a tmux session (e.g., React split terminals), enabling convertEol: true causes output corruption:
- Text bleeding between split panes
- Misaligned split divider (offset on first few rows only)
- Cursor positioning errors
- Tmux sends terminal sequences with proper line endings (
\n) - xterm.js with
convertEol: trueconverts\n→\r\n(carriage return + line feed) - Each xterm instance in the split converts the same tmux output independently
- Different cursor positioning = panes corrupt each other
Conditionally disable EOL conversion for tmux sessions:
// Terminal.tsx - xterm initialization
const isTmuxSession = !!agent.sessionName || shouldUseTmux;
const xtermOptions = {
theme: theme.xterm,
fontSize: savedFontSize,
cursorBlink: true,
allowProposedApi: true,
cursorStyle: "block",
scrollback: isTmuxSession ? 0 : 10000,
// CRITICAL: Disable EOL conversion for tmux
// Tmux manages its own terminal sequences - xterm should display raw output
convertEol: !isTmuxSession, // Only convert for regular shells
// Ensure UNIX-style line endings
windowsMode: false,
};
const xterm = new XTerm(xtermOptions);- Tmux sessions:
convertEol: false→ xterm displays raw PTY output without modification - Regular shells:
convertEol: true→ xterm converts for proper display (Windows compatibility) - Both xterm instances now handle tmux output identically → no corruption
- Tmux is a terminal multiplexer - it manages its own terminal protocol
- Multiple xterm instances sharing one tmux session must handle output identically
- EOL conversion must be disabled to prevent double-processing of tmux sequences
windowsMode: falseensures UNIX-style line endings (\nonly, not\r\n)
After applying the fix:
- Spawn a TUI terminal (e.g., TFE, htop)
- Split it horizontally or vertically
- Spawn a bash terminal in the new pane
- Type commands, check for corruption
Expected behavior:
- Each pane displays independently
- No text bleeding between panes
- Line breaks work correctly in both panes
- Split divider stays aligned
When splitting tmux sessions, both panes must use the same font to calculate matching dimensions. Different fonts = different character heights = dimension mismatch.
Solution: Track reference dimensions per session and normalize fonts before xterm initialization.
// useTmuxSessionDimensions.ts
const tmuxSessionDimensions = new Map<string, {
rows: number;
cols: number;
fontFamily: string;
fontSize: number;
}>();
// Terminal.tsx - Before creating xterm
if (isTmuxSession && agent.sessionName) {
const reference = getReference();
if (reference) {
// Use reference font to ensure matching dimensions
savedFontFamily = reference.fontFamily;
savedFontSize = reference.fontSize;
}
}src/components/Terminal.tsx- xterm initialization with conditional EOL conversionsrc/hooks/useTmuxSessionDimensions.ts- Font normalization for splits
Project: Tabz - Lightweight, tab-based terminal interface for the web Commit: cc05c4a - fix: disable EOL conversion for tmux splits to prevent corruption