From 29b201cd00a3d42e3431d5b3bcd125a3dbe8fbab Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Wed, 13 Nov 2019 15:43:23 +0700 Subject: [PATCH] fix(android): Still trying to adjust the cursor on Firefox * Also updated CharSequenceUtilTest to reflect expected rota keyboard output --- .../java/com/tavultesoft/kmea/KMManager.java | 45 +++++++++------- .../kmea/util/CharSequenceUtil.java | 6 ++- .../kmea/util/CharSequenceUtilTest.java | 53 +++++++++++++++---- 3 files changed, 73 insertions(+), 31 deletions(-) diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMManager.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMManager.java index 250c48960b..37bf3ebdc0 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMManager.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMManager.java @@ -321,12 +321,15 @@ public final class KMManager { int originalBufferLength = dn*2 + 16; // characters CharSequence charsBackup = ic.getTextBeforeCursor(originalBufferLength, 0); - if (Character.isHighSurrogate(charsBackup.charAt(charsBackup.length()-1))) { // Firefox sometimes splits a surrogate pair so move the cursor back + String origChars = charsBackup.toString(); + ic.commitText("", -1); - Log.d(TAG, "adjust trimming high surrogate pair from charsBackup: " + charsBackup.toString()); charsBackup = ic.getTextBeforeCursor(originalBufferLength, 0); + Log.d(TAG, "adjusting high surrogate pair from charsBackup was: " + origChars + + ", now: " + charsBackup.toString()); + } int lastIndex = charsBackup.length()-1; @@ -348,6 +351,7 @@ public final class KMManager { if (charsToRestore.length() > 0) { // Restore expectedChars that Chromium deleted, and advance the cursor by expectedChars.length() ic.commitText(charsToRestore, charsToRestore.length()); + Log.d(TAG, "performLeftDeletions commitText(" + charsToRestore.toString() + ")"); } } @@ -2098,31 +2102,33 @@ public final class KMManager { if (s.length() > 0) { SystemKeyboardShouldIgnoreSelectionChange = true; ic.commitText(s, s.length()); + Log.d(TAG, "adjusting commitText s:" + s.toString()); CharSequence check = ic.getTextBeforeCursor(1, 0); - if (check != null && Character.isHighSurrogate(check.charAt(0))) { - ic.commitText("", -1); - } - // Compensate for surrogate pairs and combining marks - /* - int adjustedLength = s.length(); - for(char c: s.toCharArray()) { - if (Character.isLowSurrogate(c)) { - adjustedLength--; - } else if (Character.getType(c) == Character.NON_SPACING_MARK || - Character.getType(c) == Character.COMBINING_SPACING_MARK) { - adjustedLength -= 2; - } - } - ic.commitText(s, adjustedLength); - */ - //String userAgent = System.getProperty("http.agent"); + if (check != null && Character.isHighSurrogate(check.charAt(0))) { + // Firefox sometimes splits a surrogate pair so move the cursor back + String origChars = check.toString(); + + ic.commitText("", -1); + check = ic.getTextBeforeCursor(1, 0); + Log.d(TAG, "adjusting high surrogate pair from check was: " + origChars + + ", now: " + check.toString()); + } + CharSequence charsBefore = ic.getTextBeforeCursor(s.length()*2, 0); int move = CharSequenceUtil.adjustCursorPosition(charsBefore, s); if (move > 0) { Log.d(TAG, "adjusting cursor charsBefore: " + charsBefore.toString() + ", s: " + s + ", move: " + move); ic.commitText("", -move); + + // Do another check for Firefox? + charsBefore = ic.getTextBeforeCursor(s.length()*2, 0); + move = CharSequenceUtil.adjustCursorPosition(charsBefore, s); + if (move > 0) { + Log.d(TAG, "adjusting cursor 2 charsBefore: " + charsBefore.toString() + ", s: " + s + ", move: " + move); + ic.commitText("", -move); + } } } @@ -2136,5 +2142,4 @@ public final class KMManager { IMService.getCurrentInputConnection().sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keyEventCode)); } } - } diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/util/CharSequenceUtil.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/util/CharSequenceUtil.java index 694c765ef9..1045883c31 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/util/CharSequenceUtil.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/util/CharSequenceUtil.java @@ -59,6 +59,9 @@ public final class CharSequenceUtil { } } + Log.d(TAG, "adjusting expectedChars: " + expectedChars.toString() + + ", currentContext: " + currentContext.toString() + + ", charsToRestore: " + charsToRestore.toString()); return charsToRestore; } catch (Exception e) { Log.e(TAG, "Error in restoreChars: " + e); @@ -77,6 +80,7 @@ public final class CharSequenceUtil { return 0; } + int numPairs = countSurrogatePairs(charsBefore, s.length()); int _expected_start_index = charsBefore.length() - s.length(); int _move = 0; while (_move < _expected_start_index) { @@ -91,4 +95,4 @@ public final class CharSequenceUtil { return _move; } -} \ No newline at end of file +} diff --git a/android/KMEA/app/src/test/java/com/tavultesoft/kmea/util/CharSequenceUtilTest.java b/android/KMEA/app/src/test/java/com/tavultesoft/kmea/util/CharSequenceUtilTest.java index 80627ddede..3dd2e69b31 100644 --- a/android/KMEA/app/src/test/java/com/tavultesoft/kmea/util/CharSequenceUtilTest.java +++ b/android/KMEA/app/src/test/java/com/tavultesoft/kmea/util/CharSequenceUtilTest.java @@ -10,7 +10,9 @@ import com.tavultesoft.kmea.util.CharSequenceUtil; @RunWith(RobolectricTestRunner.class) public class CharSequenceUtilTest { // Smiley emoji U+1F600 = D800 DC3D - private final String SMILEY = "\uD800\uDC3D"; + private final String SMILEY_HIGH_SURROGATE_PAIR = "\uD800"; + private final String SMILEY_LOW_SURROGATE_PAIR = "\uDC3D"; + private final String SMILEY = SMILEY_HIGH_SURROGATE_PAIR + SMILEY_LOW_SURROGATE_PAIR; // Winking emoji U+1F609 = D800 DC3C private final String WINK = "\uD800\uDC3C"; @@ -21,7 +23,7 @@ public class CharSequenceUtilTest { private final String P_COMPOSING_DOT_ABOVE = "p" + COMPOSING_DOT_ABOVE; private final String P_COMPOSING_CIRCUMFLEX_ACCENT = "p" + COMPOSING_CIRCUMFLEX_ACCENT; - // Section countSurrogaetPairs Tests + //region countSurrogatePairs tests @Test public void test_countSurrogatePairs_invalid_input() { @@ -64,10 +66,14 @@ public class CharSequenceUtilTest { public void test_countSurrogatePairs_one_pair() { // Test for scenarios that expect 1 surrogate pair - CharSequence sequence = "Have A " + SMILEY; + CharSequence sequence = SMILEY_LOW_SURROGATE_PAIR; int numPairs = CharSequenceUtil.countSurrogatePairs(sequence, 1); Assert.assertEquals(1, numPairs); + sequence = "Have A " + SMILEY; + numPairs = CharSequenceUtil.countSurrogatePairs(sequence, 1); + Assert.assertEquals(1, numPairs); + numPairs = CharSequenceUtil.countSurrogatePairs(sequence, 2); Assert.assertEquals(1, numPairs); @@ -94,6 +100,9 @@ public class CharSequenceUtilTest { Assert.assertEquals(2, numPairs); } + //endregion + + // region restoreChars tests @Test public void test_restoreChars_invalid_input() { @@ -118,7 +127,7 @@ public class CharSequenceUtilTest { @Test public void test_restoreChars_split_surrogate_pair() { CharSequence expectedChars = "o" + P_COMPOSING_CIRCUMFLEX_ACCENT + P_COMPOSING_CIRCUMFLEX_ACCENT + WINK + "p"; - CharSequence currentContext = P_COMPOSING_CIRCUMFLEX_ACCENT + "\uD800"; + CharSequence currentContext = P_COMPOSING_CIRCUMFLEX_ACCENT + SMILEY_HIGH_SURROGATE_PAIR; CharSequence charsToRestore = CharSequenceUtil.restoreChars(expectedChars, currentContext); Assert.assertEquals("\uDC3C" + "p", charsToRestore); } @@ -141,6 +150,10 @@ public class CharSequenceUtilTest { Assert.assertEquals("p" + COMPOSING_CIRCUMFLEX_ACCENT + "p" + COMPOSING_CIRCUMFLEX_ACCENT, charsToRestore); } + //endregion + + // region adjustCursorPosition tests + @Test public void test_adjustCursorPosition_invalid_input() { CharSequence sequence = null; @@ -155,17 +168,37 @@ public class CharSequenceUtilTest { } @Test - public void test_adjustCursorPosition_move_3() { - CharSequence charsBefore = "o" + P_COMPOSING_CIRCUMFLEX_ACCENT + P_COMPOSING_CIRCUMFLEX_ACCENT + - SMILEY + P_COMPOSING_DOT_ABOVE; - String s = P_COMPOSING_CIRCUMFLEX_ACCENT + P_COMPOSING_CIRCUMFLEX_ACCENT; + public void test_adjustCursorPosition_split_surrogate_pair() { + CharSequence sequence = SMILEY_LOW_SURROGATE_PAIR + P_COMPOSING_CIRCUMFLEX_ACCENT + SMILEY_HIGH_SURROGATE_PAIR; + String s = P_COMPOSING_CIRCUMFLEX_ACCENT; + int move = CharSequenceUtil.adjustCursorPosition(sequence, s); + Assert.assertEquals(1, move); + } + @Test + public void test_adjustCursorPosition_move() { + CharSequence charsBefore = P_COMPOSING_DOT_ABOVE + SMILEY; + String s = P_COMPOSING_DOT_ABOVE; int move = CharSequenceUtil.adjustCursorPosition(charsBefore, s); + Assert.assertEquals(2, move); + + charsBefore = P_COMPOSING_CIRCUMFLEX_ACCENT + SMILEY; + s = P_COMPOSING_CIRCUMFLEX_ACCENT; + move = CharSequenceUtil.adjustCursorPosition(charsBefore, s); + Assert.assertEquals(2, move); + + charsBefore = P_COMPOSING_CIRCUMFLEX_ACCENT + P_COMPOSING_CIRCUMFLEX_ACCENT + SMILEY + P_COMPOSING_DOT_ABOVE; + s = P_COMPOSING_CIRCUMFLEX_ACCENT + P_COMPOSING_CIRCUMFLEX_ACCENT; + move = CharSequenceUtil.adjustCursorPosition(charsBefore, s); Assert.assertEquals(4, move); - charsBefore = "g" + P_COMPOSING_CIRCUMFLEX_ACCENT + P_COMPOSING_CIRCUMFLEX_ACCENT + "lyf"; + // Firefox behavior + charsBefore = "o" + P_COMPOSING_CIRCUMFLEX_ACCENT + P_COMPOSING_CIRCUMFLEX_ACCENT + SMILEY + "p"; + s = P_COMPOSING_CIRCUMFLEX_ACCENT + P_COMPOSING_CIRCUMFLEX_ACCENT; move = CharSequenceUtil.adjustCursorPosition(charsBefore, s); Assert.assertEquals(3, move); - } + + //endregion + }