fix: 支持终端GUI应用鼠标追踪模式下的滚轮事件

This commit is contained in:
2026-03-20 16:54:27 +08:00
parent 435836378e
commit 6de7229be5

View File

@@ -112,6 +112,7 @@ const TerminalViewport = React.forwardRef<TerminalController, TerminalViewportPr
const lastProcessedChunkIdRef = React.useRef<number | null>(null);
const followOutputRef = React.useRef(true);
const touchScrollCleanupRef = React.useRef<(() => void) | null>(null);
const mouseTrackingWheelCleanupRef = React.useRef<(() => void) | null>(null);
const viewportDiscoveryTimeoutRef = React.useRef<number | null>(null);
const viewportDiscoveryAttemptsRef = React.useRef(0);
const hiddenInputRef = React.useRef<HTMLTextAreaElement | null>(null);
@@ -996,6 +997,26 @@ const TerminalViewport = React.forwardRef<TerminalController, TerminalViewportPr
bumpTerminalReady();
cursorBlinkStateRef.current = false;
const canvas = (terminal as unknown as { canvas?: HTMLCanvasElement }).canvas;
if (canvas) {
mouseTrackingWheelCleanupRef.current = () => {
canvas.removeEventListener('wheel', handleMouseTrackingWheel, { capture: true });
};
const handleMouseTrackingWheel = (event: WheelEvent) => {
const wasmTerm = terminal.wasmTerm;
if (wasmTerm && wasmTerm.hasMouseTracking()) {
event.stopImmediatePropagation();
const rect = canvas.getBoundingClientRect();
const x = Math.round((event.clientX - rect.left) / (rect.width / terminal.cols));
const y = Math.round((event.clientY - rect.top) / (rect.height / terminal.rows));
const button = event.deltaY < 0 ? 64 : 65;
terminal.input(`\x1b[<${button};${x};${y}M`);
terminal.input(`\x1b[<${button - 32};${x};${y}m`);
}
};
canvas.addEventListener('wheel', handleMouseTrackingWheel, { capture: true });
}
localTerminalTextarea =
(terminal as unknown as { textarea?: HTMLTextAreaElement | null }).textarea
?? container.querySelector('textarea');
@@ -1082,6 +1103,8 @@ const TerminalViewport = React.forwardRef<TerminalController, TerminalViewportPr
localDisposables.forEach((disposable) => disposable.dispose());
restorePatchedScrollToBottom?.();
restorePatchedScrollToBottom = null;
mouseTrackingWheelCleanupRef.current?.();
mouseTrackingWheelCleanupRef.current = null;
if (localTerminalTextarea) {
localTerminalTextarea.removeEventListener('focus', handleTerminalTextareaFocus);
localTerminalTextarea.removeEventListener('blur', handleTerminalTextareaBlur);