movableContentOf with subcomposeLayout not working...
# compose
a
movableContentOf with subcomposeLayout not working in 1.3? I know there was an issue that it didn't keep remembered state in 1.2 to move between subcompose and not, but without that type of change it was working in 1.2 -- our usage now is crashing after upgrading to 1.3. Maybe similar to https://issuetracker.google.com/issues/258053979 but the callstack is completely different, and in our case there is just 1 arg (modifier) that we're passing right now...
Copy code
java.lang.ArrayIndexOutOfBoundsException: length=0; index=-677
	at androidx.compose.runtime.SlotTableKt.groupSize(SlotTable.kt:3251)
	at androidx.compose.runtime.SlotTableKt.access$groupSize(SlotTable.kt:1)
	at androidx.compose.runtime.SlotWriter.groupSize(SlotTable.kt:1246)
	at androidx.compose.runtime.SlotWriter$Companion.moveGroup(SlotTable.kt:1952)
	at androidx.compose.runtime.SlotWriter$Companion.access$moveGroup(SlotTable.kt:1944)
	at androidx.compose.runtime.SlotWriter.moveFrom(SlotTable.kt:2192)
	at androidx.compose.runtime.ComposerImpl$recordInsert$1.invoke(Composer.kt:3438)
	at androidx.compose.runtime.ComposerImpl$recordInsert$1.invoke(Composer.kt:3436)
	at androidx.compose.runtime.ComposerImpl$insertMovableContentGuarded$1$1$5$1$2.invoke(Composer.kt:3073)
	at androidx.compose.runtime.ComposerImpl$insertMovableContentGuarded$1$1$5$1$2.invoke(Composer.kt:3069)
	at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:808)
	at androidx.compose.runtime.CompositionImpl.applyLateChanges(Composition.kt:849)
	at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:979)
	at androidx.compose.runtime.ComposerImpl$CompositionContextImpl.composeInitial$runtime_release(Composer.kt:3848)
	at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:519)
	at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcomposeInto(SubcomposeLayout.kt:468)
	at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:441)
	at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:432)
	at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:421)
	at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$Scope.subcompose(SubcomposeLayout.kt:733)
	at com.myapp.TwoPaneLayoutKt$TwoPaneLayoutImpl$1.invoke-0kLqBqw(TwoPaneLayout.kt:248)
	at com.myapp.TwoPaneLayoutKt$TwoPaneLayoutImpl$1.invoke(TwoPaneLayout.kt:234)
	at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$createMeasurePolicy$1.measure-3p2s80s(SubcomposeLayout.kt:591)
	at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:103)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1077)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1073)
	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:124)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:130)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:126)
	at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341)
	at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:126)
	at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120)
	at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release(OwnerSnapshotObserver.kt:107)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1073)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:36)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:341)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.measure-BRTryo0(LayoutNodeLayoutDelegate.kt:320)
s
So yeah, this is probably close to my discussion here, https://kotlinlang.slack.com/archives/CJLTWPH7S/p1667925209738679. The call stack looks different, but I think the underlying issue is still that when moving inside SubCompose, it somehow doesn’t properly read the most up to date and correct data passed into it.
a
We're doing this with our NavGraph so it stays alive when not visible/placed. We are using a control similar to accompanist's adapative.TwoPane control (something we built a year ago that does a few additional things...), in our usage of movablecontentOf we have a navgraph for each of the two panes that we're moving, since they're not both visible all the time on phones, just tablets. I'll see if I can make a demo project hit this using the accompanist version
s
Yeah, my repro project is super minimal, as small as possible. If you can make another one which would test another scenario and attach it to the bugtracker that could help
a
ok took me awhile to figure out what was involved, created as small of a repro as I could and created an issue for it. https://issuetracker.google.com/issues/259767846 Also I saw another SlotTableKt bug reported in our app after moving to 1.3.1 thats totally different area of the app, haven't tried to minify that case yet (not using moveableContentOf, its using animation when filtering a list)