From ffe7d81ebc435f9998c2c61b8f07a01099b3d284 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Wed, 19 Jul 2023 17:05:53 +0200 Subject: [PATCH] improve emoji deletion --- README.md | 1 + .../inputmethod/keyboard/KeyboardView.java | 12 +----- .../inputmethod/latin/common/StringUtils.java | 20 ++++++++++ .../latin/inputlogic/InputLogic.java | 38 +++++++++++-------- 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index cce02823f..ef97b3079 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Changes: * Re-arranged comma-long-press-menu, https://github.com/Helium314/openboard/pull/7 * Make Bengali spell check work, https://github.com/Helium314/openboard/pull/11 * Fix azerty layout in landscape mode on tablets, https://github.com/openboard-team/openboard/pull/791 +* Improve issues with emoji deletion (still happens with delete gesture), https://github.com/Helium314/openboard/issues/22 Plan / to do: * ~upgrade dependencies~ diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/KeyboardView.java b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/KeyboardView.java index 0f7be32a5..aaaa6bf93 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/KeyboardView.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/KeyboardView.java @@ -40,6 +40,7 @@ import org.dslul.openboard.inputmethod.keyboard.internal.KeyDrawParams; import org.dslul.openboard.inputmethod.keyboard.internal.KeyVisualAttributes; import org.dslul.openboard.inputmethod.latin.R; import org.dslul.openboard.inputmethod.latin.common.Constants; +import org.dslul.openboard.inputmethod.latin.common.StringUtils; import org.dslul.openboard.inputmethod.latin.settings.Settings; import org.dslul.openboard.inputmethod.latin.settings.SettingsValues; import org.dslul.openboard.inputmethod.latin.suggestions.MoreSuggestionsView; @@ -464,7 +465,7 @@ public class KeyboardView extends View { // set key color only if not in emoji keyboard range if (keyboard != null && (this.getClass() == MoreSuggestionsView.class ? - !containsEmoji(key.getLabel()) : // doesn't contain emoji (all can happen in MoreSuggestionsView) + !StringUtils.probablyContainsEmoji(key.getLabel()) : // doesn't contain emoji (all can happen in MoreSuggestionsView) (keyboard.mId.mElementId < 10 || keyboard.mId.mElementId > 26) // not showing emoji keyboard (no emojis visible on main keyboard otherwise) )) paint.setColorFilter(keyTextColorFilter); @@ -559,15 +560,6 @@ public class KeyboardView extends View { } } - private static boolean containsEmoji(String s) { - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (!(c <= 0xD7FF || (c >= 0xE000 && c <= 0xFFFD) || (c >= 0x10000 && c <= 0x10FFFF))) - return true; - } - return false; - } - // Draw popup hint "..." at the bottom right corner of the key. protected void drawKeyPopupHint(@Nonnull final Key key, @Nonnull final Canvas canvas, @Nonnull final Paint paint, @Nonnull final KeyDrawParams params) { diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/common/StringUtils.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/common/StringUtils.java index acfc6896f..5ad05c1ce 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/common/StringUtils.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/common/StringUtils.java @@ -711,4 +711,24 @@ public final class StringUtils { } return false; } + + public static boolean probablyContainsEmoji(String s) { + int offset = 0; + int length = s.length(); + while (offset < length) { + int c = Character.codePointAt(s, offset); + if (probablyIsEmojiCodePoint(c)) + return true; + offset += Character.charCount(c); + } + return false; + } + + // seemingly arbitrary ranges taken from "somewhere on the internet" + public static boolean probablyIsEmojiCodePoint(int c) { + return (0x200D <= c && c <= 0x3299) // ?? + || (0x1F004 <= c && c <= 0x1F251) // ?? + || (0x1F300 <= c && c <= 0x1FFFF) // ?? + || c == 0xFE0F; // variation selector emoji with color + } } diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/inputlogic/InputLogic.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/inputlogic/InputLogic.java index 3f8d94cb1..cb1b0857d 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/inputlogic/InputLogic.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/inputlogic/InputLogic.java @@ -1187,24 +1187,30 @@ public final class InputLogic { } final int lengthToDelete = Character.isSupplementaryCodePoint(codePointBeforeCursor) ? 2 : 1; - mConnection.deleteTextBeforeCursor(lengthToDelete); - int totalDeletedLength = lengthToDelete; - if (mDeleteCount > Constants.DELETE_ACCELERATE_AT) { - // If this is an accelerated (i.e., double) deletion, then we need to - // consider unlearning here because we may have already reached - // the previous word, and will lose it after next deletion. - hasUnlearnedWordBeingDeleted |= unlearnWordBeingDeleted( - inputTransaction.getMSettingsValues(), currentKeyboardScriptId); - final int codePointBeforeCursorToDeleteAgain = - mConnection.getCodePointBeforeCursor(); - if (codePointBeforeCursorToDeleteAgain != Constants.NOT_A_CODE) { - final int lengthToDeleteAgain = Character.isSupplementaryCodePoint( - codePointBeforeCursorToDeleteAgain) ? 2 : 1; - mConnection.deleteTextBeforeCursor(lengthToDeleteAgain); - totalDeletedLength += lengthToDeleteAgain; + if (StringUtils.probablyIsEmojiCodePoint(codePointBeforeCursor)) { + // emoji length varies, so we'd need to find out length to delete correctly + // this is not optimal, but a reasonable workaround for issues when trying to delete emojis + sendDownUpKeyEvent(KeyEvent.KEYCODE_DEL); + } else { + mConnection.deleteTextBeforeCursor(lengthToDelete); + int totalDeletedLength = lengthToDelete; + if (mDeleteCount > Constants.DELETE_ACCELERATE_AT) { + // If this is an accelerated (i.e., double) deletion, then we need to + // consider unlearning here because we may have already reached + // the previous word, and will lose it after next deletion. + hasUnlearnedWordBeingDeleted |= unlearnWordBeingDeleted( + inputTransaction.getMSettingsValues(), currentKeyboardScriptId); + final int codePointBeforeCursorToDeleteAgain = + mConnection.getCodePointBeforeCursor(); + if (codePointBeforeCursorToDeleteAgain != Constants.NOT_A_CODE) { + final int lengthToDeleteAgain = Character.isSupplementaryCodePoint( + codePointBeforeCursorToDeleteAgain) ? 2 : 1; + mConnection.deleteTextBeforeCursor(lengthToDeleteAgain); + totalDeletedLength += lengthToDeleteAgain; + } } + StatsUtils.onBackspacePressed(totalDeletedLength); } - StatsUtils.onBackspacePressed(totalDeletedLength); } } if (!hasUnlearnedWordBeingDeleted) {