Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,10 @@ internal class RootNodeOwner(
val semanticsOwner get() = owner.semanticsOwner
var size: IntSize? = size
set(value) {
field = value
onRootConstrainsChanged(value?.toConstraints())
if (field != value) {
field = value
onRootConstrainsChanged(value?.toConstraints())
}
}
var density by mutableStateOf(density)

Expand Down Expand Up @@ -219,7 +221,7 @@ internal class RootNodeOwner(
height = children.fastMaxOfOrDefault(0) { it.outerCoordinator.measuredHeight },
)
} finally {
measureAndLayoutDelegate.updateRootConstraintsWithInfinityCheck(constraints)
measureAndLayoutDelegate.updateRootConstraintsWithInfinityCheck(size?.toConstraints())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ import androidx.compose.ui.text.input.TextEditingScope
import androidx.compose.ui.text.input.TextEditorState
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -154,18 +156,53 @@ class RootNodeOwnerTest {
assertTrue(keyboardShowCalled)
assertTrue(keyboardHideCalled)
}

@Test
fun setSizeOnlyTriggersConstraintChangeWhenValueChanges() = runTest {
var measureAndLayoutCount = 0

val owner = RootNodeOwner(
snapshotInvalidationTracker = SnapshotInvalidationTracker {
measureAndLayoutCount++
}
)

// Set initial size
owner.size = IntSize(100, 100)
val initialCount = measureAndLayoutCount

// Setting the same size should not trigger measure and layout
owner.size = IntSize(100, 100)

// Count should remain the same
assertEquals(measureAndLayoutCount, initialCount)

// Setting a different size should trigger measure and layout
owner.size = IntSize(200, 200)

// Count should increase
assertTrue(measureAndLayoutCount > initialCount)
val afterChangeCount = measureAndLayoutCount

// Setting the same size again should not trigger another measure and layout
owner.size = IntSize(200, 200)

// Count should remain the same
assertEquals(measureAndLayoutCount, afterChangeCount)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wording here is a bit confusing, because there's no measure-and-layout happening.

I'd suggest:

  1. Rename measureAndLayoutCount to invalidationCount.
  2. Change the comments from "trigger measure and layout" to "triggerInvalidation".

}
}

private fun RootNodeOwner(
coroutineContext: CoroutineContext = EmptyCoroutineContext,
platformContext: PlatformContext = PlatformContext.Empty(),
snapshotInvalidationTracker: SnapshotInvalidationTracker = SnapshotInvalidationTracker {},
) = RootNodeOwner(
density = Density(1f),
layoutDirection = LayoutDirection.Ltr,
size = null,
coroutineContext = coroutineContext,
platformContext = platformContext,
snapshotInvalidationTracker = SnapshotInvalidationTracker {},
snapshotInvalidationTracker = snapshotInvalidationTracker,
inputHandler = ComposeSceneInputHandler(
prepareForPointerInputEvent = {},
processPointerInputEvent = { PointerEventResult(false) },
Expand Down