Adjust RegV5 window insets so screens draw under system bars and handle display cutouts.

This commit is contained in:
jeffrey-signal
2026-06-03 07:25:06 -04:00
committed by Cody Henthorne
parent 4c942f39b0
commit ceee5f714d
7 changed files with 65 additions and 49 deletions
@@ -22,7 +22,8 @@
<activity
android:name=".MainActivity"
android:exported="true">
android:exported="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -88,8 +88,8 @@ sealed interface SampleRoute : NavKey {
*/
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
super.onCreate(savedInstanceState)
setContent {
SignalTheme {
@@ -108,11 +108,7 @@ class MainActivity : ComponentActivity() {
fun AppScreen(registrationDependencies: RegistrationDependencies) {
val backStack = rememberNavBackStack(SampleRoute.Main)
Box(
modifier = Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.safeDrawing)
) {
Box(modifier = Modifier.fillMaxSize()) {
SampleNavHost(
backStack = backStack,
registrationDependencies = registrationDependencies,
@@ -13,7 +13,8 @@
<activity
android:name=".RegistrationActivity"
android:exported="false"
android:theme="@android:style/Theme.Material.NoActionBar" />
android:theme="@android:style/Theme.Material.NoActionBar"
android:windowSoftInputMode="adjustResize" />
</application>
</manifest>
@@ -7,11 +7,7 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContract
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier
import com.google.accompanist.permissions.ExperimentalPermissionsApi
@@ -25,6 +21,13 @@ import org.signal.core.ui.compose.theme.SignalTheme
*/
class RegistrationActivity : ComponentActivity() {
companion object {
@JvmStatic
fun createIntent(context: Context): Intent {
return Intent(context, RegistrationActivity::class.java)
}
}
private val repository: RegistrationRepository by lazy {
RegistrationRepository(
context = this.application,
@@ -36,44 +39,25 @@ class RegistrationActivity : ComponentActivity() {
@OptIn(ExperimentalPermissionsApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
super.onCreate(savedInstanceState)
setContent {
SignalTheme(incognitoKeyboardEnabled = false) {
Surface {
Box(
modifier = Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.safeDrawing)
) {
RegistrationNavHost(
registrationRepository = repository,
modifier = Modifier.fillMaxSize(),
onRegistrationComplete = {
setResult(RESULT_OK)
finish()
}
)
}
Surface(modifier = Modifier.fillMaxSize()) {
RegistrationNavHost(
registrationRepository = repository,
modifier = Modifier.fillMaxSize(),
onRegistrationComplete = {
setResult(RESULT_OK)
finish()
}
)
}
}
}
}
companion object {
/**
* Creates an intent to launch the RegistrationActivity.
*
* @param context The context used to create the intent.
* @return An intent that can be used to start the RegistrationActivity.
*/
@JvmStatic
fun createIntent(context: Context): Intent {
return Intent(context, RegistrationActivity::class.java)
}
}
/**
* Activity result contract for launching the registration flow.
*
@@ -7,14 +7,21 @@ package org.signal.registration.screens
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Surface
@@ -160,9 +167,14 @@ object RegistrationScaffold {
) {
Surface(
modifier = modifier.fillMaxWidth(),
shadowElevation = if (isElevated) 8.dp else 0.dp,
content = content
)
shadowElevation = if (isElevated) 8.dp else 0.dp
) {
Box(
modifier = Modifier.windowInsetsPadding(WindowInsets.navigationBars)
) {
content()
}
}
}
}
@@ -176,7 +188,12 @@ fun RegistrationScaffold(
topBar: (@Composable () -> Unit)? = null,
footer: (@Composable () -> Unit)? = null
) {
SubcomposeLayout(modifier = modifier.imePadding()) { constraints ->
SubcomposeLayout(
modifier = modifier
.then(if (topBar == null) Modifier.windowInsetsPadding(WindowInsets.safeDrawing.only(WindowInsetsSides.Top)) else Modifier)
.then(if (footer == null) Modifier.windowInsetsPadding(WindowInsets.safeDrawing.only(WindowInsetsSides.Bottom)) else Modifier)
.imePadding()
) { constraints ->
val footerPlaceables = footer?.let {
subcompose("footer", it).map { m -> m.measure(constraints.copy(minWidth = 0, minHeight = 0)) }
} ?: emptyList()
@@ -215,7 +232,15 @@ fun OnePaneRegistrationScaffold(
modifier = modifier.fillMaxSize(),
topBar = topBar,
footer = footer,
content = { content(params.panePadding(hasHeader = topBar != null)) }
content = {
Box(
modifier = Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.safeDrawing.only(WindowInsetsSides.Horizontal))
) {
content(params.panePadding(hasHeader = topBar != null))
}
}
)
}
@@ -238,7 +263,9 @@ fun TwoPaneRegistrationScaffold(
content = {
Row(
horizontalArrangement = Arrangement.SpaceAround,
modifier = Modifier.fillMaxSize()
modifier = Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.safeDrawing.only(WindowInsetsSides.Horizontal))
) {
firstPane(params.firstPanePadding(hasHeader = topBar != null))
secondPane(params.secondPanePadding(hasHeader = topBar != null))
@@ -11,10 +11,13 @@ import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@@ -48,6 +51,7 @@ fun CaptchaScreen(
Column(
modifier = modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.safeDrawing)
) {
Box(
modifier = Modifier
@@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
@@ -176,7 +177,8 @@ private fun OnePaneLayout(
OnePaneRegistrationScaffold(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding),
.padding(innerPadding)
.consumeWindowInsets(innerPadding),
params = params,
content = { paddingValues ->
Column(
@@ -237,7 +239,8 @@ private fun TwoPaneLayout(
TwoPaneRegistrationScaffold(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding),
.padding(innerPadding)
.consumeWindowInsets(innerPadding),
params = params,
firstPane = { paddingValues ->
Column(