diff --git a/tui/web_templates/app_index.html b/tui/web_templates/app_index.html
index be72d94..f72f140 100644
--- a/tui/web_templates/app_index.html
+++ b/tui/web_templates/app_index.html
@@ -165,57 +165,44 @@
}
})();
- // Mobile keyboard control: block virtual keyboard unless toggled open
+ // Mobile: floating button to dismiss keyboard
(function() {
if (!("ontouchstart" in window)) return;
- var kbAllowed = false;
-
- // Floating toggle button
var btn = document.createElement("div");
- btn.id = "kb-toggle";
- btn.textContent = "\u2328";
+ btn.id = "kb-dismiss";
+ btn.textContent = "\u2328\u2193";
btn.style.cssText = "position:fixed;bottom:12px;right:12px;z-index:9999;" +
"width:48px;height:48px;border-radius:50%;background:rgba(94,11,167,0.9);" +
- "color:#fff;font-size:24px;display:flex;align-items:center;justify-content:center;" +
+ "color:#fff;font-size:20px;display:none;align-items:center;justify-content:center;" +
"cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,0.5);user-select:none;" +
"-webkit-tap-highlight-color:transparent;touch-action:manipulation;";
document.addEventListener("DOMContentLoaded", function() {
document.body.appendChild(btn);
});
- btn.addEventListener("touchstart", function(e) {
- e.preventDefault();
- e.stopPropagation();
- kbAllowed = !kbAllowed;
- var ta = document.querySelector(".xterm-helper-textarea");
- if (kbAllowed) {
- btn.style.background = "rgba(0,204,0,0.9)";
- btn.textContent = "\u2715";
- if (ta) { ta.inputMode = "text"; ta.focus(); }
- } else {
- btn.style.background = "rgba(94,11,167,0.9)";
- btn.textContent = "\u2328";
- if (ta) { ta.inputMode = "none"; ta.blur(); }
- }
- }, { passive: false });
-
- // Intercept focus on xterm textarea — set inputmode=none if keyboard not allowed
+ // Show dismiss button when keyboard is likely open (textarea focused)
document.addEventListener("focusin", function(e) {
- if (kbAllowed) return;
if (e.target && e.target.classList && e.target.classList.contains("xterm-helper-textarea")) {
- e.target.inputMode = "none";
+ btn.style.display = "flex";
}
}, true);
- // Set inputmode=none as soon as textarea appears
- new MutationObserver(function(mutations, obs) {
+ // Dismiss keyboard on tap
+ btn.addEventListener("touchstart", function(e) {
+ e.preventDefault();
+ e.stopPropagation();
var ta = document.querySelector(".xterm-helper-textarea");
- if (ta) {
- ta.inputMode = "none";
- obs.disconnect();
+ if (ta) ta.blur();
+ btn.style.display = "none";
+ }, { passive: false });
+
+ // Hide button when keyboard closes
+ document.addEventListener("focusout", function(e) {
+ if (e.target && e.target.classList && e.target.classList.contains("xterm-helper-textarea")) {
+ setTimeout(function() { btn.style.display = "none"; }, 300);
}
- }).observe(document.body, { childList: true, subtree: true });
+ }, true);
})();
// Touch-to-scroll: translate swipe into mouse wheel for Textual scrollable containers