Giter VIP home page Giter VIP logo

Comments (6)

elijah-semyonov avatar elijah-semyonov commented on May 24, 2024

Investigation of this particular sample is required.
Platform specific API works correctly:

val modifier = if (isSystemInDarkTheme()) {
        Modifier.background(Color.Gray)
    } else {
        Modifier.background(Color.White)
    }
    Box(modifier.fillMaxSize()) {
        Text("Background color depends on current system theme")
 }

from compose-multiplatform.

elijah-semyonov avatar elijah-semyonov commented on May 24, 2024

Thanks for a nice sample, reproduced.

https://github.com/elijah-semyonov/alkaa/commits/main/

Launching the app and changing the theme produces this log:

AlkaaLightColorScheme.primary: Color(0.0, 0.37254903, 0.69411767, 1.0, sRGB IEC61966-2.1)
AlkaaDarkColorScheme.primary: Color(0.6431373, 0.78431374, 1.0, 1.0, sRGB IEC61966-2.1)

isDarkTheme: false
Resolved MaterialTheme.colors.primary: Color(0.0, 0.37254903, 0.69411767, 1.0, sRGB IEC61966-2.1)
AlkaaNavGraph, MaterialTheme.colors.primary: Color(0.0, 0.37254903, 0.69411767, 1.0, sRGB IEC61966-2.1)
AlkaaNavGraph:BottomSheetNavigator, MaterialTheme.colors.primary: Color(0.0, 0.37254903, 0.69411767, 1.0, sRGB IEC61966-2.1)
AlkaaNavGraph:BottomSheetNavigator:Navigator, MaterialTheme.colors.primary: Color(0.0, 0.37254903, 0.69411767, 1.0, sRGB IEC61966-2.1)

// Theme changes

isDarkTheme: true
Resolved MaterialTheme.colors.primary: Color(0.6431373, 0.78431374, 1.0, 1.0, sRGB IEC61966-2.1)
AlkaaNavGraph, MaterialTheme.colors.primary: Color(0.6431373, 0.78431374, 1.0, 1.0, sRGB IEC61966-2.1)
AlkaaNavGraph:BottomSheetNavigator, MaterialTheme.colors.primary: Color(0.6431373, 0.78431374, 1.0, 1.0, sRGB IEC61966-2.1)
// LocalColorScheme.current, accessed through MaterialTheme.colorScheme is not updated
AlkaaNavGraph:BottomSheetNavigator:Navigator, MaterialTheme.colors.primary: Color(0.0, 0.37254903, 0.69411767, 1.0, sRGB IEC61966-2.1)

from compose-multiplatform.

elijah-semyonov avatar elijah-semyonov commented on May 24, 2024

Related issue:
adrielcafe/voyager#391

from compose-multiplatform.

elijah-semyonov avatar elijah-semyonov commented on May 24, 2024

On iOS Navigator Composable is recomposed with wrong(first non-default) staticCompositionLocal value.
On Desktop, the Navigator Composable is not recomposed at all.

enum class DummyTheme {
    DARK, LIGHT, UNKNOWN
}

val DummyThemeLocal = staticCompositionLocalOf {
    DummyTheme.UNKNOWN
}

@OptIn(ExperimentalMaterialApi::class)
@Composable
fun AlkaaMultiplatformApp(
    navigationAction: NavigationAction = NavigationAction.Home,
    modifier: Modifier = Modifier,
    onThemeUpdate: (isDarkTheme: Boolean) -> Unit = {},
) {
    println("App")
    var isDark by remember { mutableStateOf(true) }

    val theme = if (isDark) {
        DummyTheme.DARK
    } else {
        DummyTheme.LIGHT
    }

    Button(onClick = {
        isDark = !isDark
    }) {
        Text("Toggle")
    }

    CompositionLocalProvider(
        DummyThemeLocal provides theme
    ) {
        println("CompositionLocalProvider")
        BottomSheetNavigator {
            println("BottomSheetNavigator")
            println(DummyThemeLocal.current)
            Navigator(screen = object : Screen {
                @Composable
                override fun Content() = Unit
            }) { navigator ->
                println("Navigator")
                println(DummyThemeLocal.current)
            }
        }
    }
}

Confirmed, that the problem is not present on Android.
The issue doesn't seem to be related to PersistentCompositionLocalHashMap, there are no recent code changes in there.
Voyager uses currentCompositeKeyHash, which is explicitly marked as InternalComposeApi, which looks very suspicious, but doesn't explain why Android behaves correctly.

from compose-multiplatform.

m-sasha avatar m-sasha commented on May 24, 2024

Standalone reproducer:

import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.window.singleWindowApplication


val MyLocal1 = staticCompositionLocalOf<Int> { error("Not provided") }
val MyLocal2 = staticCompositionLocalOf<Int> { error("Not provided") }

fun main() = singleWindowApplication {
    var number by remember { mutableStateOf(1) }

    Button(
        onClick = { number += 1 }
    ) {
        Text("Toggle")
    }

    CompositionLocalProvider(MyLocal1 provides number) {
        CompositionLocalProvider(MyLocal2 providesDefault 5) {
            println("1: ${MyLocal1.current}")
            CompositionLocalProvider(MyLocal2 providesDefault 5) {
                println("2: ${MyLocal1.current}")
                Text(MyLocal1.current.toString())
            }
        }
    }
}

The issue is either https://issuetracker.google.com/issues/330036209 or another problem with providesDefault. I'll see that it's fixed on the Google side, but in the meanwhile, Voyager can work around this problem by using

CompositionLocalProvider(values = arrayOf(MyLocal2 providesDefault 5)) {

from compose-multiplatform.

m-sasha avatar m-sasha commented on May 24, 2024

Ok, whether it's that issue or something else, it no longer reproduces in 1.6.10.

from compose-multiplatform.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.