diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 8b5f595..f7ef2f6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -35,13 +35,13 @@ plugins { android { namespace = "at.dasher.android" - compileSdk = 35 + compileSdk = 36 ndkVersion = "27.0.12077973" defaultConfig { applicationId = "at.dasher.android" minSdk = 24 - targetSdk = 35 + targetSdk = 36 versionCode = gitVersionCode(base = 1000, fallback = 8) versionName = gitVersionName(fallback = "0.1.8") diff --git a/app/src/main/java/at/dasher/android/DasherImeService.kt b/app/src/main/java/at/dasher/android/DasherImeService.kt index e9f127d..13b8ed9 100644 --- a/app/src/main/java/at/dasher/android/DasherImeService.kt +++ b/app/src/main/java/at/dasher/android/DasherImeService.kt @@ -139,9 +139,9 @@ class DasherImeService : InputMethodService() { // window's FrameLayout-based decor. LinearLayout.LayoutParams here // survives until a re-measure casts them and crashes (Float's // docked-shrink relayout did exactly that). + dockedRoot = root setDockedHeight(imeHeightPx()) root.minimumHeight = imeHeightPx() - dockedRoot = root floatBtn.setOnClickListener { enterFloatingMode(floatBtn) } @@ -469,6 +469,26 @@ class DasherImeService : InputMethodService() { eng.clearSpeakListener() // IME doesn't speak (the app does) } + // API 36+ (Android 16): measure the actual docked-root position in the + // window so the insets animation has a concrete target (review C1/C3: + // imeHeightPx() is a HEIGHT, not an offset — a constant created a dead + // touch band above the keyboard and was wrong in floating mode). + // Measuring handles both modes automatically: floating shrinks the + // docked root to 40dp, and the measurement reflects that. + // API 36+: force-show even if a hardware keyboard is attached — our users + // (motor-impaired AAC) always want the soft keyboard (accessibility decision). + override fun onEvaluateInputViewShown(): Boolean = true + + override fun onComputeInsets(outInsets: Insets) { + super.onComputeInsets(outInsets) + val root = dockedRoot ?: return + val loc = IntArray(2) + root.getLocationInWindow(loc) + outInsets.contentTopInsets = loc[1] + outInsets.visibleTopInsets = loc[1] + outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_CONTENT + } + override fun onStartInputView(info: EditorInfo?, restarting: Boolean) { super.onStartInputView(info, restarting) // Re-assert ALL IME-owned static listeners — the main app may have