diff --git a/tui/web_templates/app_index.html b/tui/web_templates/app_index.html index 37e66f8..57a87da 100644 --- a/tui/web_templates/app_index.html +++ b/tui/web_templates/app_index.html @@ -164,35 +164,43 @@ } })(); - // Touch-to-scroll: translate swipe gestures into wheel events for xterm + // Touch-to-scroll: translate swipe gestures into key events for Textual (function() { var touchStartY = null; - var THRESHOLD = 5; + var accumDY = 0; + var STEP = 20; // pixels per scroll step document.addEventListener("touchstart", function(e) { if (e.touches.length === 1) { touchStartY = e.touches[0].clientY; + accumDY = 0; } }, { passive: true }); document.addEventListener("touchmove", function(e) { if (touchStartY === null || e.touches.length !== 1) return; - var dy = touchStartY - e.touches[0].clientY; - if (Math.abs(dy) < THRESHOLD) return; - touchStartY = e.touches[0].clientY; + e.preventDefault(); - var target = document.querySelector(".xterm-screen") || document.querySelector("#terminal"); - if (!target) return; - target.dispatchEvent(new WheelEvent("wheel", { - deltaY: dy > 0 ? 3 : -3, - deltaMode: 0, - bubbles: true, - cancelable: true - })); + var currentY = e.touches[0].clientY; + accumDY += touchStartY - currentY; + touchStartY = currentY; + + var textarea = document.querySelector(".xterm-helper-textarea"); + if (!textarea) return; + + while (Math.abs(accumDY) >= STEP) { + var key = accumDY > 0 ? "ArrowDown" : "ArrowUp"; + textarea.dispatchEvent(new KeyboardEvent("keydown", { + key: key, code: key, keyCode: key === "ArrowDown" ? 40 : 38, + bubbles: true, cancelable: true + })); + accumDY -= (accumDY > 0 ? STEP : -STEP); + } }, { passive: false }); document.addEventListener("touchend", function() { touchStartY = null; + accumDY = 0; }, { passive: true }); })();