fix(app): submit on Magic Keyboard Enter in the iPadOS PWA composer - #1099
Open
salemsayed wants to merge 1 commit into
Open
fix(app): submit on Magic Keyboard Enter in the iPadOS PWA composer#1099salemsayed wants to merge 1 commit into
salemsayed wants to merge 1 commit into
Conversation
The composer gated Enter-to-submit on a coarse pointer, so an iPad always took the newline path even with a Magic Keyboard attached. In the iPad PWA there was then no way to send a prompt from the hardware keyboard. On iPadOS WebKit only, a ProseMirror DOM keydown hook now inspects the original event's physical code. A Magic Keyboard Enter reports code="Enter"/"NumpadEnter" and submits; the software keyboard's Return reports an empty code and still inserts a newline. Other platforms, including Android and coarse-pointer Windows hybrids, stay entirely on ProseMirror's normal path. The steer/queue mapping is unchanged: Enter and Command+Enter keep their existing roles under steerActiveThreadOnEnter, Shift+Enter and zen-mode Enter stay newlines, and an open typeahead menu still consumes Enter to apply its suggestion. IME composition is excluded via view.composing, event.isComposing and keyCode 229, plus ProseMirror's Safari compositionend -> keydown window, so confirming a candidate never submits. Docs, the bb-cli skill, and the bb guide template describe the resulting Enter behavior. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In the installed iPad PWA, there is no way to send a prompt from a Magic Keyboard. Pressing Enter in the composer always inserts a newline, and the only way to submit is to tap the send button.
The composer gates Enter-to-submit on pointer coarseness alone:
An iPad reports a coarse pointer whether or not a hardware keyboard is attached, so the hardware Enter is permanently routed to the newline path. Making this device-wide would break the software keyboard, whose Return must stay a newline.
Two details make the physical key hard to detect on this platform:
handleKeyDown, so the software keyboard can finish its own DOM mutation first. That synthetic event no longer carries the physicalcode.code, while a Magic Keyboard Enter arrives ascode: "Enter"(or"NumpadEnter").Fix
A custom ProseMirror DOM
keydownhook now looks at the original event before ProseMirror's deferral, and only on iPadOS WebKit. When that original event carries a physicalEnter/NumpadEntercode, the existing key handler is invoked withisOriginalIPadHardwareEnter, which enables Enter-to-submit for that one event:Device detection combines an Apple WebKit vendor/UA check with either the legacy
iPadplatform or the modern desktop-likeMacIntelplatform plusmaxTouchPoints > 2, which is what distinguishes current iPadOS from macOS.Everything else keeps ProseMirror's normal path, including the software keyboard's Return, which still inserts a newline.
Steer/queue mapping is unchanged
No submit routing changed.
canSubmitWithEnterKeysimply moved from a component-level constant to a per-event value inside the key handler.steerActiveThreadOnEnteroff (default): Enter queues a follow-up, Command+Enter steers.steerActiveThreadOnEnteron: Enter steers, Command+Enter queues.FollowUpPromptBox.test.tsxconsolidates the two overlapping shortcut tests into one parameterized case that asserts both settings, including the scroll-to-bottom behavior that differs between queue and steer.Android and desktop safeguards
The interception is scoped as narrowly as possible, and both non-iPad coarse-pointer cases are covered by tests:
Google Inc.vendor,Linux armv8l) reportscode: "Enter"from its software keyboard. It fails the Apple WebKit check, is never intercepted, and keeps Return as a newline.Win32,maxTouchPoints: 10) likewise fail the vendor check and are untouched.!isPointerCoarsepath.IME and typeahead
Composition is excluded on several fronts, so confirming a candidate never submits:
view.composing,event.isComposing, andevent.keyCode === 229all bail out.compositionend→keydownsafeguard with a 500 ms window. Because this DOM hook runs before ProseMirror's keydown handler, skipping that safeguard would submit an IME candidate confirmation.WeakSet, so if it later arrives through the normal handler it is still refused rather than double-processed.Typeahead is unaffected: with an open command or mention menu, a Magic Keyboard Enter applies the highlighted suggestion (
/→/review, with the mention resource attached) and does not submit, matching the fine-pointer behavior.Performance
isIPadOSWebKit()is computed once per mount viauseMemo. The value is stable for the lifetime of the page, so no additional media-query or event listener is registered.WeakSetlookup. Keying the set on the event object means entries are collected along with the event, so it cannot grow unbounded.canSubmitWithEnterKeyleft theuseCallbackdependency list and was replaced byisPointerCoarse, so handler identity churns no more often than before.handleEditorKeyDownRefmoved fromuseEffecttouseLayoutEffect, so the ref is current before any keydown can be dispatched after a commit and a stale handler cannot fire in the same frame.Documentation
Per the repository's rule that a user-facing behavior change updates its discoverable surfaces in the same change, the Enter behavior is now described in:
docs/configuration.mdbb-cliskill (SKILL.mdandreferences/app-settings.md)bb-guide-customization.mdand its generated counterpartEach now states the typeahead exception, Shift+Enter and zen-mode newlines, the coarse-pointer software-keyboard path, and the iPadOS Magic Keyboard behavior.
Validation
New coverage in
PromptBoxInternal.test.tsxspans fine-pointer Enter, Magic Keyboard Enter, software-keyboard Enter, Android, a Windows touch hybrid, Shift+Enter, Command+Enter, IME composition, the post-compositionendwindow, zen mode, and typeahead application.🤖 Generated with Claude Code