Repository navigation
Report hardware keyboard keys in Android TextInput onKeyPress - #59120
Open
YevheniiKotyrlo wants to merge 1 commit into
Open
YevheniiKotyrlo wants to merge 1 commit into
YevheniiKotyrlo wants to merge 1 commit into
Conversation
YevheniiKotyrlo
marked this pull request as ready for review
October 15, 2026 18:51
YevheniiKotyrlo
marked this pull request as draft
October 15, 2026 20:09
|
Warning JavaScript API change detected This PR commits an update to
This change was flagged as: |
YevheniiKotyrlo
marked this pull request as ready for review
October 15, 2026 23:52
ReactEditText.onKeyDown reports every key event the view receives, from a hardware keyboard or forwarded by an input method through InputConnection.sendKeyEvent, by its KeyboardEvent.key value, with altKey, ctrlKey, metaKey and shiftKey. A Ctrl or Meta shortcut is named by its key, and so is an Alt shortcut where Alt types nothing on the layout. A key that types a character after a dead key is reported as the composed character, and system keys such as Back and volume are not reported. ReactEditTextInputConnectionWrapper reports only the text an input method types, so no key is reported twice. The key table follows the UI Events key values as Firefox for Android pairs them with key codes, so View onKeyDown also names Home, End, the function keys and Ctrl shortcuts instead of reporting them as Unidentified.
YevheniiKotyrlo
force-pushed
the
fix/android-hardware-key-press
branch
from
November 11, 2026 14:14
8276603 to
0725a33
Compare
This branch has not been deployed
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.
Summary:
With a keyboard attached to an Android phone or tablet,
TextInput'sonKeyPressmisses keys, and which ones depends on the keyboard app. With Samsung Keyboard, the default on Samsung devices, nothing typed on the keyboard is reported: not letters, not Enter, not Backspace. With Gboard, letters and Backspace are reported, but arrows, Home, End and every other key are not. A code field that steps back on Backspace, or a suggestion list moved with the arrow keys, works on the web and not on Android. The docs record the limitation ("on Android only the inputs from soft keyboard are handled"), and #19507 met the same gap on the soft numeric keypad, which #29046 closed for digits only.onKeyPressonly reported what an input method types through theInputConnection. A hardware key reachesReactEditTextas a key event instead: directly with Samsung Keyboard, and throughInputConnection.sendKeyEventwith Gboard. This reports every key event fromReactEditText.onKeyDown, where both arrive, by itsKeyboardEvent.keyvalue, withaltKey,ctrlKey,metaKeyandshiftKey, asonKeyPressreports on the web. System keys (Back, volume, media) are not reported, and a character typed after a dead key is reported composed, as on the web. The input connection wrapper keeps reporting typed text, without itssendKeyEventspecial cases.The names come from the table the View
onKeyDownevent (#54308) already used, completed with the UI Events key values as Firefox for Android pairs them with key codes, soonKeyDownalso names Home, End, the function keys and Ctrl shortcuts that it reported asUnidentified.onKeyDownalone does not cover this: it is behindenableKeyEvents, and it never sees a key that Gboard types as text.Changelog:
[ANDROID] [ADDED] -
TextInputonKeyPressreports every hardware keyboard key by itsKeyboardEvent.keyvalue, withaltKey,ctrlKey,metaKeyandshiftKeyTest Plan:
ReactEditTextKeyPressTestfocuses the view in a window and sends keys the two ways a device does: to the window, as a hardware keyboard does, and through the view's input connection, which the framework delivers back to the view. Onmain10 of its 15 cases fail; with the change all pass.KeyDownEventTestfails onmainwithUnidentifiedfor Home, PageDown, Delete and F1. The ReactAndroid unit suite passes with-PenableWarningsAsErrors=true, as do Flow, both TypeScript checks, ESLint, Prettier and ktfmt, andReactNativeApi.d.tsis regenerated.RNTester release builds with the Playground below, typing a, Shift+B, Ctrl+C, ←, →, Home, End, F1, Alt+E, E, volume up, volume down, ←, Backspace and z on a USB keyboard (registered through
uinput), report:main[]a,shift+Shift,shift+B,ctrl+Control,ctrl+c,ArrowLeft,ArrowRight,Home,End,F1,alt+Alt,alt+e,e,ArrowLeft,Backspace,za,B,e,Backspace,za,shift+Shift,B,e,ctrl+Control,ctrl+c,ArrowLeft,ArrowRight,Home,End,F1,alt+Alt,alt+e,ArrowLeft,Backspace,zGboard types letters as text at once and forwards the other keys later, so the two interleave in the order Gboard delivers them. The volume keys are not reported on either device. An accent key (Alt+E in Android's virtual key map, sent with
adb shell input keycombination) reportsalt+Deadand thenéon the S23. The soft keyboard (q, Backspace, Backspace,w) and the soft numeric keypad (1,2, Backspace,3) report the same keys on both builds and both devices.packages/rn-tester/js/examples/Playground/RNTesterPlayground.js