Hi, I'm struggling with an issue I cannot reproduc...
# compose-desktop
o
Hi, I'm struggling with an issue I cannot reproduce on my side due to missing hardware. Some users are reporting navigation & app state loss when moving a Compose Desktop window from one screen to another. I do not have a secondary screen to test this, so I request some advices: • can you imagine another scenario which could mimic this? (I guess this is related to window being destroyed & recreated somehow?) • could you guess a reason why this happen? ◦ I'm using Decompose & Kodein in particular, maybe the Decompose nav scope isn't large enough? Maybe Kodein singleton lifecycle is not properly scoped either?
m
Maybe DPI change? There's no such thing as "navigation and state loss" in normal desktop apps, so that sounds like something Compose Desktop or the mobile libraries you're adding on top is doing in response to something it thinks of as equivalent to an Android activity restart.
I'd suggest changing your screen DPI whilst the app is open and see what happens
a
Since you are using Decompose, please make sure you are creating your root component correctly. See the docs. Most likely your root gets recreated.
o
I guess this is already what I'm doing right now:
Copy code
fun main(args: Array<String>) {
    val lifecycle = LifecycleRegistry()
    val rootComponentContext = DefaultComponentContext(lifecycle)

    application {
        ...
    }
}
I'm not using the
runOnUiThread
util though
a
What about the root component? Is it also created outside
application
?
o
Indeed, I read too quickly. I'm only dealing with
RootComponentContext
which is then provided to compose runtime with
ProvideComponentContext(rootComponentContext) {}
Maybe I miss something then. I think I started this from a sample in a blog post.
That being said, I do not have
DefaultRootComponent
available 🤔
I'm reading the quick-start
I'm creating my
ChildStack
in a nested composable, maybe this is why my navigation state is loss? I might have to store it in my
RootComponent
if I properly understand
a
Right, the approach in that article is another option. I believe the issue is that all
remember
-ed things (including
ChildStack
) are getting lost when you move the window to another display.
This might be a bug in Compose.
o
I'm moving around everything in a component created outside Compose runtime
a
One of the ways of fixing this currently, would be switching to a component-based navigation (as described in Decompose docs). Another way would be saving and restoring the state manually. Feel free to ask for details in #decompose channel.
@xxfast Decompose-Router may be affected as well.
👀 1
o
thanks for the hints! I'll try a blind fix approach by following decompose docs and try to find a way to validate this
👍 1
a
Yeah! I believe the actual cause is that
application {}
composition gets restarted (disposed and then a new composition started), which causes the navigation state to reset. Here is a fix from the top of my head (didn't try to run), in case you prefer to keep your way of doing navigation.
Copy code
fun main() {
    var savedState: ParcelableContainer? = null
    val instanceKeeper = InstanceKeeperDispatcher()

    application {
        val lifecycle = remember { LifecycleRegistry() }
        val stateKeeper = remember { StateKeeperDispatcher(savedState = savedState) }

        DisposableEffect(stateKeeper) {
            onDispose { savedState = stateKeeper.save() }
        }

        val rootComponentContext =
            DefaultComponentContext(
                lifecycle = lifecycle,
                stateKeeper = stateKeeper,
                instanceKeeper = instanceKeeper,
            )
        
        val windowState = rememberWindowState()
        LifecycleController(lifecycle, windowState)

        // The rest of the code
    }
}
o
I'll give it a try yes
m
As @mikehearn it could be a DPI change, I'm working on a desktop app that completely recompose when I move the window to another screen because the DPI changes.
a
Yes. But the actual issue looks not just full recomposition, but also losing any
remember
-ed objects. It appears that the whole
application
composition gets disposed and a new one started.
m
Yes, this is presumably some logic brought across from Android, which likes to dispose and rebuild the entire activity when screens change in certain ways iirc.
a
@Sebastian Aigner this looks like a bug in Compose, WDYT?
a
I’m not getting any recomposition at all when changing the resolution on my Mac
Don’t have another monitor, unfortunately.
o
When changing resolution, I didn't face my issue either, same, can't try with another monitor yet, in few weeks when I'm back at work, I'll be able to.
So, I finally managed to reproduce the issue with a secondary screen. After all, it appears that the issue came from my DI setup using Kodein, I was recreating some objects while considering they were reused. So, I'd say it's unrelated to Compose nor Decompose but a combination of several things and at the root an incorrect use of Kodein.
👍 1
👍🏼 1