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 {