https://kotlinlang.org logo
Title
b

bartosz.malkowski

10/18/2021, 11:47 AM
Hi! I stuck with one problem. I'm not sure if it is caused by Decompose or Compose Desktop, but I'm not able to reproduce it without router. I have master-detail application. When I click on master menu item, then I replace ruter configuration:
when (menuItem) {
	is SideMenu.MenuItem.DirectChatMenuItem -> router.replaceCurrent(Configuration.Conversation(menuItem.chat.openChatId))
	else -> router.replaceCurrent(Configuration.Nothing)
}
Here is child factory:
private fun createChild(
	configuration: Configuration, componentContext: ComponentContext,
): Child = when (configuration) {
	is Configuration.Conversation -> Child.Chat(
		ConversationMainComponent(componentContext, configuration.chatId, storeFactory)
	)
	is Configuration.Nothing -> Child.WelcomeScreen
}
ConversationMainComponent
contains
TextField
. When I show
ConversationMainComponent
first time and I make text field focused, then everything works fine. When I switch to different
DirectChatMenuItem
what creates different
ConversationMainComponent
and then I try to focus text field, I see exception:
Exception in thread "AWT-EventQueue-0" kotlin.UninitializedPropertyAccessException: lateinit property relocationRequesterNode has not been initialized
	at androidx.compose.ui.layout.RelocationRequesterModifier.getRelocationRequesterNode(RelocationRequesterModifier.kt:32)
	at androidx.compose.ui.layout.RelocationRequester.bringIntoView(RelocationRequester.kt:61)
	at androidx.compose.ui.layout.RelocationRequester.bringIntoView$default(RelocationRequester.kt:59)
	at androidx.compose.foundation.FocusableKt$focusable$2$4$1.invokeSuspend(Focusable.kt:108)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at androidx.compose.ui.platform.FlushCoroutineDispatcher$dispatch$2.invokeSuspend(CoroutineDispatchers.desktop.kt:55)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
	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)
Funny is, that when I select one direct chat, make field focused, then I select something else (
Child.WelcomeScreen
) and I select direct chat again, then everything works fine. Any advice? :-)
a

Arkadii Ivanov

10/18/2021, 12:31 PM
Hello! To me it looks like the issue is in Compose for Desktop. I would try on of the fresh Compose versions, e.g. Decompose 0.4.0 and 1.0.0-alpha4-build348. If the issue is still there, then I suggest to file an issue to https://github.com/JetBrains/compose-jb/issues Decompose does no magic here, I guess. Bu just in case, how the configurations are defined?
b

bartosz.malkowski

10/18/2021, 12:35 PM
private val router = router<Configuration, Child>(
		key = "MainRouter",
		initialConfiguration = Configuration.Roster, handleBackButton = true, childFactory = ::createChild,
	)


	sealed class Configuration : Parcelable {

		@Parcelize
		object Nothing : Configuration()

		@Parcelize
		object Roster : Configuration()

		@Parcelize
		object Settings : Configuration()

		@Parcelize
		data class Conversation(val chatId: Long) : Configuration()
	}
It seems will be good if I prepare project to reproduce this error 🙂
a

Arkadii Ivanov

10/18/2021, 12:40 PM
Looks perfectly fine. Yeah a reproducer would be good. Also you can start reducing the error by the following steps, check the error is still there after every step: 1. Remove the
Children(animation=)
argument, if set 2. Remove the
Children
function at all, and use just usual
routerState.subscribeAsState()
+
when (...)
3. Remove the
Router
and use just usual
State<Pair<Configuration, Child>>
(if compose only) or
StateFlow
(otherwise), and replace configurations and components manually. If you need a back stack (seems like you don't, but still), then it should be
State<List<Pair<Configuration, Child>>>
.
Regardless, I think the issue is in Compose for Desktop, it should not crash. Recently I experienced another crash with focusable input fields: https://github.com/JetBrains/compose-jb/issues/1157 Seems unrelated, but still, maybe try different versions of Compose.
b

bartosz.malkowski

10/18/2021, 1:18 PM
a

Arkadii Ivanov

10/18/2021, 1:19 PM
Thanks, I will try to check it today
🙂 1
So it looks like a bug in Compose. Also reproduced in normal Jetpack Compose. Filed an issue: https://issuetracker.google.com/issues/203433629
👍 1