Skip to content

fix(mobile): send on Ctrl/Cmd+Enter from a hardware keyboard on Android - #8362

Open
sideeffffect wants to merge 1 commit into
pingdotgg:mainfrom
sideeffffect:fix/android-composer-ctrl-enter
Open

sideeffffect wants to merge 1 commit into
pingdotgg:mainfrom
sideeffffect:fix/android-composer-ctrl-enter

Conversation

@sideeffffect

@sideeffffect sideeffffect commented Aug 27, 2026

Copy link
Copy Markdown

Problem

On the Android app, there is no way to send a message from a hardware (e.g. Bluetooth) keyboard. Plain Enter inserts a newline — correct for touch — but no modifier shortcut was wired, so tablet/phone users with a keyboard attached are stuck reaching for the on-screen Send button.

iOS already handles this: the Swift view registers a Cmd+Enter key command and emits an onComposerSubmit event, which T3ComposerEditor.ios.tsx forwards to the composer's onSubmit. The Android side never implemented onComposerSubmit — not in the native module, not in the view, and not in the T3ComposerEditor.native.tsx bridge.

Fix

Wire the same onComposerSubmit path on Android, mirroring iOS:

  • T3ComposerEditorModule.kt — declare the onComposerSubmit event.
  • T3ComposerEditorView.kt — the native EditText now detects Ctrl/Meta+Enter in onKeyDown and emits onComposerSubmit; plain Enter falls through to the default multiline newline insertion.
  • T3ComposerEditor.native.tsx — declare and forward onComposerSubmit to the composer's onSubmit, exactly as the iOS variant already does.

Ctrl+Enter is the Android convention (matching iOS's Cmd+Enter); Meta is accepted too for external keyboards that map a Command/Meta key.

Surfaces

  • Android: fixed here.
  • iOS: already worked; unchanged.
  • Web: mobile-web has the same gap (plain Enter never submits on a mobile viewport, no modifier fallback) — that lives in a completely separate code path (composer-logic.ts) and is out of scope for this PR to keep it to one concern.

Testing

  • vp run typecheck (mobile) — pass.
  • vp run lint:mobile (ktlint 1.8.0 + detekt against detekt.yml --build-upon-default-config) — pass.
  • Native Android build is not part of PR CI, so the Kotlin was verified against ktlint/detekt locally.

I don't have a device set up to capture a hardware-keyboard video; happy to add one if a maintainer can point me at the mobile e2e harness.

Done by Claude Opus 4.8 via Claude Code.


Note

Low Risk
Localized Android composer keyboard handling with no auth, data, or shared business-logic changes; behavior aligns with existing iOS submit path.

Overview
Android composer now matches iOS for keyboard send: hardware Ctrl/Meta+Enter triggers submit; plain Enter still inserts a newline in the multiline editor.

The Expo module declares onComposerSubmit, the native EditText handles the shortcut in onKeyDown, and T3ComposerEditor.native.tsx forwards it to the composer's onSubmit prop (same wiring as the iOS bridge).

Reviewed by Cursor Bugbot for commit 094a8d2. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Send submit event on Ctrl/Cmd+Enter from hardware keyboard on Android composer

  • Adds a submitListener callback to SelectionAwareEditText that fires on Ctrl+Enter or Meta+Enter, consuming the key event so plain Enter still inserts a newline.
  • Wires the callback through T3ComposerEditorView to dispatch an onComposerSubmit event, exported by T3ComposerEditorModule.
  • Forwards a new onSubmit prop from the ComposerEditor React component to the native view as onComposerSubmit.
  • Risk: onKeyDown override in SelectionAwareEditText consumes Ctrl/Meta+Enter before default handling; verify no other key handlers depend on receiving that event.

Macroscope summarized 094a8d2.

On Android the composer had no way to send from a hardware keyboard:
plain Enter inserts a newline (correct for touch) and no modifier
shortcut was wired, so Bluetooth-keyboard users on tablets and phones
were stuck. iOS already sends on Cmd+Enter through an onComposerSubmit
event, but the Android native module, view, and JS bridge never
implemented it.

Wire the same onComposerSubmit path on Android: the native EditText now
detects Ctrl/Meta+Enter and emits onComposerSubmit, and the Android JS
bridge (T3ComposerEditor.native.tsx) forwards it to the composer's
onSubmit, mirroring the iOS variant. Plain Enter still inserts a newline.

Done by Claude Opus 4.8 via Claude Code.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0e0ac312-6462-4fac-bc04-647138079a7d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 27, 2026
@macroscopeapp

macroscopeapp Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 094a8d2

Macroscope's review found this PR approvable — This is a small Android-only parity fix that connects Ctrl/Meta+Enter to the existing send handler while preserving plain Enter newline behavior. It is isolated to native keyboard handling and event wiring, with no schema, security, billing, deployment, or shared-infrastructure impact.

You can add or adjust custom eligibility rules. Learn more.

Sowyu pushed a commit to Sowyu/t3pretzel that referenced this pull request Sep 15, 2026
Fixes reproduced on an Android emulator and from upstream reports.

Feed: Android stops drawing a text view past the GPU's maximum texture
height, so a long list rendered as one selectable Text lost its tail and
took seconds per frame to draw. Long lists now split into 40-item chunks.
Wide assistant markdown blocks keep a pinned width; the feed reserves
bottom padding.

Keyboard: the feed re-pins after keyboard transitions settle and when the
composer collapses; the back gesture collapses the composer; sticky
composers only follow the keyboard after a fresh show or real focus
(upstream pingdotgg#8212).

Terminal: hardware Enter no longer moves focus off the terminal; keyboards
that use deleteSurroundingText (FUTO) send Backspace; forward delete works.

Also: stream haptics no longer buzz every 320ms on Android and all haptics
use the system engine; thread settings apply on tap without Save; typed
pairing codes are normalized to the server format; non-git projects fall
back to the current checkout instead of a dead worktree default; user CA
certificates are trusted; Ctrl/Cmd+Enter sends from a hardware keyboard;
thread rename, project favicons in the filter, tablet sidebar toggle,
desktop-window density, route titles, Material You review colors, bottom
gesture-bar insets, and the composer placeholder clipping (upstream PRs
pingdotgg#11503, pingdotgg#11370, pingdotgg#11339, pingdotgg#8200, pingdotgg#8717, pingdotgg#11445, pingdotgg#6003, pingdotgg#5052, pingdotgg#8362, pingdotgg#10709,
pingdotgg#11611, pingdotgg#8800, adapted).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant