From 6d9f69a4b6d30669fa84891aedb0ffc1d9c6937c Mon Sep 17 00:00:00 2001 From: Eran Leshem <1707552+eranl@users.noreply.github.com> Date: Sat, 26 Apr 2025 08:34:27 +0300 Subject: [PATCH] Fix keyboard insets on Android 15, again (#1497) --- .../helium314/keyboard/latin/InputView.java | 62 ++++++++++++++++++- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/InputView.java b/app/src/main/java/helium314/keyboard/latin/InputView.java index 31bd722e8..aca0353b1 100644 --- a/app/src/main/java/helium314/keyboard/latin/InputView.java +++ b/app/src/main/java/helium314/keyboard/latin/InputView.java @@ -6,6 +6,9 @@ package helium314.keyboard.latin; +import java.util.function.BiFunction; + +import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Insets; import android.graphics.Rect; @@ -18,6 +21,7 @@ import android.view.WindowManager; import android.view.WindowMetrics; import android.widget.FrameLayout; +import androidx.annotation.RequiresApi; import androidx.core.view.ViewKt; import helium314.keyboard.accessibility.AccessibilityUtils; @@ -26,6 +30,7 @@ import helium314.keyboard.latin.common.ColorType; import helium314.keyboard.latin.settings.Settings; import helium314.keyboard.latin.suggestions.PopupSuggestionsView; import helium314.keyboard.latin.suggestions.SuggestionStripView; +import helium314.keyboard.latin.utils.Log; import kotlin.Unit; @@ -114,13 +119,17 @@ public final class InputView extends FrameLayout { Settings.getValues().mColors.setBackground(findViewById(R.id.main_keyboard_frame), ColorType.MAIN_BACKGROUND); if (Build.VERSION.SDK_INT >= 30) { - getLocationOnScreen(LOCATION); WindowManager wm = getContext().getSystemService(WindowManager.class); WindowMetrics windowMetrics = wm.getCurrentWindowMetrics(); - if (LOCATION[1] + getHeight() == windowMetrics.getBounds().height()) { + + if (Build.VERSION.SDK_INT >= 35 || isEdgeToEdge(windowMetrics)) { // Edge-to-edge mode + logInsets(wm.getMaximumWindowMetrics(), "max-metrics"); + logInsets(wm.getCurrentWindowMetrics(), "current-metrics"); + WindowInsets windowInsets = windowMetrics.getWindowInsets(); - int insetTypes = WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout(); + int insetTypes = WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout() + | WindowInsets.Type.systemGestures(); Insets insets = windowInsets.getInsetsIgnoringVisibility(insetTypes); // Can't set padding on this view, since it results in an overlap with window above the keyboard. @@ -133,6 +142,53 @@ public final class InputView extends FrameLayout { return null; } + @SuppressLint("DefaultLocale") + @RequiresApi(api = 30) + private boolean isEdgeToEdge(WindowMetrics windowMetrics) { + getLocationOnScreen(LOCATION); + Log.i("insets", String.format("Keyboard bottom: %d, screen height: %d.", LOCATION[1] + getHeight(), + windowMetrics.getBounds().height())); + return LOCATION[1] + getHeight() == windowMetrics.getBounds().height(); + } + + @RequiresApi(api = 30) + private static void logInsets(WindowMetrics metrics, String metricsType) { + logInsets(metrics, metricsType, WindowInsets::getInsets, "insets"); + logInsets(metrics, metricsType, WindowInsets::getInsetsIgnoringVisibility, "insetsIgnoringVisibility"); + } + + @RequiresApi(api = 30) + private static void logInsets(WindowMetrics metrics, String metricsType, + BiFunction insetsGetter, String visibility) { + logInsets(metrics, metricsType, WindowInsets.Type.navigationBars(),"navigationBars", + insetsGetter, visibility); + logInsets(metrics, metricsType, WindowInsets.Type.systemBars(), "systemBars", insetsGetter, visibility); + logInsets(metrics, metricsType, WindowInsets.Type.statusBars(), "statusBars", insetsGetter, visibility); + logInsets(metrics, metricsType, WindowInsets.Type.displayCutout(),"displayCutout", + insetsGetter, visibility); + logInsets(metrics, metricsType, WindowInsets.Type.systemGestures(),"systemGestures", + insetsGetter, visibility); + logInsets(metrics, metricsType, WindowInsets.Type.mandatorySystemGestures(), "mandatorySystemGestures", + insetsGetter, visibility); + logInsets(metrics, metricsType, WindowInsets.Type.tappableElement(),"tappableElement", + insetsGetter, visibility); + + if (Build.VERSION.SDK_INT >= 34) { + logInsets(metrics, metricsType, WindowInsets.Type.systemOverlays(), "systemOverlays", + insetsGetter, visibility); + } + } + + @RequiresApi(api = 30) + @SuppressLint("DefaultLocale") + private static void logInsets(WindowMetrics metrics, String metricsType, int insetTypes, String insetsType, + BiFunction insetsGetter, String visibility) { + WindowInsets windowInsets = metrics.getWindowInsets(); + Insets insets = insetsGetter.apply(windowInsets, insetTypes); + Log.i("insets", String.format("%s, %s, %s, bottom %d, top %d", metricsType, insetsType, visibility, + insets.bottom, insets.top)); + } + /** * This class forwards series of {@link MotionEvent}s from SenderView to * ReceiverView.