JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
14.85k stars 1.08k forks source link

DrawModifierNode is not synced with LazyColumn scroll position #4740

Closed artsmvch closed 2 days ago

artsmvch commented 2 weeks ago

Describe the bug Drawing done in drawBehind/drawWithCache/drawWithContent is not synced with the LazyColumn scroll position. Please see the video attached: when scrolling, the position of the drawn icons (circles) is unstable relative to the items in the LazyColumn. The icons are drawn using the drawBehind modifier.

Affected platforms

Versions

To Reproduce Here is a code snippet to reproduce. Steps and/or the code snippet to reproduce the behavior:

  1. Scroll the list
  2. See the bug: the icon drawing is not synced with the LazyColumn scroll position.

Expected behavior Drawing done in drawBehind/drawWithCache/drawWithContent is synced with the LazyColumn scroll position.

Video

https://github.com/JetBrains/compose-multiplatform/assets/61359788/6975dc56-026c-45de-8201-9b5c87455f7c

Additional context Works fine on Android.

igordmn commented 2 weeks ago

when scrolling, the position of the drawn icons (circles) is unstable relative to the items in the LazyColumn.

Looks like it's only on the top/bottom elements during overscrolling?

https://github.com/JetBrains/compose-multiplatform/assets/5963351/0ddd4afe-8cad-4136-996c-ea7dd5dbc657

@elijah-semyonov, listState.layoutInfo.visibleItemsInfo doesn't take into account the overscroll effect.

artsmvch commented 2 weeks ago

@igordmn No, the problem with the overscroll effect is a separate issue that also doesn't work on Android (there is a feature request that might help fix this).

This issue is about drawings done in DrawModifierNode not being synced with the scroll position of LazyColumn when scrolled in any position (with the overscroll effect disabled).

I also noticed that this actually works fine on the simulator - so there is no such problem in your video. I can only reproduce the bug on a real device (iPhone 12 iOS 17.4.1).

igordmn commented 1 week ago

I can only reproduce the bug on a real device

Could you post a video with scrolling in the middle? In the video you posted it is difficult to distinguish the desync because of overscoll and the desync because of other reasons

artsmvch commented 1 week ago

Sure, I updated the code to make the problem more visible.

And here is the video:

https://github.com/JetBrains/compose-multiplatform/assets/61359788/b292b5c4-89aa-49a4-b6b5-0c60a04c5e63

Set the speed to 0.5 to see that the drawn elements (yellow boxes) are not aligned to the list items when scrolling.

elijah-semyonov commented 1 week ago

@elijah-semyonov, listState.layoutInfo.visibleItemsInfo doesn't take into account the overscroll effect.

@igordmn That makes sense. Overscroll effect on iOS is based on applying Modifier.offset to the scroll content and tracks its own state, it doesn't know anything about the implementation of the particular scroll it's integrated with (whether it's a TextField scroll, .scrollable or LazyList.

Native iOS works with negative (or above the max value) scrolls. Such values are breaking common logic invariants, so supporting it in the same way as native iOS does it would be extremely intrusive.

The lag looks interesting though, did we include main-loop sequence fix in beta03?

igordmn commented 1 week ago

The lag looks interesting though, did we include https://github.com/JetBrains/compose-multiplatform-core/pull/1260 in beta03?

Yes, it is included

m-sasha commented 3 days ago

Possibly fixed by https://github.com/JetBrains/compose-multiplatform-core/pull/1356; worth trying.

elijah-semyonov commented 2 days ago

@m-sasha it's indeed fixed by that fix.

https://github.com/JetBrains/compose-multiplatform/assets/4167681/af9be465-8f11-4ea1-8aa8-3ab83994a669

m-sasha commented 2 days ago

Could you check the one with the yellow squares too? It's much more visible there.

elijah-semyonov commented 1 day ago

Sure! It's not present there either:

https://github.com/JetBrains/compose-multiplatform/assets/4167681/3c522443-be25-473f-be39-32ecbda73d1f

artsmvch commented 1 day ago

Nice, what version will the fix come in?

m-sasha commented 1 day ago

It will definitely be in 1.7, possibly earlier in 1.6.11. You can also see it in our dev builds, which we release every few days.