From ded7159d3b8f6f32a4ad749270a4f9f8911d1706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Wed, 26 Jul 2023 08:29:04 +0200 Subject: [PATCH] Use BreakIterator to count characters to delete Since emoji characters take up multiple characters, this uses BreakIterator from android.icu to correctly determine length of a single Unicode character. This also fixes behavior for other Unicode characters that may be made up of multiple characters. --- .../keyboard/services/SimpleKeyboardIME.kt | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/keyboard/services/SimpleKeyboardIME.kt b/app/src/main/kotlin/com/simplemobiletools/keyboard/services/SimpleKeyboardIME.kt index 8e73c94..0e10ad8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/keyboard/services/SimpleKeyboardIME.kt +++ b/app/src/main/kotlin/com/simplemobiletools/keyboard/services/SimpleKeyboardIME.kt @@ -5,6 +5,8 @@ import android.content.SharedPreferences import android.graphics.drawable.Icon import android.graphics.drawable.LayerDrawable import android.graphics.drawable.RippleDrawable +import android.icu.text.BreakIterator +import android.icu.util.ULocale import android.inputmethodservice.InputMethodService import android.os.Build import android.os.Bundle @@ -27,6 +29,7 @@ import androidx.autofill.inline.common.ViewStyle import androidx.autofill.inline.v1.InlineSuggestionUi import androidx.core.graphics.drawable.toBitmap import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.commons.helpers.isNougatPlus import com.simplemobiletools.keyboard.R import com.simplemobiletools.keyboard.extensions.config import com.simplemobiletools.keyboard.extensions.getStrokeColor @@ -54,6 +57,7 @@ class SimpleKeyboardIME : InputMethodService(), OnKeyboardActionListener, Shared private var inputTypeClassVariation = TYPE_CLASS_TEXT private var enterKeyType = IME_ACTION_NONE private var switchToLetters = false + private var breakIterator: BreakIterator? = null override fun onInitializeInterface() { super.onInitializeInterface() @@ -84,6 +88,9 @@ class SimpleKeyboardIME : InputMethodService(), OnKeyboardActionListener, Shared keyboard = createNewKeyboard() keyboardView?.setKeyboard(keyboard!!) keyboardView?.setEditorInfo(attribute) + if (isNougatPlus()) { + breakIterator = BreakIterator.getCharacterInstance(ULocale.getDefault()) + } updateShiftKeyState() } @@ -150,7 +157,8 @@ class SimpleKeyboardIME : InputMethodService(), OnKeyboardActionListener, Shared MyKeyboard.KEYCODE_DELETE -> { val selectedText = inputConnection.getSelectedText(0) if (TextUtils.isEmpty(selectedText)) { - inputConnection.deleteSurroundingText(1, 0) + val count = getCountToDelete(inputConnection) + inputConnection.deleteSurroundingText(count, 0) } else { inputConnection.commitText("", 1) } @@ -260,6 +268,26 @@ class SimpleKeyboardIME : InputMethodService(), OnKeyboardActionListener, Shared } } + private fun getCountToDelete(inputConnection: InputConnection): Int { + if (breakIterator == null || !isNougatPlus()) { + return 1 + } + + val prevText = inputConnection.getTextBeforeCursor(8, 0) + + + if (!TextUtils.isEmpty(prevText)) { + return breakIterator?.let { + it.setText(prevText.toString()) + val end = it.last() + val start = it.previous() + (end - (if (start == BreakIterator.DONE) 0 else start)).coerceIn(0, prevText?.length) + } ?: 1 + } + + return 1 + } + override fun onActionUp() { if (switchToLetters) { // TODO: Change keyboardMode to enum class