update at 2026-03-03 22:07:05
This commit is contained in:
@@ -1205,23 +1205,7 @@ async function loadWebglAddonOnDesktop(): Promise<void> {
|
||||
*/
|
||||
function initTerminal(): void {
|
||||
|
||||
// --- 极致全局监听器,抓出是谁吃掉了 move ---
|
||||
const globalEventDebug = (e: Event) => {
|
||||
// 若这是消失的 move 事件,打出到底在哪被拦截了
|
||||
if (e.type === "touchmove" || e.type === "pointermove" || e.type === "touchcancel" || e.type === "pointercancel") {
|
||||
// 为了不刷屏,如果是 pointermove 我们只在 touch 活跃时打印
|
||||
if (e.type === "pointermove" && (e as PointerEvent).pointerType !== "touch") return;
|
||||
|
||||
console.log(`[GLOBAL INTERCEPT] ${e.type} | Phase: ${e.eventPhase} | Cancelable: ${e.cancelable} | Target: ${(e.target as Element)?.className || (e.target as Element)?.tagName}`);
|
||||
}
|
||||
};
|
||||
|
||||
['touchmove', 'touchstart', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointercancel'].forEach(type => {
|
||||
// 用最顶级的 window capture 拦截,这样在任何人(包括 xterm 内部那些黑盒代码)前面执行
|
||||
window.addEventListener(type, globalEventDebug, { capture: true, passive: false });
|
||||
});
|
||||
|
||||
if (!containerRef.value) return;
|
||||
if (!containerRef.value) return;
|
||||
|
||||
terminal = new Terminal({
|
||||
// Unicode11Addon 依赖 xterm proposed API,需显式开启。
|
||||
@@ -1465,7 +1449,6 @@ function initTerminal(): void {
|
||||
};
|
||||
|
||||
onTouchKeyboardPointerDown = (event: PointerEvent) => {
|
||||
console.log("[Scroll Deep] 🟡 POINTER DOWN: ", { pointerId: event.pointerId, type: event.pointerType, target: (event.target as Node)?.nodeName });
|
||||
if (event.pointerType !== "touch") {
|
||||
return;
|
||||
}
|
||||
@@ -1527,7 +1510,6 @@ function initTerminal(): void {
|
||||
|
||||
};
|
||||
onTouchKeyboardPointerUp = (event: PointerEvent) => {
|
||||
console.log("[Scroll Deep] 🟠 POINTER UP: ", { pointerId: event.pointerId, type: event.pointerType });
|
||||
if (event.pointerType !== "touch" || touchGatePointerId !== event.pointerId) {
|
||||
return;
|
||||
}
|
||||
@@ -1536,22 +1518,7 @@ function initTerminal(): void {
|
||||
|
||||
if (Math.abs(touchScrollVelocity) > 0.2 && touchGateScrollLike && !hasActiveNativeSelectionInTerminal()) {
|
||||
touchScrollVelocity *= 1.35;
|
||||
console.log(`[Scroll Deep] 🚀 Pointer 释放,触发JS惯性,速度=${touchScrollVelocity.toFixed(2)}`);
|
||||
runTouchScrollMomentum();
|
||||
} else {
|
||||
console.log(`[Scroll Deep] 🛑 Pointer 静止释放或非滚动释放`);
|
||||
}
|
||||
|
||||
|
||||
// 释放时触发滚行动量
|
||||
|
||||
if (Math.abs(touchScrollVelocity) > 0.2 && touchGateScrollLike && !hasActiveNativeSelectionInTerminal()) {
|
||||
touchScrollVelocity *= 1.35;
|
||||
console.log(`[Scroll Deep] 🚀 Pointer 释放,触发JS惯性,速度=${touchScrollVelocity.toFixed(2)}`);
|
||||
runTouchScrollMomentum();
|
||||
} else {
|
||||
console.log(`[Scroll Deep] 🛑 Pointer 静止释放或非滚动释放`);
|
||||
}
|
||||
runTouchScrollMomentum();}
|
||||
|
||||
const context = {
|
||||
inBand: touchGateStartInBand,
|
||||
@@ -1660,7 +1627,6 @@ function initTerminal(): void {
|
||||
}
|
||||
};
|
||||
onTouchKeyboardPointerCancel = (event: PointerEvent) => {
|
||||
console.log("[Scroll Deep] ⚫ POINTER CANCEL: ", { pointerId: event.pointerId, type: event.pointerType });
|
||||
if (event.pointerType !== "touch" || touchGatePointerId !== event.pointerId) {
|
||||
return;
|
||||
}
|
||||
@@ -1694,13 +1660,6 @@ function initTerminal(): void {
|
||||
touchScrollVelocity = 0;
|
||||
}
|
||||
|
||||
console.log("[Scroll Deep] 🟢 TOUCH START:", {
|
||||
touches: event.touches.length,
|
||||
isCancelable: event.cancelable,
|
||||
target: (event.target as Node)?.nodeName,
|
||||
viewportScrollTop: viewportScroller?.scrollTop
|
||||
});
|
||||
|
||||
if (!helperTextarea) return;
|
||||
if (focusKeyboardTimerId !== null) {
|
||||
window.clearTimeout(focusKeyboardTimerId);
|
||||
@@ -1711,7 +1670,6 @@ function initTerminal(): void {
|
||||
helperTextarea.readOnly = true;
|
||||
};
|
||||
onTouchKeyboardTouchMove = (event: TouchEvent) => {
|
||||
console.log(`[Scroll Deep] 🔵 TOUCH MOVE | cancelable: ${event.cancelable} | target: ${(event.target as Node)?.nodeName}`);
|
||||
const hasSelection = hasActiveNativeSelectionInTerminal();
|
||||
if (hasSelection) {
|
||||
lastTouchAction = "PASS_NATIVE";
|
||||
@@ -1751,7 +1709,6 @@ function initTerminal(): void {
|
||||
else if (touchScrollVelocity < -touchMaxSpeed) touchScrollVelocity = -touchMaxSpeed;
|
||||
|
||||
if (Math.abs(dy) > 2) {
|
||||
console.log(`[Scroll Deep] ➡️ 手指位移真实触发生效,Δy=${dy.toFixed(1)}px | 渲染视口=${before}→${viewportScroller.scrollTop} | v=${v.toFixed(2)}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1759,16 +1716,11 @@ function initTerminal(): void {
|
||||
touchScrollLastTime = now;
|
||||
};
|
||||
onTouchKeyboardTouchEnd = (event: TouchEvent) => {
|
||||
console.log(`[Scroll Deep] 🔴 TOUCH END/CANCEL | cancelable: ${event.cancelable} | target: ${(event.target as Node)?.nodeName} | 最终 scrollTop: ${viewportScroller?.scrollTop}`);
|
||||
|
||||
|
||||
if (Math.abs(touchScrollVelocity) > 0.2) {
|
||||
touchScrollVelocity *= 1.35;
|
||||
console.log(`[Scroll Deep] 🚀 准备进行 JS 惯性滚动,起步速度=${touchScrollVelocity.toFixed(2)}`);
|
||||
runTouchScrollMomentum();
|
||||
} else {
|
||||
console.log(`[Scroll Deep] 🛑 静止释放,不触发惯性`);
|
||||
}
|
||||
runTouchScrollMomentum();}
|
||||
};
|
||||
// passive: true — 以上均不调用 preventDefault()。非 passive 的 touch 监听器
|
||||
// 会阻塞 iOS 滚动合成器等待 JS 主线程,即使实际未 preventDefault 也会引入卡顿。
|
||||
|
||||
Reference in New Issue
Block a user