Open wuhuagang opened 1 year ago
Could you please provide a small sample to reproduce the crash?
I have an even smaller number: (794673 instead of 2147483647)
Exception in thread "AWT-EventQueue-0 @coroutine#13" java.lang.IllegalArgumentException: Can't represent a size of 794673 in Constraints
at androidx.compose.ui.unit.Constraints$Companion.bitsNeedForSize(Constraints.kt:403)
at androidx.compose.ui.unit.Constraints$Companion.createConstraints-Zbe2FdA$ui_unit(Constraints.kt:363)
at androidx.compose.ui.unit.Constraints$Companion.fixed-JhjzzOo(Constraints.kt:314)
at androidx.compose.foundation.text.modifiers.TextAnnotatedStringNode.measure-3p2s80s(TextAnnotatedStringNode.kt:287)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116)
at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure-3p2s80s(GraphicsLayerModifier.kt:646)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116)
at androidx.compose.foundation.layout.FillNode.measure-3p2s80s(Size.kt:698)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116)
at androidx.compose.foundation.layout.PaddingNode.measure-3p2s80s(Padding.kt:397)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1499)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1495)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2300)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:471)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:234)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui(OwnerSnapshotObserver.kt:133)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui(OwnerSnapshotObserver.kt:113)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1495)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:35)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:560)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.measure-BRTryo0(LayoutNodeLayoutDelegate.kt:539)
at androidx.compose.foundation.layout.BoxKt$boxMeasurePolicy$1.measure-3p2s80s(Box.kt:114)
at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:126)
at androidx.compose.foundation.ScrollingLayoutNode.measure-3p2s80s(Scroll.kt:389)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116)
at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure-3p2s80s(GraphicsLayerModifier.kt:646)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1499)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1495)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2300)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:471)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:234)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui(OwnerSnapshotObserver.kt:133)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui(OwnerSnapshotObserver.kt:113)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1495)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:35)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:560)
at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui(LayoutNode.kt:1140)
at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui$default(LayoutNode.kt:1131)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-sdFAvZA(MeasureAndLayoutDelegate.kt:323)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:458)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.access$remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:39)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout(MeasureAndLayoutDelegate.kt:344)
at androidx.compose.ui.platform.SkiaBasedOwner.measureAndLayout(SkiaBasedOwner.skiko.kt:246)
at androidx.compose.ui.node.Owner.measureAndLayout$default(Owner.kt:223)
at androidx.compose.ui.ComposeScene.render(ComposeScene.skiko.kt:546)
at androidx.compose.ui.awt.ComposeBridge$skikoView$1$onRender$1.invoke(ComposeBridge.desktop.kt:156)
at androidx.compose.ui.awt.ComposeBridge$skikoView$1$onRender$1.invoke(ComposeBridge.desktop.kt:155)
at androidx.compose.ui.awt.ComposeBridge.catchExceptions(ComposeBridge.desktop.kt:128)
at androidx.compose.ui.awt.ComposeBridge.access$catchExceptions(ComposeBridge.desktop.kt:59)
at androidx.compose.ui.awt.ComposeBridge$skikoView$1.onRender(ComposeBridge.desktop.kt:155)
at org.jetbrains.skiko.SkiaLayer.update$skiko(SkiaLayer.awt.kt:548)
at org.jetbrains.skiko.redrawer.AWTRedrawer.update(AWTRedrawer.kt:54)
at org.jetbrains.skiko.redrawer.MetalRedrawer$frameDispatcher$1.invokeSuspend(MetalRedrawer.kt:83)
at org.jetbrains.skiko.redrawer.MetalRedrawer$frameDispatcher$1.invoke(MetalRedrawer.kt)
at org.jetbrains.skiko.redrawer.MetalRedrawer$frameDispatcher$1.invoke(MetalRedrawer.kt)
at org.jetbrains.skiko.FrameDispatcher$job$1.invokeSuspend(FrameDispatcher.kt:33)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
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.executePrivileged(AccessController.java:778)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
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)
Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [CoroutineId(13), "coroutine#13":StandaloneCoroutine{Cancelling}@6b3dd778, SwingDispatcher@43153f9d]
As #3799 is closed, I will continue the discussion here.
Setting a string with 300K length to a Text()
component would reproduce the constraint issue. Although this limitation is what Compose for Android designed, because it might not (?) make sense to display such volume in an Android mobile device. But in desktop, I think it is a valid use case. It does not make sense that a desktop application cannot handle displaying 1MB data. It is expected Google would reject or put in a very low priority for this issue, but in the desktop world this is a larger issue.
I think an alternative is to provide a LazyText (or make Text lazy) with some care of scrolling API design, or expose the text layout API so that developers can split long strings into multiple Text components embedded in a LazyColumn/Row.
It seems there already exists workaround for other use cases, e.g. giant image - cropped by visible area with nested scrolling, long list - use LazyColumn.
With compose desktop 1.5.2, I only encountered this issue with Text
, not scrollbars.
I am able to implement a workaround for long Text
composable.
var contentWidthInPx by remember { mutableStateOf<Int?>(null) }
val textStyle = LocalTextStyle.current.copy(
fontSize = LocalFont.current.bodyFontSize,
fontFamily = FontFamily.Monospace,
)
val density = LocalDensity.current
val fontFamilyResolver = LocalFontFamilyResolver.current
val numCharsInALine = if (contentWidthInPx != null) {
remember(contentWidthInPx) {
Paragraph(
text = "0".repeat(1000),
style = textStyle,
constraints = Constraints(maxWidth = contentWidthInPx!!),
density = density,
fontFamilyResolver = fontFamilyResolver,
).getLineEnd(0)
}
} else {
0
}
val textsSplitted = if (contentWidthInPx != null && numCharsInALine > 0) {
text.split('\n')
.flatMap {
it.chunked(numCharsInALine)
}
.withIndex()
.groupBy { it.index / 100 }
.map { it.value.joinToString("\n") { it.value } }
} else {
listOf(" ")
}
LazyColumn(modifier = Modifier.onGloballyPositioned {
contentWidthInPx = it.size.width
}) {
textsSplitted.forEach {
item {
Text(
text = it,
fontFamily = FontFamily.Monospace
)
}
}
}
Problems:
Text
is within a lazy container, the composable structure needs to be rewritten to avoid nested scrolling. (Can be very painful!)Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Can't represent a size of 2147483647 in Constraints at androidx.compose.ui.unit.Constraints$Companion.bitsNeedForSize(Constraints.kt:408) at androidx.compose.ui.unit.Constraints$Companion.createConstraints-Zbe2FdA$ui_unit(Constraints.kt:371) at androidx.compose.ui.unit.Constraints$Companion.fixed-JhjzzOo(Constraints.kt:319) at androidx.compose.foundation.Scrollbar_desktopKt$horizontalMeasurePolicy$1.measure-3p2s80s(Scrollbar.desktop.kt:610) at androidx.compose.ui.node.InnerPlaceable.measure-BRTryo0(InnerPlaceable.kt:55) at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131) at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131) at androidx.compose.foundation.layout.PaddingModifier.measure-3p2s80s(Padding.kt:364) at androidx.compose.ui.node.ModifiedLayoutNode.measure-BRTryo0(ModifiedLayoutNode.kt:39) at androidx.compose.foundation.layout.FillModifier.measure-3p2s80s(Size.kt:658) at androidx.compose.ui.node.ModifiedLayoutNode.measure-BRTryo0(ModifiedLayoutNode.kt:39) at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131) at androidx.compose.ui.node.OuterMeasurablePlaceable$remeasure$2.invoke(OuterMeasurablePlaceable.kt:99) at androidx.compose.ui.node.OuterMeasurablePlaceable$remeasure$2.invoke(OuterMeasurablePlaceable.kt:98) at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:1798) at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:121) at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui(OwnerSnapshotObserver.kt:88) at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui(OwnerSnapshotObserver.kt:76) at androidx.compose.ui.node.OuterMeasurablePlaceable.remeasure-BRTryo0(OuterMeasurablePlaceable.kt:98) at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui(LayoutNode.kt:1317) at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui$default(LayoutNode.kt:1313) at androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure(MeasureAndLayoutDelegate.kt:170) at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:228) at androidx.compose.ui.node.MeasureAndLayoutDelegate.access$remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:38) at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout(MeasureAndLayoutDelegate.kt:201) at androidx.compose.ui.platform.SkiaBasedOwner.measureAndLayout(SkiaBasedOwner.skiko.kt:245) at androidx.compose.ui.node.Owner$DefaultImpls.measureAndLayout$default(Owner.kt:182) at androidx.compose.ui.ComposeScene.render(ComposeScene.skiko.kt:381) at androidx.compose.ui.awt.ComposeLayer$1$onRender$1.invoke(ComposeLayer.desktop.kt:237) at androidx.compose.ui.awt.ComposeLayer$1$onRender$1.invoke(ComposeLayer.desktop.kt:236) at androidx.compose.ui.awt.ComposeLayer.catchExceptions(ComposeLayer.desktop.kt:89) at androidx.compose.ui.awt.ComposeLayer.access$catchExceptions(ComposeLayer.desktop.kt:70) at androidx.compose.ui.awt.ComposeLayer$1.onRender(ComposeLayer.desktop.kt:236) at org.jetbrains.skiko.SkiaLayer.update$skiko(SkiaLayer.awt.kt:441) at org.jetbrains.skiko.redrawer.Direct3DRedrawer.update(Direct3DRedrawer.kt:54) at org.jetbrains.skiko.redrawer.Direct3DRedrawer.access$update(Direct3DRedrawer.kt:10) at org.jetbrains.skiko.redrawer.Direct3DRedrawer$frameDispatcher$1.invokeSuspend(Direct3DRedrawer.kt:28) at org.jetbrains.skiko.redrawer.Direct3DRedrawer$frameDispatcher$1.invoke(Direct3DRedrawer.kt) at org.jetbrains.skiko.redrawer.Direct3DRedrawer$frameDispatcher$1.invoke(Direct3DRedrawer.kt) at org.jetbrains.skiko.FrameDispatcher$job$1.invokeSuspend(FrameDispatcher.kt:33) 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$$$capture(InvocationEvent.java:318) at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716) 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:741) 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) Disconnected from the target VM, address: '127.0.0.1:62502', transport: 'socket'
Process finished with exit code 0