Skip to content

fix(android): route Modal hardware ESC through onBackPressedDispatcher so onRequestClose fires#56631

Open
mohanrajvenkatesan2304-hash wants to merge 1 commit intofacebook:mainfrom
mohanrajvenkatesan2304-hash:fix/issue-56411-modal-escape-key
Open

fix(android): route Modal hardware ESC through onBackPressedDispatcher so onRequestClose fires#56631
mohanrajvenkatesan2304-hash wants to merge 1 commit intofacebook:mainfrom
mohanrajvenkatesan2304-hash:fix/issue-56411-modal-escape-key

Conversation

@mohanrajvenkatesan2304-hash
Copy link
Copy Markdown

@mohanrajvenkatesan2304-hash mohanrajvenkatesan2304-hash commented Apr 28, 2026

Summary:

On Android, pressing the hardware ESC key (external/Bluetooth keyboard) on an open Modal did not invoke the JS onRequestClose callback, even though hardware BACK did. The dialog was being dismissed by a platform path before the JS callback ran, leaving the React tree's visible state stuck.

This change:

  • Adds a small ReactModalDialog subclass of androidx.activity.ComponentDialog and overrides dispatchKeyEvent. KEYCODE_ESCAPE ACTION_UP is forwarded to the dialog's own onBackPressedDispatcher.onBackPressed(), the same path BACK uses, so both keys now flow through the registered OnBackPressedCallback and trigger onRequestClose.
  • Removes the previous KEYCODE_ESCAPE branch from the modal's setOnKeyListener to avoid double-dispatch.

Fixes #56411.

Changelog:

[ANDROID] [FIXED] - Modal onRequestClose now fires when the user presses hardware ESC on Android (matching hardware BACK behavior)

Test Plan:

  • Added ReactModalDialogTest.kt (Robolectric) asserting KEYCODE_ESCAPE ACTION_UP routes through onBackPressedDispatcher and that other key events delegate to super.dispatchKeyEvent.
  • Could not execute Gradle tests locally (no JDK on the dev sandbox); CI is the source of truth for yarn test-android. The diff was reviewed for compile correctness against the existing ComponentDialog usage on the same file (onBackPressedDispatcher is already used, Theme_FullScreenDialog is defined in themes.xml).
  • Manual verification path for a reviewer with an Android emulator/device:
    adb shell input keyevent 111   # KEYCODE_ESCAPE
    
    with a Modal open should now produce the same onRequestClose callback that BACK already produces. Pairing a Bluetooth keyboard and pressing ESC should behave identically.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Apr 28, 2026
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Apr 28, 2026
…r so onRequestClose fires (facebook#56411)

Hardware ESC was not invoking JS onRequestClose on Android Modals. Subclass
ComponentDialog and override dispatchKeyEvent so KEYCODE_ESCAPE ACTION_UP
routes through onBackPressedDispatcher.onBackPressed(), the same path
KEYCODE_BACK already uses. Removed the redundant ESC branch from
setOnKeyListener to prevent double-dispatch.
@mohanrajvenkatesan2304-hash mohanrajvenkatesan2304-hash force-pushed the fix/issue-56411-modal-escape-key branch from 77d2138 to cafb750 Compare April 28, 2026 11:19
@mohanrajvenkatesan2304-hash mohanrajvenkatesan2304-hash changed the title Fix Modal not invoking onRequestClose on hardware ESC key on Android fix(android): route Modal hardware ESC through onBackPressedDispatcher so onRequestClose fires Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android, Accessibility] Modals break when pressing ESC on physical keyboard

1 participant