fix(android): account for edge-to-edge inset in keyboard avoidance - #190
Open
Qiiks wants to merge 1 commit into
Open
fix(android): account for edge-to-edge inset in keyboard avoidance#190Qiiks wants to merge 1 commit into
Qiiks wants to merge 1 commit into
Conversation
…#156) The composer (text field, attachment buttons, mic) is completely hidden behind the keyboard on Android. Reproduced on an Android 12 emulator on current main, i.e. with 6c103ac's behavior="padding" already applied. The cause is a coordinate-space mismatch rather than the behavior prop. KeyboardAvoidingView computes padding = frame.y + frame.height - (keyboardFrame.screenY - offset) `frame` comes from its own onLayout, in **window** coordinates (origin below the status bar). `keyboardFrame.screenY` is in **screen** coordinates (true top of the display). Before Expo's mandatory edge-to-edge those origins coincided and the OS also resized the window, so the difference was invisible. Under edge-to-edge the window spans the whole display, the two spaces disagree by exactly the status-bar inset, and the computed padding lands short by that amount. Measured on an Android 12 emulator (scale 3.5), keyboard open on the session screen: screen height 845.71 dp window height 748.86 dp insets.top 48.86 dp insets.bottom 48 dp keyboard screenY 511.71 dp height 286 dp computed padding = 748.86 - 511.71 = 237.14 dp required padding = 286.00 dp shortfall = 48.86 dp === insets.top 48.86dp x 3.5 = 171px, which is exactly the composer row. This also explains why the problem keeps returning under new issue numbers: dzianisv#53/dzianisv#70, dzianisv#147/dzianisv#148 and the closed dzianisv#74 each only changed the `behavior` value, so none of them addressed the mismatch. Add keyboardVerticalOffset(platform, insetTop): iOS keeps its existing empirical 90 (it has no such mismatch), Android returns insets.top, clamped at 0 so a bogus inset can never push content downward. Pure and unit-tested, including a guard asserting the corrected arithmetic lands exactly on the real keyboard height. Verified on device: composer, attachment and mic controls all visible and usable above the keyboard, in portrait and at 1.5x font scale. Landscape is not applicable since app.json locks portrait orientation.
This was referenced Aug 17, 2026
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.
Closes #156
Context
This is a focused extraction of the keyboard portion of blocked PR #182. It preserves the original fix and author credit from commit 38544db, while leaving the unrelated SSE, auto-scroll, text-selection, and reconnect changes out of this PR.
Root cause
Under Expo edge-to-edge Android, KeyboardAvoidingView measures its layout frame in window coordinates while the keyboard reports screen coordinates. The origins differ by the top status-bar inset, so the computed padding is short by exactly that inset and the composer remains behind the keyboard.
Change
keyboardVerticalOffset(platform, insetTop)helper.Verification
ERR_MODULE_NOT_FOUNDbecause upstream main has no keyboard-offset implementation; the branch then passes all 5 focused tests.app/session/[id].tsx,src/lib/keyboard-offset.ts, andsrc/lib/keyboard-offset.test.ts.Device verification
The reporter is using Android 17, but this Windows host currently has no Android SDK, emulator, ADB binary, or connected device. Therefore no Android 17 rendering claim is made here. The original commit documents on-device verification on a Pixel 3 XL / Android 12; please validate this focused PR on Android 17 hardware before merging.
Related work