Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frozen composition with pager and text field #4681

Closed
alexzhirkevich opened this issue Apr 23, 2024 · 1 comment · Fixed by JetBrains/compose-multiplatform-core#1316
Closed
Assignees
Labels
bug Something isn't working p:critical Critical priority reproduced runtime Compose runtime problem

Comments

@alexzhirkevich
Copy link
Contributor

alexzhirkevich commented Apr 23, 2024

Describe the bug
Weird frozen composition bug with Scaffold, HorizontalPager and text field (basic or material).
Input doesn't work, content inside pager is unresponsive until external recomposition occurred.
Happens only when pagerState.targetPage is read from some drawing context inside topBar or bottomBar

Works fine in 1.6.10-dev1575. Doesn't work starting from 1.6.10-dev1578
Possibly related: JetBrains/compose-multiplatform-core#1260

Affected platforms
Skiko backed

Versions

  • Kotlin version*: 1.9.23
  • Compose Multiplatform version*: 1.6.10-dev1578

To Reproduce

  1. Launch app
  2. Try input something - nothing happens
  3. Resize window to force recomposition
  4. Input becomes responsive
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.Scaffold
import androidx.compose.material3.TextField
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.window.singleWindowApplication

@OptIn(ExperimentalFoundationApi::class)
fun main() {
    singleWindowApplication {
        val pagerState = rememberPagerState { 1 }
        Scaffold(
            modifier = Modifier.fillMaxSize(),
            topBar = {
                Spacer(Modifier.drawBehind {
                    pagerState.targetPage
                })
            }
        ) {
            HorizontalPager(
                modifier = Modifier.fillMaxSize(),
                state = pagerState,
            ) {
                Box(
                    modifier = Modifier.fillMaxSize(),
                    contentAlignment = Alignment.Center
                ) {

                    var value by remember {
                        mutableStateOf("Resize window to force recomposition")
                    }
                    TextField(
                        value = value,
                        onValueChange = { value = it },
                    )
                }
            }
        }
    }
}
@alexzhirkevich alexzhirkevich added bug Something isn't working submitted labels Apr 23, 2024
@igordmn igordmn added p:critical Critical priority submitted reproduced runtime Compose runtime problem and removed submitted labels Apr 23, 2024
igordmn added a commit to JetBrains/compose-multiplatform-core that referenced this issue Apr 24, 2024
Fixes JetBrains/compose-multiplatform#4681

The issue was because of this situation:
- the parent RenderNodeLayer is drawn and cached it's `picture`
- the child RenderNodeLayer isn't drawn, but `invalidate` is called

the child's `invalidate` should invalidate parent layer unconditionally, but we called it only if the child was drawn (picture != null), which is incorrect.

It is a regression after #1260, but it just revealed the bug, not introduced it.

## Testing
- new added tests fail before, work after the fix
- the issue is no longer reproducible

This should be tested by QA

## Release Notes
> Fixes - Multiple Platforms
- _(prerelease fix)_ Fix frozen composition with pager and text field
igordmn added a commit to JetBrains/compose-multiplatform-core that referenced this issue Apr 25, 2024
Fixes JetBrains/compose-multiplatform#4681

The issue was because of this situation:
- the parent RenderNodeLayer is drawn and cached it's `picture`
- the child RenderNodeLayer isn't drawn, but `invalidate` is called

`invalidate` should have updated the parent layer (removing the
`picture` cache), but didn't do that as we do that conditionally. Now
`invalidate` invalidates the parent layer unconditionally.

It is a regression after
#1260, but
it just revealed the bug, didn't introduce it.

## Testing
- new added tests fail before, work after the fix
- the issue is no longer reproducible

This should be tested by QA

## Release Notes
> Fixes - Multiple Platforms
- _(prerelease fix)_ Fix frozen composition with pager and text field
@okushnikov
Copy link

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working p:critical Critical priority reproduced runtime Compose runtime problem
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants