@@ -27,8 +27,6 @@ import androidx.compose.foundation.text.selection.hasSelection
2727import androidx.compose.foundation.text.selection.isMouseOrTouchPad
2828import androidx.compose.ui.Modifier
2929import androidx.compose.ui.geometry.Offset
30- import androidx.compose.ui.geometry.Rect
31- import androidx.compose.ui.geometry.Size
3230import androidx.compose.ui.hapticfeedback.HapticFeedback
3331import androidx.compose.ui.hapticfeedback.HapticFeedbackType
3432import androidx.compose.ui.input.pointer.AwaitPointerEventScope
@@ -46,12 +44,9 @@ import androidx.compose.ui.node.ModifierNodeElement
4644import androidx.compose.ui.node.currentValueOf
4745import androidx.compose.ui.platform.InspectorInfo
4846import androidx.compose.ui.platform.LocalHapticFeedback
49- import androidx.compose.ui.relocation.bringIntoView
5047import androidx.compose.ui.util.fastAll
5148import androidx.compose.ui.util.fastForEach
5249import kotlin.coroutines.cancellation.CancellationException
53- import kotlinx.coroutines.CoroutineStart
54- import kotlinx.coroutines.launch
5550
5651private interface CupertinoTextDragObserver {
5752 fun onStart (startPoint : Offset , selectionAdjustment : SelectionAdjustment )
@@ -67,28 +62,28 @@ internal actual fun SelectionRegistrar.makeSelectionModifier(
6762 return CupertinoSelectionModifierElement (
6863 selectionRegistrar = this ,
6964 selectableId = selectableId,
70- layoutCoordinates = layoutCoordinatesProvider,
65+ layoutCoordinatesProvider = layoutCoordinatesProvider,
7166 )
7267}
7368
7469internal class CupertinoSelectionModifierElement (
7570 private val selectionRegistrar : SelectionRegistrar ,
7671 private val selectableId : Long ,
77- private val layoutCoordinates : () -> LayoutCoordinates ? ,
72+ private val layoutCoordinatesProvider : () -> LayoutCoordinates ? ,
7873) : ModifierNodeElement<CupertinoSelectionModifierNode>() {
7974
8075 override fun create () =
8176 CupertinoSelectionModifierNode (
8277 selectionRegistrar = selectionRegistrar,
8378 selectableId = selectableId,
84- layoutCoordinates = layoutCoordinates ,
79+ layoutCoordinatesProvider = layoutCoordinatesProvider ,
8580 )
8681
8782 override fun update (node : CupertinoSelectionModifierNode ) {
8883 node.update(
8984 selectionRegistrar = selectionRegistrar,
9085 selectableId = selectableId,
91- layoutCoordinates = layoutCoordinates ,
86+ layoutCoordinates = layoutCoordinatesProvider ,
9287 )
9388 }
9489
@@ -103,21 +98,21 @@ internal class CupertinoSelectionModifierElement(
10398
10499 return selectionRegistrar == other.selectionRegistrar &&
105100 selectableId == other.selectableId &&
106- layoutCoordinates == = other.layoutCoordinates
101+ layoutCoordinatesProvider == = other.layoutCoordinatesProvider
107102 }
108103
109104 override fun hashCode (): Int {
110105 var result = selectableId.hashCode()
111106 result = 31 * result + selectionRegistrar.hashCode()
112- result = 31 * result + layoutCoordinates .hashCode()
107+ result = 31 * result + layoutCoordinatesProvider .hashCode()
113108 return result
114109 }
115110}
116111
117112internal class CupertinoSelectionModifierNode (
118113 private var selectionRegistrar : SelectionRegistrar ,
119114 private var selectableId : Long ,
120- private var layoutCoordinates : () -> LayoutCoordinates ? ,
115+ private var layoutCoordinatesProvider : () -> LayoutCoordinates ? ,
121116) : DelegatingNode(), CompositionLocalConsumerModifierNode {
122117
123118 private val pointerInputNode = delegate(
@@ -155,7 +150,7 @@ internal class CupertinoSelectionModifierNode(
155150 var dragTotalDistance = Offset .Zero
156151
157152 override fun onStart (startPoint : Offset , selectionAdjustment : SelectionAdjustment ) {
158- layoutCoordinates ()?.let {
153+ layoutCoordinatesProvider ()?.let {
159154 if (! it.isAttached) return
160155
161156 selectionRegistrar.notifySelectionUpdateStart(
@@ -174,7 +169,7 @@ internal class CupertinoSelectionModifierNode(
174169 }
175170
176171 override fun onDrag (delta : Offset , selectionAdjustment : SelectionAdjustment ) {
177- layoutCoordinates ()?.let {
172+ layoutCoordinatesProvider ()?.let {
178173 if (! it.isAttached) return
179174 // selection never started, did not consume any drag
180175 if (! selectionRegistrar.hasSelection(selectableId)) return
@@ -215,32 +210,33 @@ internal class CupertinoSelectionModifierNode(
215210 }
216211 }
217212
218- private fun createMouseSelectionObserver () = selectionRegistrar.skikoMouseSelectionObserver(
219- selectableId = selectableId,
220- layoutCoordinates = layoutCoordinates,
221- bringIntoView = ::bringIntoView
213+ private fun createMouseSelectionObserver () = selectionRegistrar.DefaultMouseSelectionObserver (
214+ selectableIdProvider = { selectableId },
215+ layoutCoordinatesProvider =
216+ // `layoutCoordinatesProvider` is a var, hence the lambda, to refer to the latest
217+ @Suppress(" UnnecessaryLambdaCreation" ) { layoutCoordinatesProvider() },
222218 )
223219
224220 private var mouseSelectionObserver = createMouseSelectionObserver()
225221
226- private fun bringIntoView (offset : Offset ) {
227- coroutineScope.launch(start = CoroutineStart .UNDISPATCHED ) {
228- bringIntoView {
229- Rect (offset = offset, size = Size .Zero )
230- }
231- }
232- }
233-
234222 fun update (
235223 selectionRegistrar : SelectionRegistrar ,
236224 selectableId : Long ,
237225 layoutCoordinates : () -> LayoutCoordinates ? ,
238226 ) {
227+ val selectionRegistrarChanged = selectionRegistrar != this .selectionRegistrar
228+
239229 this .selectionRegistrar = selectionRegistrar
240230 this .selectableId = selectableId
241- this .layoutCoordinates = layoutCoordinates
231+ this .layoutCoordinatesProvider = layoutCoordinates
232+
233+ // When the SelectionRegistrar itself changes (which should be very rare), recreate the
234+ // input observers altogether (the alternative would be to pass them the registrar via a
235+ // lambda).
236+ if (selectionRegistrarChanged) {
237+ mouseSelectionObserver = createMouseSelectionObserver()
238+ }
242239
243- mouseSelectionObserver = createMouseSelectionObserver()
244240 pointerInputNode.resetPointerInputHandler()
245241 }
246242}
0 commit comments