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:
1 parent
cf003ae986
commit
e09c6aa6bd
1 file changed
+16
-1
+16
-1
@@ -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 {
|
||||
|
||||
Reference in new issue
Block a user