mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-03 22:19:42 +02:00
fix(mobile): do not dismiss the keyboard when a scroll ends
Regression from the dismiss handler in #279: it fired on any touchend, and a scroll ends in touchend too. Scrolling to read something while composing closed the keyboard and dropped the composer — worse than the bug it fixed. Track finger travel from touchstart and only treat a near-stationary gesture as a tap, using the same 8px TAP_THRESHOLD the terminal's own touch handling uses so both agree on tap-vs-scroll. Multi-touch is never a dismissing tap. All three listeners stay passive; nothing calls preventDefault. Measured on a Pixel-class viewport with a Firefox UA: tap -> dismissed scroll (120px) -> keyboard kept micro-drift (4px) -> dismissed, so an imprecise tap still works Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,9 @@
|
||||
// (_installMobileKeyboardDismiss). Two groups: anything that is about to take
|
||||
// focus itself, and the accessory bar, which is built to be used while the
|
||||
// keyboard is open.
|
||||
// Finger travel (px) still counted as a tap for keyboard dismissal. Matches
|
||||
// the terminal's own TAP_THRESHOLD so both agree on tap-vs-scroll.
|
||||
const MOBILE_KEYBOARD_DISMISS_TAP_SLOP = 8;
|
||||
const MOBILE_KEYBOARD_DISMISS_EXEMPT_SELECTOR = [
|
||||
'input',
|
||||
'textarea',
|
||||
@@ -199,6 +202,7 @@
|
||||
PAGE_KEY_MAX_PER_BATCH,
|
||||
TUI_PROMPT_DEFAULT_ROWS_FROM_BOTTOM,
|
||||
MOBILE_KEYBOARD_DISMISS_EXEMPT_SELECTOR,
|
||||
MOBILE_KEYBOARD_DISMISS_TAP_SLOP,
|
||||
};
|
||||
global.CODEMAN_XTERM_THEMES = CODEMAN_XTERM_THEMES;
|
||||
global.codemanCurrentXtermTheme = currentXtermTheme;
|
||||
@@ -3534,7 +3538,35 @@ Object.assign(CodemanApp.prototype, {
|
||||
*/
|
||||
_installMobileKeyboardDismiss() {
|
||||
if (this._mobileKeyboardDismissHandler) return;
|
||||
|
||||
// A SCROLL also ends in touchend, and dismissing there is wrong: scrolling
|
||||
// to read something while composing must not close the keyboard and lose
|
||||
// the composer. Track how far the finger travelled and only treat a
|
||||
// near-stationary gesture as a tap — the same TAP_THRESHOLD the terminal's
|
||||
// own touch handling uses, so both agree on what a tap is.
|
||||
let startX = 0;
|
||||
let startY = 0;
|
||||
let moved = false;
|
||||
this._mobileKeyboardDismissStart = (ev) => {
|
||||
if (ev.touches.length !== 1) {
|
||||
moved = true; // a multi-touch gesture is never a dismissing tap
|
||||
return;
|
||||
}
|
||||
startX = ev.touches[0].clientX;
|
||||
startY = ev.touches[0].clientY;
|
||||
moved = false;
|
||||
};
|
||||
this._mobileKeyboardDismissMove = (ev) => {
|
||||
if (moved || !ev.touches.length) return;
|
||||
const dx = ev.touches[0].clientX - startX;
|
||||
const dy = ev.touches[0].clientY - startY;
|
||||
const slop = window.CodemanTerminalInput.MOBILE_KEYBOARD_DISMISS_TAP_SLOP;
|
||||
if (Math.abs(dx) > slop || Math.abs(dy) > slop) {
|
||||
moved = true;
|
||||
}
|
||||
};
|
||||
this._mobileKeyboardDismissHandler = (ev) => {
|
||||
if (moved) return;
|
||||
if (!this._isMobileTerminalInputFocused()) return;
|
||||
const target = ev.target;
|
||||
if (!target || typeof target.closest !== 'function') return;
|
||||
@@ -3542,8 +3574,10 @@ Object.assign(CodemanApp.prototype, {
|
||||
if (target.closest(window.CodemanTerminalInput.MOBILE_KEYBOARD_DISMISS_EXEMPT_SELECTOR)) return;
|
||||
this._blurMobileTerminalInput();
|
||||
};
|
||||
// Passive: this never calls preventDefault, so it must not make the page
|
||||
// feel less responsive to scrolling.
|
||||
// Passive throughout: this never calls preventDefault, so it must not make
|
||||
// the page feel less responsive to scrolling.
|
||||
document.addEventListener('touchstart', this._mobileKeyboardDismissStart, { passive: true });
|
||||
document.addEventListener('touchmove', this._mobileKeyboardDismissMove, { passive: true });
|
||||
document.addEventListener('touchend', this._mobileKeyboardDismissHandler, { passive: true });
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user