Skip to content

fix: keyboard jump on samsung non edge-to-edge devices#3718

Merged
isekovanic merged 4 commits into
developfrom
fix/jumping-keyboard-samsung-devices
Jul 9, 2026
Merged

fix: keyboard jump on samsung non edge-to-edge devices#3718
isekovanic merged 4 commits into
developfrom
fix/jumping-keyboard-samsung-devices

Conversation

@isekovanic

Copy link
Copy Markdown
Contributor

🎯 Goal

This PR fixes a transient issue on Android, opening the keyboard inside a channel could make the composer and the message list briefly shoot up to a random high point and then drop back down onto the keyboard. It's most obvious on Samsung (Android 13) and it's intermittent, since it comes down to timing.

KeyboardCompatibleView calculates a JS offset to lift the composer above the keyboard. But on a non edge-to-edge app the OS is already doing that for us with adjustResize and it shrinks the window when the keyboard shows up. The catch is our layout frame only reflects that resize one render after keyboardDidShow fires, so for a frame or two we compute the offset from the old, full height frame and stack it on top of the native resize. That extra offset is the jump we see.

🛠 Implementation details

I split the behaviour based on whether the OS resizes the window for the keyboard:

  • Non edge-to-edge - the window resizes, so we don't need a JS offset at all. We return 0 and let adjustResize handle it. No double offset, nothing to race against, no jump.
  • Edge-to-edge (the default on Android 15 / API 35+, opt-in below that) - the window is not resized, RN dispatches insets instead, so our JS offset is the only thing keeping the composer above the keyboard and we have to apply it.

The annoying part is you can't tell those two apart from screen - window on its own. Below API 35 the system bars get reported as an inset in both modes, so a plain screen - window > 0 check wrongly triggers under edge-to-edge and ends up hiding the composer behind the keyboard. So on top of the inset check we read RN's isEdgeToEdge, DeviceInfo flag, and we only skip the JS offset when there's a bar inset (room for adjustResize to shrink into) and the app isn't edge-to-edge.

The table below provides a report of where and how this has been tested on:

Device Android / API Mode Result
Samsung Galaxy A51 (SM-A515F) 13 / 33 non edge-to-edge (default) keyboard open/close repeatedly, no jump
Samsung Galaxy A51 (SM-A515F) 13 / 33 edge-to-edge (edgeToEdgeEnabled=true) composer stays above keyboard (this is the case a plain inset check breaks)
Xiaomi 23124RA7EO 15 / 35 edge-to-edge (platform-enforced) unchanged, composer stays above keyboard

Opened and closed the keyboard a bunch of times on each to make sure the jump is gone and nothing regressed.

🎨 UI Changes

iOS
Before After
Android
Before After

🧪 Testing

☑️ Checklist

  • I have signed the Stream CLA (required)
  • PR targets the develop branch
  • Documentation is updated
  • New code is tested in main example apps, including all possible scenarios
    • SampleApp iOS and Android
    • Expo iOS and Android

@isekovanic isekovanic requested review from oliverlaz and szuperaz July 9, 2026 10:59
@Stream-SDK-Bot

Copy link
Copy Markdown
Contributor

SDK Size

title develop branch diff status
js_bundle_size 1976 KB 1977 KB +364 B 🟡

@isekovanic isekovanic merged commit 07e5554 into develop Jul 9, 2026
10 checks passed
@isekovanic isekovanic deleted the fix/jumping-keyboard-samsung-devices branch July 9, 2026 14:09
@github-actions github-actions Bot mentioned this pull request Jul 9, 2026
6 tasks
@stream-ci-bot

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 9.6.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants