const fs = require('fs'); let code = fs.readFileSync('src/components/TerminalPanel.vue', 'utf8'); // Inside `onTouchKeyboardPointerMove`: we can perform the actual scrolling! const pointerMoveRegex = /onTouchKeyboardPointerMove = \(event: PointerEvent\) => \{[\s\S]*?touchGateScrollLike = true;\n\s*\}/m; // Let's replace the whole onTouchKeyboardPointerMove function to sync scrolling instead of just detecting it. // Actually, earlier the user showed that the `touchmove` stopped. Why did `touchmove` stop? // Because we have `touch-action: none`? // iOS Safari requires `e.preventDefault()` on `touchmove` to keep the `touchmove` stream alive, but you have to do it BEFORE the compositor steals it. // We added: `if (event.cancelable && !hasActiveNativeSelectionInTerminal()) { event.preventDefault(); }` to `touchstart`! // If we call preventDefault on touchstart, NO POINTER EVENTS or touch events should be stolen by scroll. BUT touchmove STILL DISAPPEARED? // Wait, if we call preventDefault on touchstart, does that disable pointermove? Or touchmove? // Actually if `touch-action: none` is present, pointer events fire constantly, while touch events MIGHT ONLY FIRE IF POINTER EVENTS DON'T CANCEL THEM. code = code.replace(/onTouchKeyboardPointerMove = \(event: PointerEvent\) => \{[\s\S]*?\}\;\n onTouchKeyboardPointerUp/m, ` onTouchKeyboardPointerMove = (event: PointerEvent) => { if (event.pointerType !== "touch" || touchGatePointerId !== event.pointerId) { return; } const dx = event.clientX - touchGateStartX; const dy = event.clientY - touchGateStartY; const absDx = Math.abs(dx); const absDy = Math.abs(dy); if (absDx > TOUCH_KEYBOARD_TAP_MAX_MOVE_PX || absDy > TOUCH_KEYBOARD_TAP_MAX_MOVE_PX) { touchGateMoved = true; } if (absDy > absDx && absDy > TOUCH_KEYBOARD_TAP_MAX_MOVE_PX) { touchGateScrollLike = true; } // --- Pointer Scroll Sync --- const hasSelection = hasActiveNativeSelectionInTerminal(); if (!hasSelection && viewportScroller) { // Stop system gestures like swipe back if needed event.stopImmediatePropagation(); const now = performance.now(); const dt = now - touchScrollLastTime; const currentY = event.clientY; const deltaY = currentY - (touchScrollLastY || currentY); if (dt > 0 && touchScrollLastTime > 0) { viewportScroller.scrollTop -= deltaY; const v = (-deltaY / dt) * 16; if (touchScrollVelocity * v > 0) { touchScrollVelocity = touchScrollVelocity * 0.5 + v * 0.5; } else { touchScrollVelocity = v; } const touchMaxSpeed = 120; if (touchScrollVelocity > touchMaxSpeed) touchScrollVelocity = touchMaxSpeed; else if (touchScrollVelocity < -touchMaxSpeed) touchScrollVelocity = -touchMaxSpeed; } touchScrollLastY = currentY; touchScrollLastTime = now; } }; onTouchKeyboardPointerUp`); fs.writeFileSync('src/components/TerminalPanel.vue', code);