Fix #3076: don't force mobile send-on-Enter when a real keyboard is attached

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.
This commit is contained in:
Sanjays2402 committed 2026-05-29 03:26:12 -07:00
1 parent cf003ae986
commit e09c6aa6bd
1 file changed
+16 -1
+16 -1
View File
@@ -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 {