Claude Code on Linux: Scrolling and Copy/Paste
The Symptom
Section titled “The Symptom”You spin the mouse wheel to reach an older message. The view does not move. Instead the input box cycles through prompts you typed earlier, as though you had pressed the up arrow. Arrow keys do the same. Scrolling back through a session becomes impossible.
Claude Code knows this is happening and says so in the bottom right corner:
Scroll wheel is sending arrow keys · use PgUp/PgDn to scrollTwo related symptoms usually arrive with it. Ctrl+Shift+C silently does nothing in the response area, while middle-click paste keeps working. Text selection with the mouse does not select.
All three have the same root cause, so one fix addresses all three.
The Fix
Section titled “The Fix”In ~/.claude/settings.json:
{ "env": { "CLAUDE_CODE_DISABLE_MOUSE": "1", "CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN": "1" }, "tui": "default"}Restart Claude Code. Both variables are read once, at startup.
The trade-off is that elements inside the Claude Code interface stop being clickable, because the terminal now owns the mouse. PgUp and PgDn keep working regardless, in every configuration. When something is broken, that is your escape hatch.
Why It Happens
Section titled “Why It Happens”Terminals keep two screen buffers. The normal buffer accumulates scrollback. The alternate buffer does not, which is how vim and less leave your shell history unchanged when they exit.
Claude Code has two rendering modes. The fullscreen renderer puts the terminal on the alternate screen and turns on alternate scroll mode, which tells the terminal to stop scrolling its own buffer and convert each wheel notch into an Up or Down arrow keypress sent to the application. Claude Code normally compensates by also requesting mouse events and consuming those wheel events itself.
Now look at what happens if you set only half the fix.
CLAUDE_CODE_DISABLE_MOUSE=1 switches off mouse reporting while leaving alternate scroll mode on. The wheel arrives as arrow keys, the arrows land in the prompt box, and the prompt box does the one thing arrows do there. Worse, the alternate screen has no scrollback to fall back on, so there is nothing to scroll even in principle. Setting that variable on its own makes scrolling worse, not better. This is the single most common way people get stuck, because it is the variable whose name sounds like the fix.
CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1 is what pins the classic renderer, so the conversation lives in your terminal’s real scrollback buffer and there is something for the wheel to reach. The two belong together.
Why It Comes Back
Section titled “Why It Comes Back”The intermittency is the part that makes people doubt their own configuration. A session that worked yesterday breaks today with no local change. You are not imagining it, and it is not your machine.
Claude Code decides which renderer to use by walking an ordered list of conditions and taking the first match. Roughly, in order:
- Background session kind, which forces fullscreen
- Screen reader detected, which forces classic
CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN, which forces classicCLAUDE_CODE_NO_FLICKER=true, which forces fullscreen- tmux control mode, and SSH on Windows, both of which force classic
- Your
tuisetting insettings.json - Two remote gates, which decide server-side
Two things fall out of that ordering.
The env var sits above the remote gates, which is the whole point of setting it. Those gates at the bottom can be flipped by Anthropic between sessions with no local change on your part, and that is what the intermittency actually is. Anything above them wins.
The env var is not unconditional, though. A background session kind is checked first and forces the alternate screen regardless of what you set.
The /tui Trap
Section titled “The /tui Trap”tui and the env var look redundant. They are not, and this is worth knowing because it bites in a way that looks like the fix failing.
The env var wins on precedence, as above. The tui setting survives a relaunch, and that matters because /tui does not simply repaint. It re-executes Claude Code, and it deliberately drops CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN from the environment on the way. After any /tui switch, that variable is gone from the process for the rest of the session, and your settings.json tui value is the only thing left standing between you and the remote gate.
So set both. Not for redundancy, for coverage. And do not reach for /tui as a reflex fix when the wheel breaks, because it disarms the thing that was protecting you.
Over SSH, Half the Advice Applies to the Wrong Machine
Section titled “Over SSH, Half the Advice Applies to the Wrong Machine”Split the problem in two and the confusion goes away.
Claude Code’s config is server-side. The settings.json on the machine running Claude Code is what gets read.
The wheel and the scrollback are client-side. Once the mouse is released, the wheel is handled by the terminal emulator you are physically sitting at, and the scrollback you page through is your local terminal’s buffer.
So if you set your terminal to unlimited scrollback, do it on your laptop, not on the server. A 10,000 line default on the client is the real ceiling no matter how the server is configured.
Claude Code does treat SSH plus the alternate screen as a known bad combination and auto-selects the classic renderer for it. But only on Windows. Linux to Linux SSH gets no such protection, which is exactly when you need the setting most.
What Does Not Transfer From the Issue Threads
Section titled “What Does Not Transfer From the Issue Threads”The most common advice online is to turn off “Scroll wheel sends arrow keys when in alternate screen mode” in iTerm2, or to enable mouse and scroll reporting in Warp. Both are macOS terminals.
GNOME Terminal has no equivalent setting. Its profile schema carries only these, and none of them govern alternate scroll:
scroll-on-insert scroll-on-keystroke scroll-on-outputscrollback-lines scrollback-unlimited scrollbar-policyOn Linux the fix has to come from Claude Code’s side.
Scrollback Depth
Section titled “Scrollback Depth”Once the classic renderer is pinned, the conversation lives in your terminal’s real buffer, so that buffer’s depth becomes the limit on how far back you can scroll. Both common terminals ship with a cap a Claude Code session will blow through quickly.
GNOME Terminal, default 10,000 lines:
$ P=$(gsettings get org.gnome.Terminal.ProfilesList default | tr -d \")$ gsettings set "org.gnome.Terminal.Legacy.Profile:/org/gnome/terminal/legacy/profiles:/:$P/" scrollback-unlimited truekitty, default 2,000 lines. In ~/.config/kitty/kitty.conf, where a negative value means unlimited:
scrollback_lines -1Under tmux
Section titled “Under tmux”tmux changes the picture, because now three parties want the wheel rather than two.
The good news is that a correctly configured tmux keeps its own deep scrollback and hands the wheel to it. The catch is that this only works once Claude Code has released the mouse. Leave the mouse with Claude Code and tmux forwards the wheel straight to it, and tmux’s scrollback sits there correct and unreachable.
There is a quieter version of the same trap. If Claude Code runs on tmux’s alternate screen, tmux’s history never receives the conversation at all, for the same reason your terminal’s scrollback goes blind when tmux starts. You scroll up and find whatever was on screen before you launched it.
The tmux side of this, including a config to start from and what deep scrollback costs in memory, is covered in tmux: Sessions That Survive.
If It Breaks Again
Section titled “If It Breaks Again”-
Look at the bottom right.
Scroll wheel is sending arrow keysnames the failure outright. -
Check the variables actually reached the process, from inside the broken session rather than a fresh terminal. Claude Code passes its environment to child processes, so asking it to run
envtells you what it actually saw. A clean terminal tells you nothing about the broken session.Terminal window $ env | grep -E 'CLAUDE_CODE_DISABLE_MOUSE|ALTERNATE_SCREEN|SESSION_KIND|NO_FLICKER'If
CLAUDE_CODE_DISABLE_ALTERNATE_SCREENis missing, something dropped it, and/tuiis the known path. If it is present and the wheel is still broken, the renderer is not your problem and it is worth reporting upstream. -
PgUpandPgDnalways work, in every mode. Use them while you sort out the config. -
Do not run
/tui. See above.
Upstream
Section titled “Upstream”As of July 2026 this is an open regression rather than a configuration mistake on your part. The relevant issues on the claude-code tracker are #65833, #66601, #70724, and #64214. All were open at the time of writing, none had a response from Anthropic, and the behaviour was fixed once in v2.1.160 and later regressed.
Set expectations accordingly, and check whether they have closed before assuming any of this still applies.