[go: nahoru, domu]

Fix: Selection toolbar may disappear in LazyColumn

Make sure that only the SelecitonContainer that is focused can show/hide/update the selection toolbar.

Bug: 178121997
Test: ./gradlew test
Change-Id: I7a38a016502720ed746f4d5321175ac9edc1a64e
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.kt
index d630533..6448b20 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.kt
@@ -18,7 +18,6 @@
 
 package androidx.compose.foundation.text.selection
 
-import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.focusable
 import androidx.compose.runtime.State
 import androidx.compose.runtime.getValue
@@ -95,9 +94,9 @@
     var focusRequester: FocusRequester = FocusRequester()
 
     /**
-     * MutableInteractionSource for the selection container, containing focus interactions.
+     * Return true if the corresponding SelectionContainer is focused.
      */
-    val interactionSource: MutableInteractionSource = MutableInteractionSource()
+    var hasFocus: Boolean by mutableStateOf(false)
 
     /**
      * Modifier for selection container.
@@ -106,11 +105,12 @@
         .onGloballyPositioned { containerLayoutCoordinates = it }
         .focusRequester(focusRequester)
         .onFocusChanged { focusState ->
-            if (!focusState.isFocused) {
+            if (!focusState.isFocused && hasFocus) {
                 onRelease()
             }
+            hasFocus = focusState.isFocused
         }
-        .focusable(interactionSource = interactionSource)
+        .focusable()
         .onKeyEvent {
             if (isCopyKeyEvent(it)) {
                 copy()
@@ -126,8 +126,10 @@
     var containerLayoutCoordinates: LayoutCoordinates? = null
         set(value) {
             field = value
-            updateHandleOffsets()
-            updateSelectionToolbarPosition()
+            if (hasFocus) {
+                updateHandleOffsets()
+                updateSelectionToolbarPosition()
+            }
         }
 
     /**
@@ -179,8 +181,8 @@
                 isStartHandle = true,
                 longPress = touchMode
             )
-            hideSelectionToolbar()
             focusRequester.requestFocus()
+            hideSelectionToolbar()
         }
 
         selectionRegistrar.>
@@ -334,25 +336,27 @@
      * the copy method as a callback when "copy" is clicked.
      */
     internal fun showSelectionToolbar() {
-        selection?.let {
-            textToolbar?.showMenu(
-                getContentRect(),
-                >
-                    copy()
-                    onRelease()
-                }
-            )
+        if (hasFocus) {
+            selection?.let {
+                textToolbar?.showMenu(
+                    getContentRect(),
+                    >
+                        copy()
+                        onRelease()
+                    }
+                )
+            }
         }
     }
 
     internal fun hideSelectionToolbar() {
-        if (textToolbar?.status == TextToolbarStatus.Shown) {
+        if (hasFocus && textToolbar?.status == TextToolbarStatus.Shown) {
             textToolbar?.hide()
         }
     }
 
     private fun updateSelectionToolbarPosition() {
-        if (textToolbar?.status == TextToolbarStatus.Shown) {
+        if (hasFocus && textToolbar?.status == TextToolbarStatus.Shown) {
             showSelectionToolbar()
         }
     }