8af15cf08c20
keep the wide-screen scale in one composition slot (v2.14.78)
- time
- 2026-08-31 16:42 UTC · 1 month ago
- machine
- koh2
- agent
- hy4-preview
- session
- unfolded double lock screen
- parent
- 77ad8cf7bf55
↓ peach-android-8af15cf0.tar.gzatlas at this save
files changed3 files
VERSION+1 −1app/src/main/java/com/peachpasswords/MainActivity.kt+11 −8app/src/test/java/com/peachpasswords/MainActivityTest.kt+15 −0app/src/main/java/com/peachpasswords/MainActivity.kt+11 −8
@@ -14,6 +14,7 @@1414 import androidx.compose.ui.Modifier1515 import androidx.compose.runtime.CompositionLocalProvider1616 import androidx.compose.runtime.Composable17+import androidx.compose.runtime.remember1718 import androidx.compose.foundation.layout.fillMaxSize1819 import androidx.compose.foundation.layout.BoxWithConstraints1920 import androidx.compose.runtime.collectAsState@@ -203,14 +204,16 @@203204 BoxWithConstraints(Modifier.fillMaxSize()) {204205 val base = LocalDensity.current205206 val scale = wideScreenScaleFor(scalePreference, maxWidth, maxHeight)206- if (scale == 1f) {207- content()208- } else {209- CompositionLocalProvider(210- LocalDensity provides Density(base.density * scale, base.fontScale),211- content = content,212- )213- }207+ // Always go through the same slot. Branching between a bare content()208+ // and a wrapped one changes the composition's structure whenever the209+ // scale crosses 1f, which disposes and rebuilds everything inside —210+ // including the nav host and its remembered controller. The settings211+ // flow starts at the default "auto" and only later carries the212+ // persisted value, so a device set to "large" on a tablet-like screen213+ // resolves 1f first and 1.35f a moment later, dropping the user back214+ // on the lock screen to authenticate a second time.215+ val density = remember(base, scale) { Density(base.density * scale, base.fontScale) }216+ CompositionLocalProvider(LocalDensity provides density, content = content)214217 }215218 }216219 app/src/test/java/com/peachpasswords/MainActivityTest.kt+15 −0
@@ -20,4 +20,19 @@2020 assertEquals(1f, wideScreenScaleFor("compact", 673.dp, 841.dp), 0f)2121 assertEquals(1.35f, wideScreenScaleFor("large", 800.dp, 1280.dp), 0f)2222 }23+24+ /**25+ * On a phone-width window every preset lands on the same scale, so the26+ * persisted preference arriving after the default cannot change it. Only a27+ * tablet-like window makes "auto" and "large" disagree, which is what let28+ * the re-scale tear down the nav host on a foldable's inner screen.29+ */30+ @Test fun every_preset_agrees_on_a_phone_screen() {31+ assertEquals(32+ wideScreenScaleFor("auto", 385.dp, 914.dp),33+ wideScreenScaleFor("large", 385.dp, 914.dp),34+ 0f,35+ )36+ assertEquals(1f, wideScreenScaleFor("large", 385.dp, 914.dp), 0f)37+ }2338 }