From 2b6a58f9df5a2c015356ecd8aadc4cb173914408 Mon Sep 17 00:00:00 2001 From: shuki Date: Sat, 7 Mar 2026 01:22:24 +0200 Subject: [PATCH] Fix touch scroll: dispatch wheel events to xterm canvas for page scrolling Target the xterm canvas element with WheelEvent including proper clientX/clientY coordinates so xterm.js forwards scroll events to the Textual app for container-level scrolling. Co-Authored-By: Claude Opus 4.6 --- tui/web_templates/app_index.html | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/tui/web_templates/app_index.html b/tui/web_templates/app_index.html index 57a87da..4001197 100644 --- a/tui/web_templates/app_index.html +++ b/tui/web_templates/app_index.html @@ -164,11 +164,11 @@ } })(); - // Touch-to-scroll: translate swipe gestures into key events for Textual + // Touch-to-scroll: translate swipe into mouse wheel for Textual scrollable containers (function() { var touchStartY = null; var accumDY = 0; - var STEP = 20; // pixels per scroll step + var STEP = 10; document.addEventListener("touchstart", function(e) { if (e.touches.length === 1) { @@ -185,14 +185,23 @@ accumDY += touchStartY - currentY; touchStartY = currentY; - var textarea = document.querySelector(".xterm-helper-textarea"); - if (!textarea) return; + // Find the xterm canvas to dispatch wheel events on + var canvas = document.querySelector(".xterm-screen canvas") || + document.querySelector(".xterm-screen") || + document.querySelector("#terminal"); + if (!canvas) 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 + var delta = accumDY > 0 ? 60 : -60; + canvas.dispatchEvent(new WheelEvent("wheel", { + deltaY: delta, + deltaX: 0, + deltaMode: 0, + clientX: canvas.getBoundingClientRect().width / 2, + clientY: canvas.getBoundingClientRect().height / 2, + bubbles: true, + cancelable: true, + composed: true })); accumDY -= (accumDY > 0 ? STEP : -STEP); }