diff --git a/CHANGELOG.md b/CHANGELOG.md index 5385d931..c30765a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,6 +89,7 @@ Emojis for the following are chosen based on [gitmoji](https://gitmoji.dev/). ### 🐛 Bug Fixes +- Fixed keyboard window decor transparency and navigation bar insets under Android 16 edge-to-edge display enforcement so the screen background is no longer obscured ([#759](https://github.com/scribe-org/Scribe-Android/issues/759)). - The keyboard service no longer crashes when an editor starts input with no `EditorInfo` ([#699](https://github.com/scribe-org/Scribe-Android/issues/699)). - Downloading or checking for language data updates no longer crashes the app when the server returns a malformed timestamp ([#700](https://github.com/scribe-org/Scribe-Android/issues/700)). - Native dictionaries are re-extracted after an app update so autosuggestions no longer use dictionaries from a previous install ([#701](https://github.com/scribe-org/Scribe-Android/issues/701)). diff --git a/app/src/keyboards/java/be/scri/helpers/ui/KeyboardThemeManager.kt b/app/src/keyboards/java/be/scri/helpers/ui/KeyboardThemeManager.kt index 788ef0f9..04a688d0 100644 --- a/app/src/keyboards/java/be/scri/helpers/ui/KeyboardThemeManager.kt +++ b/app/src/keyboards/java/be/scri/helpers/ui/KeyboardThemeManager.kt @@ -5,6 +5,7 @@ package be.scri.helpers.ui import android.content.Context import android.content.res.ColorStateList import android.graphics.Color +import android.graphics.drawable.ColorDrawable import android.graphics.drawable.GradientDrawable import android.graphics.drawable.LayerDrawable import android.graphics.drawable.RippleDrawable @@ -50,6 +51,7 @@ class KeyboardThemeManager { uiManager: KeyboardUIManager?, ) { val targetWindow = window ?: return + targetWindow.decorView.setBackgroundColor(Color.TRANSPARENT) targetWindow.decorView.post { val context = service.applicationContext val isDarkMode = getIsDarkModeOrNot(context) @@ -66,11 +68,7 @@ class KeyboardThemeManager { targetWindow.isNavigationBarContrastEnforced = false } - if (isFloatingMode) { - targetWindow.decorView.setBackgroundColor(Color.TRANSPARENT) - } else { - targetWindow.decorView.setBackgroundColor(color) - } + targetWindow.decorView.setBackgroundColor(Color.TRANSPARENT) val insetsController = WindowCompat.getInsetsController(targetWindow, targetWindow.decorView) insetsController.isAppearanceLightNavigationBars = isLightColor(color) @@ -89,25 +87,49 @@ class KeyboardThemeManager { } if (uiManager != null) { + uiManager.binding.root.setBackgroundColor(Color.TRANSPARENT) if (isFloatingMode) { - uiManager.binding.root.setBackgroundColor(Color.TRANSPARENT) - val kbBgColor = ContextCompat.getColor(service, if (isDarkMode) R.color.dark_keyboard_bg_color else R.color.light_keyboard_bg_color) + val kbBgColor = + ContextCompat.getColor( + service, + if (isDarkMode) R.color.dark_keyboard_bg_color else R.color.light_keyboard_bg_color, + ) uiManager.binding.floatingDragBar.setBackgroundColor(kbBgColor) val pillColor = if (isDarkMode) 0x4DFFFFFF.toInt() else 0x40000000.toInt() uiManager.binding.floatingDragHandle.setColorFilter(pillColor) } else { - uiManager.binding.root.setBackgroundColor(color) + uiManager.binding.keyboardCard.background = ColorDrawable(color) + } + + val applyBottomPadding: (WindowInsetsCompat?) -> Unit = { windowInsets -> + val insets = windowInsets ?: ViewCompat.getRootWindowInsets(targetWindow.decorView) + val insetTypes = WindowInsetsCompat.Type.navigationBars() or WindowInsetsCompat.Type.displayCutout() + val navBarHeight = insets?.getInsets(insetTypes)?.bottom ?: 0 + val extraBottomPadding = (10 * service.resources.displayMetrics.density).toInt() + val paddingBottom = if (isFloatingMode) 0 else (navBarHeight + extraBottomPadding) + val card = uiManager.binding.keyboardCard + if (card.paddingBottom != paddingBottom) { + card.setPadding(0, 0, 0, paddingBottom) + } + if (uiManager.binding.root.paddingBottom != 0) { + uiManager.binding.root.setPadding(0, 0, 0, 0) + } } - ViewCompat.setOnApplyWindowInsetsListener(uiManager.binding.root) { view, insets -> - val insetTypes = WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() - val navBarHeight = insets.getInsets(insetTypes).bottom - val paddingBottom = if (isFloatingMode) 0 else navBarHeight - view.setPadding(0, 0, 0, paddingBottom) + ViewCompat.setOnApplyWindowInsetsListener(targetWindow.decorView) { _, insets -> + applyBottomPadding(insets) insets } + ViewCompat.setOnApplyWindowInsetsListener(uiManager.binding.root) { _, insets -> + applyBottomPadding(insets) + insets + } + + applyBottomPadding(null) + uiManager.binding.root.post { + ViewCompat.requestApplyInsets(targetWindow.decorView) ViewCompat.requestApplyInsets(uiManager.binding.root) } } diff --git a/app/src/keyboards/java/be/scri/services/GeneralKeyboardIME.kt b/app/src/keyboards/java/be/scri/services/GeneralKeyboardIME.kt index 0363583b..53db30c0 100644 --- a/app/src/keyboards/java/be/scri/services/GeneralKeyboardIME.kt +++ b/app/src/keyboards/java/be/scri/services/GeneralKeyboardIME.kt @@ -387,6 +387,9 @@ abstract class GeneralKeyboardIME( outInsets.touchableRegion.setEmpty() } } else { + val card = uiManager.binding.keyboardCard + val targetView = if (card.visibility == View.VISIBLE && card.height > 0) card else inputView + targetView.getLocationInWindow(location) outInsets.visibleTopInsets = location[1] outInsets.contentTopInsets = location[1] outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_VISIBLE diff --git a/app/src/main/res/layout/input_method_view.xml b/app/src/main/res/layout/input_method_view.xml index 36d913ad..8611af16 100644 --- a/app/src/main/res/layout/input_method_view.xml +++ b/app/src/main/res/layout/input_method_view.xml @@ -715,17 +715,13 @@ GeneralKeyboardIME.kt + android:visibility="gone"> 46dp 32dp 40dp - 58dp + 50dp 40dp 73dp 113dp