workflow-kotlin
workflow-kotlin copied to clipboard
TextController.asMutableState is fragile
trafficstars
In the text input compose sample, typing two values, making a selection and banging on the swap button crashes. It's like a soap bubble.
java.lang.IllegalArgumentException: offset(12) is out of bounds [0, 11]
at androidx.compose.ui.text.MultiParagraph.requireIndexInRangeInclusiveEnd(MultiParagraph.kt:589)
at androidx.compose.ui.text.MultiParagraph.getBidiRunDirection(MultiParagraph.kt:406)
at androidx.compose.ui.text.TextLayoutResult.getBidiRunDirection(TextLayoutResult.kt:353)
at androidx.compose.foundation.text.CoreTextFieldKt.SelectionToolbarAndHandles(CoreTextField.kt:710)
at androidx.compose.foundation.text.CoreTextFieldKt.access$SelectionToolbarAndHandles(CoreTextField.kt:1)
at androidx.compose.foundation.text.CoreTextFieldKt$CoreTextField$4$1$1.invoke(CoreTextField.kt:530)
at androidx.compose.foundation.text.CoreTextFieldKt$CoreTextField$4$1$1.invoke(CoreTextField.kt:492)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.foundation.text.selection.SimpleLayoutKt.SimpleLayout(SimpleLayout.kt:77)
at androidx.compose.foundation.text.CoreTextFieldKt$CoreTextField$4$1.invoke(CoreTextField.kt:492)
at androidx.compose.foundation.text.CoreTextFieldKt$CoreTextField$4$1.invoke(CoreTextField.kt:476)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:140)
at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2156)
at androidx.compose.runtime.ComposerImpl.skipToGroupEnd(Composer.kt:2422)
at androidx.compose.material.OutlinedTextFieldKt.IconsWithTextFieldLayout-T2E5_Oc(OutlinedTextField.kt:538)
at androidx.compose.material.OutlinedTextFieldKt.access$IconsWithTextFieldLayout-T2E5_Oc(OutlinedTextField.kt:1)
at androidx.compose.material.OutlinedTextFieldKt$OutlinedTextFieldLayout$1.invoke(OutlinedTextField.kt:341)
at androidx.compose.material.OutlinedTextFieldKt$OutlinedTextFieldLayout$1.invoke(OutlinedTextField.kt:339)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.foundation.text.CoreTextFieldKt.CoreTextField(CoreTextField.kt:476)
at androidx.compose.foundation.text.BasicTextFieldKt.BasicTextField(BasicTextField.kt:257)
at androidx.compose.material.OutlinedTextFieldKt.OutlinedTextFieldLayout-Sac-xI0(OutlinedTextField.kt:314)
at androidx.compose.material.TextFieldImplKt$TextFieldImpl$1.invoke-rAjV9yQ(TextFieldImpl.kt:173)
at androidx.compose.material.TextFieldImplKt$TextFieldImpl$1.invoke(TextFieldImpl.kt:99)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:149)
at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$3.invoke(ComposableLambda.jvm.kt:164)
at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$3.invoke(ComposableLambda.jvm.kt:164)
at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:140)
at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2156)
at androidx.compose.runtime.ComposerImpl.skipToGroupEnd(Composer.kt:2422)
at androidx.compose.material.TextFieldTransitionScope.Transition(TextFieldImpl.kt:304)
at androidx.compose.material.TextFieldImplKt.TextFieldImpl(TextFieldImpl.kt:97)
at androidx.compose.material.OutlinedTextFieldKt.OutlinedTextField(OutlinedTextField.kt:263)
at androidx.compose.material.OutlinedTextFieldKt.OutlinedTextField(OutlinedTextField.kt:150)
at com.squareup.sample.compose.textinput.ComposableSingletons$TextInputViewFactoryKt$lambda-4$1.invoke(TextInputViewFactory.kt:38)
at com.squareup.sample.compose.textinput.ComposableSingletons$TextInputViewFactoryKt$lambda-4$1.invoke(TextInputViewFactory.kt:27)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:135)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at com.squareup.workflow1.ui.compose.ComposeViewFactoryKt$composeViewFactory$1.Content(ComposeViewFactory.kt:60)
at com.squareup.workflow1.ui.compose.WorkflowRenderingKt$WorkflowRendering$1.invoke(WorkflowRendering.kt:103)
at com.squareup.workflow1.ui.compose.WorkflowRenderingKt$WorkflowRendering$1.invoke(WorkflowRendering.kt:98)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:215)
at com.squareup.workflow1.ui.compose.WorkflowRenderingKt.WorkflowRendering(WorkflowRendering.kt:98)
at com.squareup.sample.compose.textinput.AppKt$TextInputApp$1.invoke(App.kt:22)
at com.squareup.sample.compose.textinput.AppKt$TextInputApp$1.invoke(App.kt:20)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:140)
at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2156)
at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:2399)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2580)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2573)
at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(SnapshotState.kt:540)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:2566)
at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:2542)
at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:613)
at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:764)
at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:103)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:447)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:416)
at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:909)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:655)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
It's a Compose bug: https://issuetracker.google.com/205172181
Probably can work around it by converting to MutableState<TextFieldValue>.
https://workflow-community.slack.com/archives/CHTFPR277/p1635983969014900