diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 475eb489..81b5e876 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -33,12 +33,12 @@ val junit5Version by extra("5.11.2") val mockkVersion by extra("1.13.13") android { - compileSdk = 35 + compileSdk = 36 defaultConfig { applicationId = "be.scri" minSdk = 26 - targetSdk = 34 + targetSdk = 36 versionCode = 7 versionName = "1.0.0" multiDexEnabled = true diff --git a/app/src/main/java/be/scri/services/GeneralKeyboardIME.kt b/app/src/main/java/be/scri/services/GeneralKeyboardIME.kt index 3e2aea96..d7c683a1 100644 --- a/app/src/main/java/be/scri/services/GeneralKeyboardIME.kt +++ b/app/src/main/java/be/scri/services/GeneralKeyboardIME.kt @@ -6,12 +6,14 @@ import DataContract import android.annotation.SuppressLint import android.content.Context import android.content.res.Configuration +import android.content.res.Resources import android.database.sqlite.SQLiteException import android.graphics.Color import android.graphics.drawable.GradientDrawable import android.graphics.drawable.LayerDrawable import android.graphics.drawable.RippleDrawable import android.inputmethodservice.InputMethodService +import android.inputmethodservice.InputMethodService.Insets import android.text.InputType import android.text.InputType.TYPE_CLASS_DATETIME import android.text.InputType.TYPE_CLASS_NUMBER @@ -22,6 +24,7 @@ import android.text.SpannableString import android.text.TextUtils import android.text.style.ForegroundColorSpan import android.util.Log +import android.view.InflateException import android.view.KeyEvent import android.view.View import android.view.inputmethod.EditorInfo @@ -228,6 +231,7 @@ abstract class GeneralKeyboardIME( suggestionHandler = SuggestionHandler(this) autocompletionManager = dbManagers.autocompletionManager autocompletionHandler = AutocompletionHandler(this) + binding = InputMethodViewBinding.inflate(layoutInflater) } /** @@ -235,22 +239,67 @@ abstract class GeneralKeyboardIME( * * @return The root View of the input method. */ - override fun onCreateInputView(): View { - binding = InputMethodViewBinding.inflate(layoutInflater) + override fun onCreateInputView(): View = + try { + val inputView = binding.root + keyboardView = binding.keyboardView + keyboard = KeyboardBase(this, getKeyboardLayoutXML(), enterKeyType) + + keyboardView?.setVibrate = getIsVibrateEnabled(applicationContext, language) + keyboardView?.setSound = getIsSoundEnabled(applicationContext, language) + keyboardView?.setHoldForAltCharacters = getHoldKeyStyle(applicationContext, language) + + keyboardView!!.setKeyboard(keyboard!!) + keyboardView!!.mOnKeyboardActionListener = this + + initializeUiElements() + setupClickListeners() + currentState = ScribeState.IDLE + saveConjugateModeType("none") + updateUI() + + inputView + } catch (e: Resources.NotFoundException) { + Log.e("GeneralKeyboardIME", "Keyboard layout resource not found", e) + View(this) + } catch (e: InflateException) { + Log.e("GeneralKeyboardIME", "Failed to inflate keyboard view", e) + View(this) + } catch (e: IllegalStateException) { + Log.e("GeneralKeyboardIME", "Illegal state while creating input view", e) + View(this) + } + + /** + * Always show the input view. Required for API 36 onwards as edge-to-edge + * enforcement can cause the keyboard to not display if this returns false. + */ + override fun onEvaluateInputViewShown(): Boolean { + super.onEvaluateInputViewShown() + return true + } + + /** + * Disable fullscreen mode to ensure the keyboard displays correctly on API 36 onwards. + * Fullscreen mode can interfere with edge-to-edge layouts. + */ + override fun onEvaluateFullscreenMode(): Boolean = false + + /** + * Compute the insets for the keyboard view. This is essential for API 36+ + * where the system needs to know the exact size of the keyboard to properly + * handle edge-to-edge display and window insets. + */ + override fun onComputeInsets(outInsets: Insets) { + super.onComputeInsets(outInsets) val inputView = binding.root - keyboardView = binding.keyboardView - keyboard = KeyboardBase(this, getKeyboardLayoutXML(), enterKeyType) - keyboardView?.setVibrate = getIsVibrateEnabled(applicationContext, language) - keyboardView?.setSound = getIsSoundEnabled(applicationContext, language) - keyboardView?.setHoldForAltCharacters = getHoldKeyStyle(applicationContext, language) - keyboardView!!.setKeyboard(keyboard!!) - keyboardView!!.mOnKeyboardActionListener = this - initializeUiElements() - setupClickListeners() - currentState = ScribeState.IDLE - saveConjugateModeType("none") - updateUI() - return inputView + if (inputView.visibility == View.VISIBLE && inputView.height > 0) { + val location = IntArray(2) + inputView.getLocationInWindow(location) + outInsets.visibleTopInsets = location[1] + outInsets.contentTopInsets = location[1] + outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_VISIBLE + } } override fun onWindowShown() { diff --git a/app/src/main/res/layout/input_method_view.xml b/app/src/main/res/layout/input_method_view.xml index 0f615b42..b3ed389f 100644 --- a/app/src/main/res/layout/input_method_view.xml +++ b/app/src/main/res/layout/input_method_view.xml @@ -12,6 +12,7 @@ android:id="@+id/keyboard_holder" android:layout_width="match_parent" android:layout_height="wrap_content" + android:fitsSystemWindows="true" android:background="@color/you_keyboard_background_color">