From 0fa3d94307bf1e2f572dcbe5060632caa7c7e224 Mon Sep 17 00:00:00 2001 From: shuki Date: Sat, 7 Mar 2026 07:22:39 +0200 Subject: [PATCH] Fix mobile keyboard: remove readonly, use inputmode only --- tui/web_templates/app_index.html | 51 +++++++++++++++++++------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/tui/web_templates/app_index.html b/tui/web_templates/app_index.html index 333e9eb..3ed90d6 100644 --- a/tui/web_templates/app_index.html +++ b/tui/web_templates/app_index.html @@ -165,7 +165,7 @@ } })(); - // Mobile keyboard control: prevent keyboard on every tap, add toggle button + // Mobile keyboard control: toggle button to show/hide virtual keyboard (function() { if (!("ontouchstart" in window)) return; @@ -178,52 +178,61 @@ btn.style.cssText = "position:fixed;bottom:12px;right:12px;z-index:9999;" + "width:44px;height:44px;border-radius:50%;background:rgba(94,11,167,0.85);" + "color:#fff;font-size:22px;display:flex;align-items:center;justify-content:center;" + - "cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,0.4);user-select:none;"; + "cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,0.4);user-select:none;" + + "-webkit-tap-highlight-color:transparent;"; document.addEventListener("DOMContentLoaded", function() { document.body.appendChild(btn); }); - function setKeyboard(open) { - kbOpen = open; - var ta = document.querySelector(".xterm-helper-textarea"); - if (!ta) return; - if (open) { - ta.removeAttribute("readonly"); + function getTA() { + return document.querySelector(".xterm-helper-textarea"); + } + + function openKeyboard() { + kbOpen = true; + var ta = getTA(); + if (ta) { ta.setAttribute("inputmode", "text"); ta.focus(); - btn.style.background = "rgba(0,204,0,0.85)"; - } else { - ta.setAttribute("inputmode", "none"); - ta.setAttribute("readonly", "readonly"); - ta.blur(); - btn.style.background = "rgba(94,11,167,0.85)"; } + btn.style.background = "rgba(0,204,0,0.85)"; + btn.textContent = "✕"; + } + + function closeKeyboard() { + kbOpen = false; + var ta = getTA(); + if (ta) { + ta.setAttribute("inputmode", "none"); + ta.blur(); + } + btn.style.background = "rgba(94,11,167,0.85)"; + btn.textContent = "⌨"; } btn.addEventListener("click", function(e) { e.preventDefault(); e.stopPropagation(); - setKeyboard(!kbOpen); + if (kbOpen) closeKeyboard(); else openKeyboard(); }); - // Block xterm from auto-focusing its textarea on touch + // Prevent keyboard from auto-opening on every tap document.addEventListener("touchend", function(e) { if (e.target === btn || btn.contains(e.target)) return; - if (kbOpen) return; // user wants keyboard open + if (kbOpen) return; setTimeout(function() { var active = document.activeElement; if (active && active.classList && active.classList.contains("xterm-helper-textarea")) { active.blur(); } - }, 50); + }, 30); }, { passive: true }); - // Disable keyboard on xterm textarea once it appears + // Set inputmode=none on xterm textarea once it appears (prevent initial keyboard) var checkReady = setInterval(function() { - var ta = document.querySelector(".xterm-helper-textarea"); + var ta = getTA(); if (ta) { clearInterval(checkReady); - ta.setAttribute("readonly", "readonly"); ta.setAttribute("inputmode", "none"); } }, 200);