From c7cf1ea06731356065eb9c1872b972b91b9af9b0 Mon Sep 17 00:00:00 2001 From: 4di-hello <4di-hello@users.noreply.github.com> Date: Mon, 26 Oct 2026 09:20:49 +0100 Subject: [PATCH] Shift on the typed word: keep it a typed word Changing the capitalization with shift marked the word as taken from existing text. The typed word then disappeared from the suggestions and others like a split "Rad Umfang" took its place. Upper case letters also lost their key positions. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01VuiaMhLXwhErf9shhrr1uD --- .../java/helium314/keyboard/latin/WordComposer.kt | 5 +++-- .../helium314/keyboard/latin/inputlogic/InputLogic.kt | 6 +++++- .../java/helium314/keyboard/latin/InputLogicTest.kt | 11 +++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/WordComposer.kt b/app/src/main/java/helium314/keyboard/latin/WordComposer.kt index f62bab7ff..5c7461efe 100644 --- a/app/src/main/java/helium314/keyboard/latin/WordComposer.kt +++ b/app/src/main/java/helium314/keyboard/latin/WordComposer.kt @@ -303,7 +303,8 @@ class WordComposer { * @param codePoints the code points to set as the composing word. * @param coordinates the x, y coordinates of the key in the CoordinateUtils format */ - fun setComposingWord(codePoints: IntArray, coordinates: IntArray) { + /** [isResumed]: the word comes from existing text (no auto-correction, the typed word is not added to the suggestions) */ + fun setComposingWord(codePoints: IntArray, coordinates: IntArray, isResumed: Boolean = true) { reset() for (i in codePoints.indices) { @@ -317,7 +318,7 @@ class WordComposer { applyProcessedEvent(processedEvent) } - mIsResumed = true + mIsResumed = isResumed } /** diff --git a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.kt b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.kt index a4efb2d35..924ab9d39 100644 --- a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.kt +++ b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.kt @@ -1985,9 +1985,13 @@ class InputLogic( return false } val codePoints = StringUtils.toCodePointArray(replacement) + // keys are found by their lower case letter, upper case letters would have no position + val coordinates = mLatinIME.getCoordinatesForCurrentKeyboard(codePoints.map { Character.toLowerCase(it) }.toIntArray()) + // still the typed word, not one from existing text: suggestions and auto-correction as before the shift + val wasResumed = mWordComposer.isResumed() mConnection.beginBatchEdit() try { - mWordComposer.setComposingWord(codePoints, mLatinIME.getCoordinatesForCurrentKeyboard(codePoints)) + mWordComposer.setComposingWord(codePoints, coordinates, isResumed = wasResumed) setComposingTextInternal(replacement, 1) } finally { mConnection.endBatchEdit() diff --git a/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt b/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt index ee03e476c..6a6043e75 100644 --- a/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt +++ b/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt @@ -386,6 +386,17 @@ class InputLogicTest { assertEquals("hello ", text) } + @Test fun `shift on a typed word keeps it a typed word`() { + reset() + latinIME.prefs().edit { putBoolean(Settings.PREF_SHIFT_RECAPITALIZES_WORD, true) } + chainInput("radumfang") + shiftTap() + assertEquals("Radumfang", composingText) + // not treated like a word from existing text, which would change suggestions and auto-correction + assertEquals(false, composer.isResumed()) + assertEquals("Radumfang", composer.getTypedWord()) + } + @Test fun `caps lock from shift on a word ends with the word`() { reset() latinIME.prefs().edit { putBoolean(Settings.PREF_SHIFT_RECAPITALIZES_WORD, true) }