fix(shell): keep keyboard hidden during mobile long-press selection

Long-pressing an xterm view to select text still let the browser
synthesize the click that focuses xterm's hidden helper textarea,
popping the mobile keyboard over the selection.

Suppress that synthesized focus on touchend when a selection or handle
drag is active and blur the textarea, both when a selection begins and
when the touch ends. A plain tap is unaffected, so it still focuses the
terminal and shows the keyboard as before.
This commit is contained in:
Haileyesus
2026-06-29 13:59:50 +03:00
parent fb34f106e7
commit 1cfb6e5590

View File

@@ -378,7 +378,7 @@ class ShellMobileSelectionCore implements MobileTerminalSelectionManager {
this.recordScrollSample(touch);
};
private onTerminalTouchEnd = (): void => {
private onTerminalTouchEnd = (event: TouchEvent): void => {
if (this.isPinching) {
this.endPinchZoom();
return;
@@ -387,6 +387,15 @@ class ShellMobileSelectionCore implements MobileTerminalSelectionManager {
this.clearTapHoldTimeout();
this.touchStart = null;
// A long-press selection (or a tap dismissing one) must not let the browser
// synthesize the mouse click that refocuses xterm's hidden textarea — that
// is what pops up the mobile keyboard. A plain tap leaves isSelecting false
// and falls through, so it still focuses the terminal and shows the keyboard.
if (this.isSelecting || this.isHandleDragging) {
event.preventDefault();
this.blurTerminalInput();
}
if (!this.pendingClearTouch) {
this.maybeStartInertia();
return;
@@ -508,6 +517,9 @@ class ShellMobileSelectionCore implements MobileTerminalSelectionManager {
this.selectionEnd = wordBounds?.end ?? coords;
this.isSelecting = true;
// Dismiss the mobile keyboard if it was open: selecting text is not typing.
this.blurTerminalInput();
this.updateSelection();
this.showHandles();
this.showContextMenu();
@@ -976,6 +988,13 @@ class ShellMobileSelectionCore implements MobileTerminalSelectionManager {
};
}
private blurTerminalInput(): void {
const textarea = this.terminal.element?.querySelector<HTMLTextAreaElement>(
'.xterm-helper-textarea',
);
textarea?.blur();
}
private getTerminalScreenElement(): HTMLElement | null {
return (
this.terminal.element?.querySelector<HTMLElement>('.xterm-screen') ??