What is the way to ensure compose window is handle...
# compose-desktop
m
What is the way to ensure compose window is handled on main thread? Using latest (1.6.11) compose desktop I do encounter namely IllegalStateException due to operating on wrong thread.
m
Make sure that you are using
Dispatchers.Main
if you are inside a coroutine.
m
do you mean to explicit add this? I am just trying to run very basic sample code:
Copy code
fun main() = application {
     Window(
         onCloseRequest = ::exitApplication,
     ) {
         var isDialogOpen by remember { mutableStateOf(false) }
 
         Button(onClick = { isDialogOpen = true }) {
             Text(text = "Open dialog")
         }
 
         if (isDialogOpen) {
             DialogWindow(
                 onCloseRequest = { isDialogOpen = false },
                 state = rememberDialogState(position = WindowPosition(Alignment.Center))
             ) {
                 // Dialog's content
             }
         }
     }
 }
m
It should run on Main by default but here you have two different contexts (Window and DialogWindow) maybe this is causing an issue.
If you try with a normal Compose Dialog do you still encounter this issue?
m
no difference unfortunately. the problem looks like in new versions for desktop lifecycle state is handled and that seems to fail due to operating on different thread
m
Weird, working fine for me
m
stack looks like this:
Copy code
Exception in thread "main" java.lang.IllegalStateException: Method setCurrentState must be called on the main thread
         at androidx.lifecycle.LifecycleRegistry.enforceMainThreadIfNeeded(LifecycleRegistry.jvm.kt:302)
         at androidx.lifecycle.LifecycleRegistry.setCurrentState(LifecycleRegistry.jvm.kt:106)
         at androidx.compose.ui.scene.ComposeContainer.updateLifecycleState(ComposeContainer.desktop.kt:453)
         at androidx.compose.ui.scene.ComposeContainer.onWindowFocusChanged(ComposeContainer.desktop.kt:222)
         at androidx.compose.ui.scene.ComposeContainer.setWindow(ComposeContainer.desktop.kt:314)
         at androidx.compose.ui.scene.ComposeContainer.<init>(ComposeContainer.desktop.kt:182)
         at androidx.compose.ui.scene.ComposeContainer.<init>(ComposeContainer.desktop.kt:82)
         at androidx.compose.ui.awt.ComposeWindowPanel.<init>(ComposeWindowPanel.desktop.kt:52)
         at androidx.compose.ui.awt.ComposeWindow.<init>(ComposeWindow.desktop.kt:65)
         at androidx.compose.ui.awt.ComposeWindow.<init>(ComposeWindow.desktop.kt:63)
         at androidx.compose.ui.window.Window_desktopKt$Window$3.invoke(Window.desktop.kt:182)
         at androidx.compose.ui.window.Window_desktopKt$Window$3.invoke(Window.desktop.kt:176)
         at androidx.compose.ui.window.Window_desktopKt$Window$10.invoke(Window.desktop.kt:409)
         at androidx.compose.ui.window.Window_desktopKt$Window$10.invoke(Window.desktop.kt:406)
         at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$2.invoke(AwtWindow.desktop.kt:70)
         at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$2.invoke(AwtWindow.desktop.kt:69)
         at androidx.compose.runtime.DisposableEffectImpl.onRemembered(Effects.kt:82)
         at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:1295)
         at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:984)
         at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:1005)
         at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:1099)
         at androidx.compose.runtime.CompositionImpl.composeInitial(Composition.kt:633)
         at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:619)
         at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2.invokeSuspend(Application.desktop.kt:221)
         at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
         at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
         at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
         at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
         at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
         at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
         at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
         at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
         at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
         at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
         at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
         at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
         at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
         at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
         at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
🤔 1