Skip to content

Commit 774e79d

Browse files
committed
Fix clickable regions not being correctly placed
It seems that using the scale modifier or scale properties of a layout modifier causes the clickable regions of some elements to be incorrect. This manifests as buttons "not working" but just being somewhere else on the screen. However, once the screen is resized, or you switch to the overview and back, the clickable regions are correct again. Not sure if this is a problem with how scaling was performed or if it's an actual bug in Compose. I'm leaning towards the second. Will try and reproduce on Android some other time. Thankfully, this can be worked around by modifying the local density instead and using a required size within.
1 parent 287b325 commit 774e79d

2 files changed

Lines changed: 25 additions & 26 deletions

File tree

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,39 @@
11
package dev.bnorm.storyboard.ui
22

33
import androidx.compose.foundation.layout.Box
4+
import androidx.compose.foundation.layout.BoxWithConstraints
5+
import androidx.compose.foundation.layout.requiredSize
46
import androidx.compose.runtime.Composable
7+
import androidx.compose.runtime.CompositionLocalProvider
8+
import androidx.compose.ui.Alignment
59
import androidx.compose.ui.Modifier
6-
import androidx.compose.ui.layout.layout
7-
import androidx.compose.ui.unit.Constraints
10+
import androidx.compose.ui.platform.LocalDensity
11+
import androidx.compose.ui.unit.Density
812
import androidx.compose.ui.unit.DpSize
913

1014
@Composable
1115
fun FixedSize(
1216
size: DpSize,
1317
modifier: Modifier = Modifier,
18+
contentAlignment: Alignment = Alignment.TopStart,
1419
content: @Composable () -> Unit,
1520
) {
16-
// TODO i think there is a bug in the scale code of Compose...
17-
// - until the desktop window is resized, clickable regions for buttons are incorrectly placed.
18-
// - this is reproducible with a BoxWithConstraints and scale modifier as well.
19-
// - going to the overview and back seems to fix it.
20-
Box(modifier = modifier.layout { measurable, constraints ->
21-
val scale = minOf(
22-
constraints.maxWidth / size.width.toPx(),
23-
constraints.maxHeight / size.height.toPx(),
24-
)
21+
BoxWithConstraints(
22+
modifier = modifier,
23+
contentAlignment = contentAlignment,
24+
) {
25+
val currentDensity = LocalDensity.current
26+
val scale = with(currentDensity) {
27+
minOf(
28+
constraints.maxWidth / size.width.toPx(),
29+
constraints.maxHeight / size.height.toPx(),
30+
)
31+
}
2532

26-
val fixedConstraints = Constraints.fixed(size.width.roundToPx(), size.height.roundToPx())
27-
val placeable = measurable.measure(fixedConstraints)
28-
layout(placeable.width, placeable.height) {
29-
placeable.placeWithLayer(0, 0) {
30-
scaleX = scale
31-
scaleY = scale
33+
CompositionLocalProvider(LocalDensity provides Density(currentDensity.density * scale)) {
34+
Box(modifier = Modifier.requiredSize(size)) {
35+
content()
3236
}
3337
}
34-
}) {
35-
content()
3638
}
3739
}

storyboard-core/src/commonMain/kotlin/dev/bnorm/storyboard/ui/Scene.kt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,10 @@ internal fun SceneWrapper(
7676
modifier: Modifier = Modifier,
7777
content: @Composable SharedTransitionScope.() -> Unit,
7878
) {
79-
// TODO i don't like that this box is part of the "scene"
80-
Box(contentAlignment = Alignment.Center, modifier = modifier.fillMaxSize()) {
81-
FixedSize(size = size) {
82-
decorator.decorate {
83-
SharedTransitionLayout {
84-
content()
85-
}
79+
FixedSize(size = size, modifier = modifier, contentAlignment = Alignment.Center) {
80+
decorator.decorate {
81+
SharedTransitionLayout {
82+
content()
8683
}
8784
}
8885
}

0 commit comments

Comments
 (0)