From b431428260a0f03827aec7a2688bc62e1f6c843b Mon Sep 17 00:00:00 2001 From: Louis Date: Sat, 26 Sep 2026 00:12:21 +0200 Subject: [PATCH] Android: handle status bar, navigation bar and keyboard insets natively and consume them, so the keyboard no longer shrinks the view twice and content no longer sits under the status bar Co-Authored-By: Claude Opus 5.5 --- .../android/app/src/main/AndroidManifest.xml | 2 +- .../main/java/de/mrterm/app/MainActivity.java | 25 ++++++++++++++----- mobile/web/styles.css | 5 ++-- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/mobile/android/app/src/main/AndroidManifest.xml b/mobile/android/app/src/main/AndroidManifest.xml index 540218b..3ca7956 100644 --- a/mobile/android/app/src/main/AndroidManifest.xml +++ b/mobile/android/app/src/main/AndroidManifest.xml @@ -15,7 +15,7 @@ android:label="@string/title_activity_main" android:theme="@style/AppTheme.NoActionBarLaunch" android:launchMode="singleTask" - android:windowSoftInputMode="adjustResize" + android:windowSoftInputMode="adjustNothing" android:exported="true"> diff --git a/mobile/android/app/src/main/java/de/mrterm/app/MainActivity.java b/mobile/android/app/src/main/java/de/mrterm/app/MainActivity.java index ff2a56e..e96fe82 100644 --- a/mobile/android/app/src/main/java/de/mrterm/app/MainActivity.java +++ b/mobile/android/app/src/main/java/de/mrterm/app/MainActivity.java @@ -1,10 +1,13 @@ package de.mrterm.app; +import android.os.Build; import android.os.Bundle; import android.view.View; +import android.view.WindowManager; import android.webkit.WebView; import androidx.activity.OnBackPressedCallback; +import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; @@ -25,14 +28,24 @@ public class MainActivity extends BridgeActivity { } }); - // Edge-to-Edge: Bei offener Tastatur den WebView um die Tastaturhöhe verkleinern, - // damit Terminal und Zusatztasten sichtbar bleiben + // Edge-to-Edge: Abstände für Statusleiste, Navigationsleiste und Tastatur setzt allein diese Ansicht. + // Die Insets werden danach verbraucht, damit WebView/System nicht ein zweites Mal verkleinern. View parent = (View) web.getParent(); + parent.setBackgroundColor(0xFF14161D); + final boolean[] imeOpen = { false }; + // Vor Android 11 kommen Tastatur-Insets nicht zuverlässig: dort verkleinert das System das Fenster + final boolean legacyIme = Build.VERSION.SDK_INT < Build.VERSION_CODES.R; + if (legacyIme) getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); ViewCompat.setOnApplyWindowInsetsListener(parent, (v, insets) -> { - int ime = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom; - v.setPadding(0, 0, 0, ime); - web.evaluateJavascript("window.mrtermIme && window.mrtermIme(" + (ime > 0) + ")", null); - return insets; + Insets bars = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout()); + int ime = legacyIme ? 0 : insets.getInsets(WindowInsetsCompat.Type.ime()).bottom; + v.setPadding(bars.left, bars.top, bars.right, Math.max(ime, bars.bottom)); + boolean open = ime > 0; + if (open != imeOpen[0]) { + imeOpen[0] = open; + web.evaluateJavascript("window.mrtermIme && window.mrtermIme(" + open + ")", null); + } + return WindowInsetsCompat.CONSUMED; }); } } diff --git a/mobile/web/styles.css b/mobile/web/styles.css index 29831c7..28fcc9a 100644 --- a/mobile/web/styles.css +++ b/mobile/web/styles.css @@ -13,8 +13,9 @@ --orange: #ffb347; --radius: 14px; /* Capacitor setzt --safe-area-inset-* bei Edge-to-Edge; env() als Rückfall */ - --top: max(env(safe-area-inset-top, 0px), var(--safe-area-inset-top, 0px)); - --bottom: max(env(safe-area-inset-bottom, 0px), var(--safe-area-inset-bottom, 0px)); + /* Status-/Navigationsleiste und Tastatur rechnet MainActivity als Rand um den WebView heraus */ + --top: 0px; + --bottom: 0px; color-scheme: dark; } * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }