Repository navigation
fix(mobile): hardware Enter keeps the Android terminal focused - #24928
maria-rcks merged 2 commits into
Conversation
…istener No behavior change. The listener can now run in a JVM test without the Expo view or the native terminal library. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A single-line EditText moves focus to the next view when its editor action listener leaves the Enter key-up unconsumed. The terminal sent CR on key-down and returned false on key-up, so every physical Enter moved focus off the terminal and the next key went nowhere. Consume both halves of Enter and numpad Enter, sending CR once on key-down. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a localized Android terminal bug fix that preserves existing input behavior while consuming hardware Enter key-up events to prevent focus loss, with a focused Robolectric regression test. Build-file changes are test-only and do not alter product defaults or static-analysis policy. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Enter event handling apps/mobile/modules/t3-terminal/android/src/main/java/expo/modules/t3terminal/T3TerminalView.kt, apps/mobile/modules/t3-terminal/android/src/main/java/expo/modules/t3terminal/TerminalEnterListener.kt |
The terminal view delegates editor actions to TerminalEnterListener. The listener sends a carriage return for IME Send and hardware Enter key-down events when the terminal is not read-only. It consumes hardware Enter key-up events and all actions when the terminal is read-only. |
Robolectric focus test apps/mobile/modules/t3-terminal/android/build.gradle, apps/mobile/modules/t3-terminal/android/src/test/java/expo/modules/t3terminal/TerminalEnterListenerTest.kt |
The module enables Android resources for unit tests, adds JUnit and Robolectric, and configures test tasks to use Java 21. The test dispatches Enter and numpad Enter events and checks that focus remains on the input and the callback runs twice. |
Priority:
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Bug fix · Severity of issue fixed: Low
Merge Risk: 
Minimal · up to 41adb
-
The change appears mergeable after normal checks. Physical-keyboard behavior on a device and the app Gradle test task remain unverified.
Pre-merge checks: 
4
-
Full details: Description check
-
Explanation
The description includes Problem, Change, Scope and approval, and Verification sections. It explains the bug, implementation, linked issue, test results, emulator evidence, screenshots, and untested scenarios.
Full details: Linked Issues check
-
Explanation
Issue
#8140requires repeated Android terminal Enter input without losing focus.TerminalEnterListenerhandlesKEYCODE_ENTERandKEYCODE_NUMPAD_ENTER, sends CR once on key-down, and consumes key-up.T3TerminalViewuses the listener.TerminalEnterListenerTestdispatches both key phases for both key codes and verifies focus remains on the input and CR is sent twice. The added Robolectric setup supports this automated regression test.
Full details: Out of Scope Changes check
-
Explanation
The changes stay within issue
#8140. The listener extraction enables isolated testing. The Robolectric dependencies and test configuration support the regression test. Numpad Enter handling addresses the same focus-loss path. No unrelated product behavior or unrelated files are changed.
-
Finishing Touches
-
🧪 Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.
|
Note Written by Verified in a real dev environmentNo changed behavior could be verified in the running app on this VM. This is an unverifiable result, not a successful verification. Read the description, discussion, inline comments and complete four-file diff at The change is Android-native: consume both hardware Enter/numpad Enter phases, send CR on key-down, and keep the single-line terminal input focused. The required user path is an Android native terminal connected to a real server, followed by consecutive shell commands without tapping to refocus. Device preflight returned: The repository mobile verification skill explicitly says: "If T3 device tools or the selected device are unavailable, report the blocker and stop verification. Do not install or switch to another automation system." No dev server was started, no checkout or source was changed, and no runtime screenshots or recordings were captured. Existing author evidence was not treated as independently reproduced evidence. Not verified
To complete verification, enable Android device access and run main then this head against one isolated dev server at a time. Type two distinguishable shell commands with hardware Enter, then a bare Enter, without tapping to refocus; check that each submits exactly once and focus stays in the terminal. Repeat with numpad Enter, then check soft-keyboard Send and read-only input. Capture the main/PR interaction and inspect it before uploading. |
|
Note Written by Verified on Android emulator (API 35) against a real dev serverNo changed app behavior was verified. This attempt is unverifiable, not a passing Android verification. Read the complete diff, description, discussion, reviews and commit authors at Booted the Checked out the exact head and completed This head predates the No candidate native client was installed, so no terminal screenshots or recordings can honestly demonstrate this change. Existing author media and CI were not substituted for independent runtime proof. GitCafe reports 27 successful checks, zero failing and zero pending. No source fix or push was made. Not verified
Verification needs a functioning filesystem and an APK built from this exact native fingerprint, then the requested app interactions and independently captured evidence. |
Problem
On Android with a physical keyboard, Enter in the native terminal sends the command, then moves focus off the terminal. The next keys go nowhere until you tap the terminal again. Fixes #8140, reported on a Pixel 10a with a physical keyboard.
The terminal's hidden input is a single-line
EditText. On a hardware Enter, Android calls the editor action listener on key-down and again on key-up. Our listener sent CR on key-down and returnedfalseon key-up. A single-lineTextViewtreats an unconsumed Enter key-up as "advance focus", so it moved focus to the next focusable view on every Enter. Numpad Enter was never handled at all: no CR, and focus moved the same way.Change
trueand does nothing else, soTextViewno longer advances focus.T3TerminalViewinto a smallTerminalEnterListenerclass. That is its own commit with no behavior change, so the fix commit shows only the key-up change.The soft keyboard's Send action is unchanged: it still arrives as
IME_ACTION_SENDwithout a key event and sends CR once. Read-only terminals still swallow Enter.Scope and approval
Bug fix for #8140. The maintainer's triage note found no duplicate or existing fix and requested Android verification with a physical keyboard. This PR adds before/after Android emulator evidence using injected keyboard-source Enter events; a physical keyboard remains untested. One choice for maintainers to confirm: numpad Enter now sends CR like the main Enter key. Before this change it sent nothing and also moved focus away. This awaits maintainer review.
Verification
TerminalEnterListener.ktandTerminalEnterListenerTest.ktand rangradle --no-daemon test --rerun-taskswith Robolectric SDK 36. The test puts the listener on a focused single-lineEditTextwith a focusable control below it, then dispatches key-down and key-up for Enter and numpad Enter. It asserts focus stays on the input after each key and that CR went out once per key, twice in total.focus left the input after key 66.apps/mobile/detekt.ymlon the three changed Kotlin files: clean.adb shell input textandinput keyevent 66, which inject keyboard-source key events, the same path a physical keyboard takes. Each run typedecho first, Enter,echo second, Enter, then a bare Enter, and read the focused view from the accessibility tree after each Enter.echo secondand both later Enters never reach the shell.Not checked:
:t3-terminal:testDebugUnitTesttask in the app's Gradle build. The regression test ran through the standalone JVM harness described above.Prior PRs
Evidence
Same three hardware Enters on an Android 16 emulator: main sends the first command, then the terminal turns grey and the rest go nowhere; this branch runs both commands and the extra Enter.
Main: after the first Enter the terminal turns grey, the keyboard's action key changes from Send to Return, and "echo second" never reaches the shell.
Full recording (mp4)
This branch: "echo first", "echo second" and a bare Enter all reach the shell, and the terminal input keeps focus throughout.
Full recording (mp4)
Focused Robolectric test with main's Enter logic: focus left the input after key 66 (Enter).
The same test on this branch passes.
Production fix, tests, PR description and images by Claude Opus 5.5 in T3 Code Nightly.
🤖 Generated with Claude Opus 5.5 in T3 Code Nightly