Fix #3076: don't force mobile send-on-Enter when a real keyboard is co-present - #3130
Conversation
…ard 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.
|
LGTM. The fix maps directly to the reporter's suggestion in #3076 ("Disable or refine the Code referencePre-PR gate (static/boot.js:1142): const _mobileDefault=matchMedia('(pointer:coarse)').matches
&&window._sendKey==='enter'
&&_isVirtualKeyboardLikelyOpen();The bug: The post-PR gate: const _mobileDefault=matchMedia('(pointer:coarse)').matches
&&!_hasFinePointerCoexisting()
&&window._sendKey==='enter'
&&_isVirtualKeyboardLikelyOpen();
Browser support is fine
Edge cases I traced
One small noteThe PR's risk section says "A touch-only device that ships with a 'fine' pointer (some smart-TV setups expose a remote as fine pointer) would lose the mobile default." Worth pinning the explicit setting in Settings as the documented escape hatch — Test plan suggestionThe PR's verification is just lint + spec-support check. The actual regression has to be tested on the reporter's hardware (Android tablet + Bluetooth keyboard), since the bug is in the interaction between Minimal, targeted, correctly diagnosed. Ship it after a single end-to-end confirmation on the reporter's setup. |
1ebd160
Thinking Path
Issue #3076 reports that Shift+Enter and Ctrl+Enter don't work on an Android tablet with an external keyboard. Traced to
static/boot.js:1142:The problem: a touch-primary device (
pointer:coarse) can also have a physical keyboard attached (Android tablet + Bluetooth keyboard, detachable Surface, iPad + Magic Keyboard). When that's the case, the visual-viewport heuristic in_isVirtualKeyboardLikelyOpen()often returns true (toolbar inset, on-screen IME hint chip, etc.) even though the user is typing on hardware keys, and_mobileDefaultflips Enter to newline. Combined with thectrlKey || metaKeygate, the user cannot submit at all.What Changed
static/boot.js:_hasFinePointerCoexisting()helper —matchMedia('(any-pointer:fine)'). This is the strongest browser signal for "there is a real keyboard/trackpad/stylus in the picture alongside touch"._mobileDefaultpath when any fine pointer is co-present. Pure-touch phones/tablets are unaffected.Why It Matters
Closes #3076. Hardware-keyboard users on touch devices regain desktop submission semantics. Pure-touch users keep newline-on-Enter.
Verification
(any-pointer:fine)is supported across all evergreen browsers (Chrome, Firefox, Safari, Edge — Level 4 Media Queries, shipped since ~2017).try/catchso unknown-query environments fall back to the prior behavior.Risks / Follow-ups
A touch-only device that ships with a "fine" pointer (some smart-TV setups expose a remote as fine pointer) would lose the mobile default. The risk is small — those devices typically aren't running hermes-webui interactively — and the failure mode there (desktop Enter semantics on a TV) is recoverable via the explicit Settings choice that already exists.
Model Used
claude-opus-4.7 via GitHub Copilot.
Closes #3076.