Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions app/src/main/java/helium314/keyboard/latin/RichInputConnection.kt
Original file line number Diff line number Diff line change
Expand Up @@ -403,14 +403,26 @@ class RichInputConnection(private val mParent: InputMethodService) : PrivateComm
}

val text = if (InputTypeUtils.isWebEditor(mParent.currentInputEditorInfo)) {
getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE, 0)?.toString() ?: ""
getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE, 0)?.toString()
} else {
if (mCommittedTextBeforeComposingText.isEmpty() && mExpectedSelStart != 0) {
if (!reloadTextCache()) {
Log.d(TAG, "Setting caps mode with default fallback (text cache unavailable).")
}
if (mCommittedTextBeforeComposingText.isEmpty() && mExpectedSelStart != 0 && !reloadTextCache()) {
null
} else {
mCommittedTextBeforeComposingText.toString()
}
}

if (text == null || (text.isEmpty() && mExpectedSelStart != 0)) {
// Unavailable context is not evidence of a sentence boundary.
val requestedModes = inputType and (TextUtils.CAP_MODE_CHARACTERS or
TextUtils.CAP_MODE_WORDS or TextUtils.CAP_MODE_SENTENCES)
val knownModes = (TextUtils.CAP_MODE_CHARACTERS or
if (hasSpaceBefore) TextUtils.CAP_MODE_WORDS else 0) and requestedModes
if (requestedModes and (TextUtils.CAP_MODE_WORDS or TextUtils.CAP_MODE_SENTENCES) == 0) {
return knownModes
}
mCommittedTextBeforeComposingText.toString()
Log.d(TAG, "Getting caps mode from editor (surrounding text unavailable).")
return knownModes or ((mIC?.getCursorCapsMode(requestedModes) ?: 0) and requestedModes)
}

return CapsModeUtils.getCapsMode(
Expand Down
45 changes: 43 additions & 2 deletions app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.text.InputType
import android.text.TextUtils
import android.view.KeyEvent
import android.view.inputmethod.*
import androidx.core.content.edit
Expand Down Expand Up @@ -46,6 +47,8 @@ import kotlin.streams.asSequence
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue

@RunWith(RobolectricTestRunner::class)
@Config(shadows = [
Expand Down Expand Up @@ -89,6 +92,36 @@ class InputLogicTest {
assertEquals("", composingText)
}

@Test fun `native missing context does not enable implicit sentence auto caps`() {
assertMissingContextDoesNotEnableAutoCaps(InputType.TYPE_CLASS_TEXT)
}

@Test fun `web missing context does not enable implicit sentence auto caps`() {
assertMissingContextDoesNotEnableAutoCaps(
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT
)
}

private fun assertMissingContextDoesNotEnableAutoCaps(inputType: Int) {
reset()
currentInputType = inputType
setText("hello there")
assertTrue(settingsValues.mAutoCap)
assertFalse(settingsValues.mForceAutoCaps)
assertEquals(0, currentInputType and TextUtils.CAP_MODE_SENTENCES)
textBeforeCursorAvailable = false
assertFalse(connection.resetCachesUponCursorMoveAndReturnSuccess(selectionStart, selectionEnd, false))
assertEquals("hello there", text)
assertEquals(11, selectionStart)
assertEquals(-1, connection.expectedSelectionStart)
assertEquals(0, inputLogic.getCurrentAutoCapsState(settingsValues))
assertEquals(TextUtils.CAP_MODE_SENTENCES, lastCursorCapsRequest)

textBeforeCursorAvailable = true
setText("Hello. ")
assertEquals(TextUtils.CAP_MODE_SENTENCES, inputLogic.getCurrentAutoCapsState(settingsValues))
}

@Test fun `english space-separated typing keeps composing word`() {
reset()
chainInput("hello")
Expand Down Expand Up @@ -1265,6 +1298,8 @@ class InputLogicTest {
text = ""
batchEdit = 0
currentInputType = InputType.TYPE_CLASS_TEXT
textBeforeCursorAvailable = true
lastCursorCapsRequest = null
lastAddedWord = ""
lastNgramContext = ""
addedWords.clear()
Expand Down Expand Up @@ -1506,6 +1541,8 @@ class InputLogicTest {
}

private var currentInputType = InputType.TYPE_CLASS_TEXT
private var textBeforeCursorAvailable = true
private var lastCursorCapsRequest: Int? = null
private var currentScript = ScriptUtils.SCRIPT_LATIN
private val messages = mutableListOf<Message>() // for latinIME / ShadowInputMethodService
private val delayedMessages = mutableListOf<Message>() // for latinIME / ShadowInputMethodService
Expand All @@ -1530,7 +1567,8 @@ private val composingText get() = if (composingStart == -1 || composingEnd == -1
private val ic = object : InputConnection {
// pretty clear (though this may be slow depending on the editor)
// bad return value here is likely the cause for that weird bug improved/fixed by fixIncorrectLength
override fun getTextBeforeCursor(p0: Int, p1: Int): CharSequence = textBeforeCursor.take(p0)
override fun getTextBeforeCursor(p0: Int, p1: Int): CharSequence? =
if (textBeforeCursorAvailable) textBeforeCursor.take(p0) else null
// pretty clear (though this may be slow depending on the editor)
override fun getTextAfterCursor(p0: Int, p1: Int): CharSequence = textAfterCursor.take(p0)
// pretty clear
Expand Down Expand Up @@ -1674,8 +1712,11 @@ private val ic = object : InputConnection {
}
// only effect is flashing, so whatever...
override fun commitCorrection(p0: CorrectionInfo?): Boolean = true
override fun getCursorCapsMode(p0: Int): Int {
lastCursorCapsRequest = p0
return TextUtils.getCapsMode(text, selectionStart, p0)
}
// implement only when necessary
override fun getCursorCapsMode(p0: Int): Int = TODO("Not yet implemented")
override fun deleteSurroundingTextInCodePoints(p0: Int, p1: Int): Boolean = TODO("Not yet implemented")
override fun commitCompletion(p0: CompletionInfo?): Boolean = TODO("Not yet implemented")
override fun performEditorAction(p0: Int): Boolean = true
Expand Down
Loading
Loading