fix keyboard handling — offset dock instead of padding

adjustResize didn't work with enableEdgeToEdge (input hidden
behind keyboard). imePadding inflated the dock (input too high).

New approach: read WindowInsets.ime bottom value directly and
apply it as negative Y offset on the dock. The dock slides up
by exactly the keyboard height — no inflation, no layout changes.
windowSoftInputMode=adjustNothing (edge-to-edge default).

When keyboard closed: offset = nav bar height (gesture bar).
When keyboard open: offset = keyboard height (includes nav bar).
This commit is contained in:
Bruno Deanoz 2026-06-22 01:21:32 +02:00
parent 420bcd7cb6
commit c014d6d90c
2 changed files with 9 additions and 3 deletions

View file

@ -21,7 +21,7 @@
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:windowSoftInputMode="adjustResize"
android:windowSoftInputMode="adjustNothing"
android:theme="@style/Theme.Kaizen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View file

@ -15,8 +15,11 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.isImeVisible
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.offset
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
@ -704,9 +707,13 @@ fun ChatScreen(
// 3. Floating Bottom Control Dock
@OptIn(ExperimentalLayoutApi::class)
val imeVisible = WindowInsets.isImeVisible
val imeBottom = WindowInsets.ime.getBottom(LocalDensity.current)
val navBottom = WindowInsets.navigationBars.getBottom(LocalDensity.current)
val bottomOffset = if (imeVisible) maxOf(imeBottom, navBottom) else navBottom
Column(
modifier = Modifier
.align(Alignment.BottomCenter)
.offset(y = with(LocalDensity.current) { -bottomOffset.toDp() })
.background(
if (imeVisible) {
Brush.verticalGradient(listOf(scrimColor, scrimColor))
@ -721,7 +728,6 @@ fun ChatScreen(
)
}
)
.navigationBarsPadding()
.then(if (isTablet) Modifier.widthIn(max = 720.dp) else Modifier)
) {
if (!imeVisible) {