From e09c6aa6bd1e8860a3b7075fc4d76640e4e04c99 Mon Sep 17 00:00:00 2001 From: Sanjays2402 <51058514+Sanjays2402@users.noreply.github.com> Date: Fri, 29 May 2026 03:26:12 -0700 Subject: [PATCH] Fix #3076: don't force mobile send-on-Enter when a real keyboard is attached MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A touch-primary device (`matchMedia('(pointer:coarse)')` is true) can still have a physical keyboard available — Android tablet + Bluetooth keyboard, detachable Surface, iPad + Magic Keyboard. The existing `_mobileDefault` gate flipped Enter to newline on every such device the moment the visual-viewport heuristic *thought* the soft keyboard was open, which it often did when the on-screen IME hadn't actually come up because the user is typing on the hardware keys. Result: Shift+Enter and Ctrl+Enter never sent and the user could not submit at all. Add `_hasFinePointerCoexisting()` (`(any-pointer:fine)`) and short- circuit the mobile-default path when ANY fine pointer is present. That flag is true whenever a real mouse/trackpad/stylus is paired, which is the strongest browser signal we have for 'there is a hardware input rig in the picture too'. Pure-touch phones/tablets are unaffected. --- static/boot.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/static/boot.js b/static/boot.js index 072171b5..23a90cac 100644 --- a/static/boot.js +++ b/static/boot.js @@ -1115,6 +1115,18 @@ function _isVirtualKeyboardLikelyOpen(){ if(!vv||!window.innerHeight)return true; return window.innerHeight-vv.height>120; } +// #3076: a touch-primary device (`pointer:coarse`) can still have a +// physical keyboard attached (Android tablet + Bluetooth keyboard, +// detachable Surface in tablet mode, iPad + Magic Keyboard). When that +// happens we should NOT force the mobile newline-on-Enter override +// because Shift+Enter / Ctrl+Enter come from real keys and the user +// expects desktop semantics. `matchMedia('(any-pointer:fine)')` is true +// whenever ANY available pointing device is fine-grained — which is the +// strongest signal browsers expose for "there is a real keyboard / +// trackpad in the picture too". Skip the mobile default in that case. +function _hasFinePointerCoexisting(){ + try{ return matchMedia('(any-pointer:fine)').matches; }catch(_){ return false; } +} $('msg').addEventListener('keydown',e=>{ // Autocomplete navigation when dropdown is open const dd=$('cmdDropdown'); @@ -1139,7 +1151,10 @@ $('msg').addEventListener('keydown',e=>{ // Users can override in Settings by explicitly choosing 'enter' mode. if(e.key==='Enter'){ if(_isImeEnter(e)){return;} - const _mobileDefault=matchMedia('(pointer:coarse)').matches&&window._sendKey==='enter'&&_isVirtualKeyboardLikelyOpen(); + const _mobileDefault=matchMedia('(pointer:coarse)').matches + &&!_hasFinePointerCoexisting() + &&window._sendKey==='enter' + &&_isVirtualKeyboardLikelyOpen(); if(window._sendKey==='ctrl+enter'||_mobileDefault){ if(e.ctrlKey||e.metaKey){e.preventDefault();send();} } else {