fix(run): restore wheel scrolling in the terminal, suppress only arrow emulation
The previous `attachCustomWheelEventHandler(() => false)` killed scrolling outright. xterm's `bindMouse` consults that handler in BOTH wheel paths — the one that emits a real SGR mouse report and the fallback that turns a notch on an alt-screen buffer into ESC[A/ESC[B — so a blanket false also blocked tmux's own wheel scrolling (tmux runs with `mouse on`, i.e. tracking is active). Now the handler returns false only for the exact bad case: no wheel tracking AND an alternate buffer. `x10` counts as untracked because that protocol reports button presses only, never the wheel, so xterm takes the emulation path for it too.
This commit is contained in:
@@ -31,14 +31,20 @@ export function TerminalView({ runId, wsBaseUrl }: TerminalViewProps) {
|
||||
if (containerRef.current) term.open(containerRef.current);
|
||||
fit.fit();
|
||||
|
||||
// When the pane's program has NOT enabled mouse tracking, xterm falls back
|
||||
// When the pane's program has NOT enabled wheel reporting, xterm falls back
|
||||
// to converting each wheel notch on an alt-screen buffer into a cursor-key
|
||||
// press (ESC[A / ESC[B). In a `claude` pane that reads as arrow up/down —
|
||||
// the wheel silently walks the prompt history instead of scrolling. This
|
||||
// handler kills only that emulation branch: real mouse reports are sent by
|
||||
// a separate listener xterm registers when the program does ask for wheel
|
||||
// events, so wheel scrolling still works wherever tracking is on.
|
||||
term.attachCustomWheelEventHandler(() => false);
|
||||
// the wheel silently walks the prompt history instead of scrolling. Kill
|
||||
// ONLY that branch: xterm runs this same handler before sending a real SGR
|
||||
// mouse report too (`bindMouse`'s wheel case consults it), so a blanket
|
||||
// `false` also blocks tmux's own wheel scrolling. `x10` counts as off here
|
||||
// because that protocol reports button presses only, never the wheel — so
|
||||
// xterm takes the emulation path for it as well.
|
||||
term.attachCustomWheelEventHandler(() => {
|
||||
const mode = term.modes.mouseTrackingMode;
|
||||
const tracked = mode !== "none" && mode !== "x10";
|
||||
return tracked || term.buffer.active.type !== "alternate";
|
||||
});
|
||||
|
||||
// xterm sends Shift+Tab as ESC[Z but — unlike plain Tab — never marks the
|
||||
// event cancelled, so the browser still runs its default action and moves
|
||||
|
||||
Reference in New Issue
Block a user