Fix iOS keyboard activation
- Remove setTimeout which breaks iOS gesture requirement for focus() - Make textarea full-size overlay with near-zero opacity (iOS needs visible element) - Remove pointer-events:none and negative z-index that prevented touch - Use touchend instead of touchstart for more reliable iOS behavior - Call focus() synchronously within user gesture handler
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -383,17 +383,23 @@ class WebTerminal {
|
|||||||
textarea.setAttribute("spellcheck", "false");
|
textarea.setAttribute("spellcheck", "false");
|
||||||
textarea.setAttribute("inputmode", "text");
|
textarea.setAttribute("inputmode", "text");
|
||||||
textarea.setAttribute("enterkeyhint", "send");
|
textarea.setAttribute("enterkeyhint", "send");
|
||||||
// Style to be invisible but still focusable (not display:none)
|
// iOS requires the element to be "visible" and interactive for keyboard
|
||||||
|
// Use opacity near-zero but not zero, and keep it in the visible area
|
||||||
textarea.style.cssText = `
|
textarea.style.cssText = `
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 1px;
|
width: 100%;
|
||||||
height: 1px;
|
height: 100%;
|
||||||
opacity: 0;
|
opacity: 0.01;
|
||||||
z-index: -1;
|
z-index: 1;
|
||||||
pointer-events: none;
|
color: transparent;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
resize: none;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
caret-color: transparent;
|
||||||
`;
|
`;
|
||||||
// Font size 16px prevents iOS auto-zoom on focus
|
// Font size 16px prevents iOS auto-zoom on focus
|
||||||
|
|
||||||
@@ -447,24 +453,24 @@ class WebTerminal {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Focus textarea on touch/click to show mobile keyboard
|
// Focus textarea on touch/click to show mobile keyboard
|
||||||
this.element.addEventListener("touchstart", () => {
|
// iOS requires focus() to be called synchronously within the gesture
|
||||||
this.focusMobileInput();
|
this.element.addEventListener("touchend", (e) => {
|
||||||
|
// Only respond to single touch on terminal area
|
||||||
|
if (e.target === textarea || e.target === this.element || this.element.contains(e.target as Node)) {
|
||||||
|
this.mobileInput?.focus();
|
||||||
|
}
|
||||||
}, { passive: true });
|
}, { passive: true });
|
||||||
|
|
||||||
this.element.addEventListener("click", () => {
|
this.element.addEventListener("click", () => {
|
||||||
this.focusMobileInput();
|
this.mobileInput?.focus();
|
||||||
|
this.terminal.focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Focus the mobile input to show keyboard */
|
/** Focus the mobile input to show keyboard */
|
||||||
private focusMobileInput(): void {
|
private focusMobileInput(): void {
|
||||||
if (this.mobileInput) {
|
// For programmatic focus (not from user gesture), this may not show keyboard on iOS
|
||||||
// Small delay helps with iOS keyboard activation
|
this.mobileInput?.focus();
|
||||||
setTimeout(() => {
|
|
||||||
this.mobileInput?.focus({ preventScroll: true });
|
|
||||||
}, 10);
|
|
||||||
}
|
|
||||||
// Also focus the terminal for desktop
|
|
||||||
this.terminal.focus();
|
this.terminal.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user