From 91a938228afae78ec785e374e515356af3528092 Mon Sep 17 00:00:00 2001 From: LeanBitLab <245915690+LeanBitLab@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:33:11 +0000 Subject: [PATCH] fix: prevent auto-caps errors with unavailable text cache When the keyboard connects to a new or transient input field, the text cache may be temporarily unavailable. Previously, this caused the caps mode to default to CAP_MODE_OFF, breaking auto-capitalization in fast switching or autofill scenarios. This commit updates `RichInputConnection.getCursorCapsMode` to use `EditorInfo.initialCapsMode` as a fallback when `getTextBeforeCursor` or `reloadTextCache` fails, properly inheriting the app's requested capitalization. Also fixes a batch edit nesting error log spam and ensures that caps mode is explicitly reset for transient `TYPE_NULL` focus events to prevent stale state leaking across apps. --- .../main/java/helium314/keyboard/latin/LatinIME.kt | 9 +++++++-- .../helium314/keyboard/latin/RichInputConnection.kt | 12 +++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/LatinIME.kt b/app/src/main/java/helium314/keyboard/latin/LatinIME.kt index ee35b1f67..12fa5e2f7 100644 --- a/app/src/main/java/helium314/keyboard/latin/LatinIME.kt +++ b/app/src/main/java/helium314/keyboard/latin/LatinIME.kt @@ -831,8 +831,13 @@ class LatinIME : InputMethodService(), if (needToCallLoadKeyboardLater) switcher.saveKeyboardState() } else if (restarting) { if (!switcher.isSecondaryViewShowing) { - switcher.resetKeyboardStateToAlphabet(currentAutoCapsState, currentRecapitalizeState) - switcher.requestUpdatingShiftState(currentAutoCapsState, currentRecapitalizeState) + if (isTransientFocusTypeNull(editorInfo)) { + switcher.resetKeyboardStateToAlphabet(Constants.TextUtils.CAP_MODE_OFF, currentRecapitalizeState) + switcher.requestUpdatingShiftState(Constants.TextUtils.CAP_MODE_OFF, currentRecapitalizeState) + } else { + switcher.resetKeyboardStateToAlphabet(currentAutoCapsState, currentRecapitalizeState) + switcher.requestUpdatingShiftState(currentAutoCapsState, currentRecapitalizeState) + } } } diff --git a/app/src/main/java/helium314/keyboard/latin/RichInputConnection.kt b/app/src/main/java/helium314/keyboard/latin/RichInputConnection.kt index 5d98df1cc..f88a193a8 100644 --- a/app/src/main/java/helium314/keyboard/latin/RichInputConnection.kt +++ b/app/src/main/java/helium314/keyboard/latin/RichInputConnection.kt @@ -161,7 +161,6 @@ class RichInputConnection(private val mParent: InputMethodService) : PrivateComm fun endBatchEdit() { if (mNestLevel <= 0) { - Log.e(TAG, "Batch edit not in progress!") mNestLevel = 0 return } @@ -447,12 +446,19 @@ class RichInputConnection(private val mParent: InputMethodService) : PrivateComm return TextUtils.CAP_MODE_CHARACTERS and inputType } - val text = if (InputTypeUtils.isWebEditor(mParent.currentInputEditorInfo)) { - getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE, 0)?.toString() ?: "" + val ei = mParent.currentInputEditorInfo + val text = if (InputTypeUtils.isWebEditor(ei)) { + val t = getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE, 0) + if (t == null) { + Log.d(TAG, "Setting caps mode with default fallback (text cache unavailable).") + return ei?.initialCapsMode ?: Constants.TextUtils.CAP_MODE_OFF + } + t.toString() } else { if (mCommittedTextBeforeComposingText.isEmpty() && mExpectedSelStart != 0) { if (!reloadTextCache()) { Log.d(TAG, "Setting caps mode with default fallback (text cache unavailable).") + return ei?.initialCapsMode ?: Constants.TextUtils.CAP_MODE_OFF } } mCommittedTextBeforeComposingText.toString()