@@ -229,24 +229,17 @@ public fun Modifier.balloon(
229229 Layout (
230230 content = { balloonContent() },
231231 measurePolicy = { measurables, constraints ->
232- val isUnboundedWidth = constraints.maxWidth == Constraints .Infinity
233- val isUnboundedHeight = constraints.maxHeight == Constraints .Infinity ||
234- constraints.maxHeight == 0
235-
236- val effectiveMaxWidth = if (fixedWidthMode) {
237- // Fixed mode: always use screenWidth so ratio/explicit widths aren't clamped by anchor.
238- screenWidth
239- } else if (isUnboundedWidth) {
240- // Unbounded (e.g., KMM, ScrollView): fall back to screenWidth.
241- screenWidth
242- } else {
243- // Bounded non-fixed mode: respect the parent constraints (e.g., XML+ComposeView).
244- constraints.maxWidth.coerceAtMost(screenWidth)
245- }
232+ // The balloon renders in a PopupWindow (floating overlay), not in the parent layout.
233+ // Therefore, parent constraints must NOT limit the balloon content measurement.
234+ // The Layout here is purely for measurement (layout(0, 0) {}), so we always use
235+ // screen dimensions as the upper bound. This fixes:
236+ // - #943: width incorrectly clamped to parent constraints in XML+ComposeView/KMM
237+ // - #952: height incorrectly clamped to parent's fixed height
238+ // - #963: negative constraints.maxHeight from ConstraintLayout on Chromebooks
239+ val effectiveMaxWidth = screenWidth
246240 val effectiveMaxHeight = when {
247241 builder.height != BalloonSizeSpec .WRAP -> builder.height
248- isUnboundedHeight -> screenWidth * 2
249- else -> constraints.maxHeight
242+ else -> screenWidth * 2
250243 }.coerceAtLeast(0 )
251244
252245 val maxContentWidth = when {
@@ -264,10 +257,8 @@ public fun Modifier.balloon(
264257 }.coerceAtLeast(0 )
265258
266259 val targetWidth = if (fixedWidthMode) {
267- // IMPORTANT: do NOT clamp to constraints.maxWidth (anchor width)
268260 maxContentWidth
269261 } else {
270- // Non-fixed mode: respect parent constraints.
271262 maxContentWidth.coerceAtMost((effectiveMaxWidth - horizontalPadding).coerceAtLeast(0 ))
272263 }.coerceAtLeast(0 )
273264
0 commit comments