From 7da4289622fae8b3643eb9152992f1f44e21c47e Mon Sep 17 00:00:00 2001 From: Yevhenii Date: Fri, 16 Oct 2026 12:09:25 +0300 Subject: [PATCH] Android: a TextInput with its context menu hidden opens no right-click menu A mouse right-click on an Android TextInput opens the context menu that Editor fills with Cut, Copy, Paste, Select all and the other text actions. ReactEditText honours contextMenuHidden only in its action mode callback, so a right-click still opened that menu with the flag set. ReactEditText adds no items to its context menu while contextMenuHidden is set, and the platform opens no menu without items: not on a right-click, and not from anything else that asks the view for its context menu. --- .../ReactAndroid/api/ReactAndroid.api | 1 + .../react/views/textinput/ReactEditText.kt | 11 ++++++++++ .../textinput/ReactTextInputPropertyTest.kt | 20 +++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 6c76d3a2197f..7fffbc6bdce2 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6251,6 +6251,7 @@ public class com/facebook/react/views/textinput/ReactEditText : androidx/appcomp public final fun maybeUpdateTypeface ()V public fun onAttachedToWindow ()V public fun onConfigurationChanged (Landroid/content/res/Configuration;)V + protected fun onCreateContextMenu (Landroid/view/ContextMenu;)V public fun onCreateInputConnection (Landroid/view/inputmethod/EditorInfo;)Landroid/view/inputmethod/InputConnection; public fun onDragEvent (Landroid/view/DragEvent;)Z public fun onDraw (Landroid/graphics/Canvas;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt index 754f10026624..aa09eea8811a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt @@ -29,6 +29,7 @@ import android.text.method.KeyListener import android.text.method.QwertyKeyListener import android.util.TypedValue import android.view.ActionMode +import android.view.ContextMenu import android.view.DragEvent import android.view.Gravity import android.view.KeyEvent @@ -388,6 +389,16 @@ public open class ReactEditText public constructor(context: Context) : AppCompat if (id == android.R.id.paste) android.R.id.pasteAsPlainText else id, ) + /* + * A secondary click opens the context menu that Editor fills with the text actions. With + * contextMenuHidden it gets no items, so no menu opens. + */ + override fun onCreateContextMenu(menu: ContextMenu) { + if (!contextMenuHidden) { + super.onCreateContextMenu(menu) + } + } + internal fun clearFocusAndMaybeRefocus() { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P || !isInTouchMode) { super.clearFocus() diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/textinput/ReactTextInputPropertyTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/textinput/ReactTextInputPropertyTest.kt index 82ec014eb89e..71553665f5e4 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/textinput/ReactTextInputPropertyTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/textinput/ReactTextInputPropertyTest.kt @@ -11,8 +11,10 @@ package com.facebook.react.views.textinput +import android.app.Activity import android.graphics.Color import android.os.Build +import android.os.Looper import android.text.InputFilter import android.text.InputFilter.AllCaps import android.text.InputType @@ -46,8 +48,10 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.robolectric.Robolectric import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment +import org.robolectric.Shadows.shadowOf /** Verify {@link EditText} view property being applied properly by {@link ReactTextInputManager} */ @RunWith(RobolectricTestRunner::class) @@ -652,6 +656,22 @@ class ReactTextInputPropertyTest { .isNull() } + @Test + fun testContextMenuHiddenRightClick() { + val activity = Robolectric.buildActivity(Activity::class.java).setup().get() + activity.setContentView(view) + view.setText("text") + shadowOf(Looper.getMainLooper()).idle() + + // A mouse right-click opens the context menu at the pointer through showContextMenu(x, y), + // which answers whether a menu opened. + manager.updateProperties(view, buildStyles()) + assertThat(view.showContextMenu(1f, 1f)).isTrue + + manager.updateProperties(view, buildStyles("contextMenuHidden", true)) + assertThat(view.showContextMenu(1f, 1f)).isFalse + } + private fun buildStyles(vararg keysAndValues: Any?): ReactStylesDiffMap { return ReactStylesDiffMap(JavaOnlyMap.of(*keysAndValues)) }