aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/event/Combiner.java14
-rw-r--r--java/src/com/android/inputmethod/event/CombinerChain.java15
-rw-r--r--java/src/com/android/inputmethod/event/DeadKeyCombiner.java5
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java19
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java1
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java39
6 files changed, 57 insertions, 36 deletions
diff --git a/java/src/com/android/inputmethod/event/Combiner.java b/java/src/com/android/inputmethod/event/Combiner.java
index ab6b70c04..c3869a299 100644
--- a/java/src/com/android/inputmethod/event/Combiner.java
+++ b/java/src/com/android/inputmethod/event/Combiner.java
@@ -16,14 +16,22 @@
package com.android.inputmethod.event;
+import java.util.ArrayList;
+
/**
- * A generic interface for combiners.
+ * A generic interface for combiners. Combiners are objects that transform chains of input events
+ * into committable strings and manage feedback to show to the user on the combining state.
*/
public interface Combiner {
/**
- * Combine an event with the existing state and return the new event.
+ * Process an event, possibly combining it with the existing state and return the new event.
+ *
+ * If this event does not result in any new event getting passed down the chain, this method
+ * returns null. It may also modify the previous event list if appropriate.
+ *
+ * @param previousEvents the previous events in this composition.
* @param event the event to combine with the existing state.
* @return the resulting event.
*/
- Event combine(Event event);
+ Event processEvent(ArrayList<Event> previousEvents, Event event);
}
diff --git a/java/src/com/android/inputmethod/event/CombinerChain.java b/java/src/com/android/inputmethod/event/CombinerChain.java
index 1deaed68f..0e01c819a 100644
--- a/java/src/com/android/inputmethod/event/CombinerChain.java
+++ b/java/src/com/android/inputmethod/event/CombinerChain.java
@@ -51,4 +51,19 @@ public class CombinerChain {
// The dead key combiner is always active, and always first
mCombiners.add(new DeadKeyCombiner());
}
+
+ // Pass a new event through the whole chain.
+ public void processEvent(final ArrayList<Event> previousEvents, final Event newEvent) {
+ final ArrayList<Event> modifiablePreviousEvents = new ArrayList<Event>(previousEvents);
+ Event event = newEvent;
+ for (final Combiner combiner : mCombiners) {
+ // A combiner can never return more than one event; it can return several
+ // code points, but they should be encapsulated within one event.
+ event = combiner.processEvent(modifiablePreviousEvents, event);
+ if (null == event) {
+ // Combiners return null if they eat the event.
+ return;
+ }
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/event/DeadKeyCombiner.java b/java/src/com/android/inputmethod/event/DeadKeyCombiner.java
index ae8639713..f77ce6347 100644
--- a/java/src/com/android/inputmethod/event/DeadKeyCombiner.java
+++ b/java/src/com/android/inputmethod/event/DeadKeyCombiner.java
@@ -21,14 +21,17 @@ import android.view.KeyCharacterMap;
import com.android.inputmethod.latin.Constants;
+import java.util.ArrayList;
+
/**
* A combiner that handles dead keys.
*/
public class DeadKeyCombiner implements Combiner {
+ // TODO: make this a list of events instead
final StringBuilder mDeadSequence = new StringBuilder();
@Override
- public Event combine(final Event event) {
+ public Event processEvent(final ArrayList<Event> previousEvents, final Event event) {
if (null == event) return null; // Just in case some combiner is broken
if (TextUtils.isEmpty(mDeadSequence)) {
if (event.isDead()) {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index fc5c7f7ec..b6d477629 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -169,7 +169,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private int mDelayUpdateSuggestions;
private int mDelayUpdateShiftState;
- private long mDoubleSpacePeriodTimerStart;
public UIHandler(final LatinIME ownerInstance) {
super(ownerInstance);
@@ -283,10 +282,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), mDelayUpdateShiftState);
}
- public void cancelUpdateShiftState() {
- removeMessages(MSG_UPDATE_SHIFT_STATE);
- }
-
@UsedForTesting
public void removeAllMessages() {
for (int i = 0; i <= MSG_LAST; ++i) {
@@ -314,19 +309,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
obtainMessage(MSG_ON_END_BATCH_INPUT, suggestedWords).sendToTarget();
}
- public void startDoubleSpacePeriodTimer() {
- mDoubleSpacePeriodTimerStart = SystemClock.uptimeMillis();
- }
-
- public void cancelDoubleSpacePeriodTimer() {
- mDoubleSpacePeriodTimerStart = 0;
- }
-
- public boolean isAcceptingDoubleSpacePeriod() {
- return SystemClock.uptimeMillis() - mDoubleSpacePeriodTimerStart
- < getOwnerInstance().mSettings.getCurrent().mDoubleSpacePeriodTimeout;
- }
-
// Working variables for the following methods.
private boolean mIsOrientationChanging;
private boolean mPendingSuccessiveImsCallback;
@@ -882,7 +864,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
setNeutralSuggestionStrip();
mHandler.cancelUpdateSuggestionStrip();
- mHandler.cancelDoubleSpacePeriodTimer();
mainKeyboardView.setMainDictionaryAvailability(null != suggest
? suggest.mDictionaryFacilitator.hasMainDictionary() : false);
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 9e5d9205d..29382fea4 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -192,6 +192,7 @@ public final class WordComposer {
final int keyX = event.mX;
final int keyY = event.mY;
final int newIndex = size();
+ mCombinerChain.processEvent(mEvents, event);
mTypedWord.appendCodePoint(primaryCode);
mEvents.add(event);
refreshSize();
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 3c7e67693..8faf17584 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -95,6 +95,7 @@ public final class InputLogic {
// TODO: This boolean is persistent state and causes large side effects at unexpected times.
// Find a way to remove it for readability.
private boolean mIsAutoCorrectionIndicatorOn;
+ private long mDoubleSpacePeriodCountdownStart;
public InputLogic(final LatinIME latinIME,
final SuggestionStripViewAccessor suggestionStripViewAccessor) {
@@ -137,6 +138,7 @@ public final class InputLogic {
// In some cases (namely, after rotation of the device) editorInfo.initialSelStart is lying
// so we try using some heuristics to find out about these and fix them.
mConnection.tryFixLyingCursorPosition();
+ cancelDoubleSpacePeriodCountdown();
mInputLogicHandler = new InputLogicHandler(mLatinIME, this);
}
@@ -405,7 +407,7 @@ public final class InputLogic {
// TODO: Consolidate the double-space period timer, mLastKeyTime, and the space state.
if (event.mCodePoint != Constants.CODE_SPACE) {
- handler.cancelDoubleSpacePeriodTimer();
+ cancelDoubleSpacePeriodCountdown();
}
boolean didAutoCorrect = false;
@@ -846,7 +848,7 @@ public final class InputLogic {
if (Constants.CODE_SPACE == codePoint) {
if (inputTransaction.mSettingsValues.isSuggestionsRequested()) {
- if (maybeDoubleSpacePeriod(inputTransaction.mSettingsValues, handler)) {
+ if (maybeDoubleSpacePeriod(inputTransaction)) {
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
mSpaceState = SpaceState.DOUBLE;
} else if (!mSuggestedWords.isPunctuationSuggestions()) {
@@ -854,7 +856,7 @@ public final class InputLogic {
}
}
- handler.startDoubleSpacePeriodTimer();
+ startDoubleSpacePeriodCountdown(inputTransaction);
handler.postUpdateSuggestionStrip();
} else {
if (swapWeakSpace) {
@@ -951,7 +953,7 @@ public final class InputLogic {
return;
}
if (SpaceState.DOUBLE == inputTransaction.mSpaceState) {
- handler.cancelDoubleSpacePeriodTimer();
+ cancelDoubleSpacePeriodCountdown();
if (mConnection.revertDoubleSpacePeriod()) {
// No need to reset mSpaceState, it has already be done (that's why we
// receive it as a parameter)
@@ -1099,6 +1101,19 @@ public final class InputLogic {
return false;
}
+ public void startDoubleSpacePeriodCountdown(final InputTransaction inputTransaction) {
+ mDoubleSpacePeriodCountdownStart = inputTransaction.mTimestamp;
+ }
+
+ public void cancelDoubleSpacePeriodCountdown() {
+ mDoubleSpacePeriodCountdownStart = 0;
+ }
+
+ public boolean isDoubleSpacePeriodCountdownActive(final InputTransaction inputTransaction) {
+ return inputTransaction.mTimestamp - mDoubleSpacePeriodCountdownStart
+ < inputTransaction.mSettingsValues.mDoubleSpacePeriodTimeout;
+ }
+
/**
* Apply the double-space-to-period transformation if applicable.
*
@@ -1111,14 +1126,12 @@ public final class InputLogic {
* method applies the transformation and returns true. Otherwise, it does nothing and
* returns false.
*
- * @param settingsValues the current values of the settings.
+ * @param inputTransaction The transaction in progress.
* @return true if we applied the double-space-to-period transformation, false otherwise.
*/
- private boolean maybeDoubleSpacePeriod(final SettingsValues settingsValues,
- // TODO: remove this argument
- final LatinIME.UIHandler handler) {
- if (!settingsValues.mUseDoubleSpacePeriod) return false;
- if (!handler.isAcceptingDoubleSpacePeriod()) return false;
+ private boolean maybeDoubleSpacePeriod(final InputTransaction inputTransaction) {
+ if (!inputTransaction.mSettingsValues.mUseDoubleSpacePeriod) return false;
+ if (!isDoubleSpacePeriodCountdownActive(inputTransaction)) return false;
// We only do this when we see two spaces and an accepted code point before the cursor.
// The code point may be a surrogate pair but the two spaces may not, so we need 4 chars.
final CharSequence lastThree = mConnection.getTextBeforeCursor(4, 0);
@@ -1134,10 +1147,10 @@ public final class InputLogic {
Character.isSurrogatePair(lastThree.charAt(0), lastThree.charAt(1)) ?
Character.codePointAt(lastThree, 0) : lastThree.charAt(length - 3);
if (canBeFollowedByDoubleSpacePeriod(firstCodePoint)) {
- handler.cancelDoubleSpacePeriodTimer();
+ cancelDoubleSpacePeriodCountdown();
mConnection.deleteSurroundingText(2, 0);
- final String textToInsert =
- settingsValues.mSpacingAndPunctuations.mSentenceSeparatorAndSpace;
+ final String textToInsert = inputTransaction.mSettingsValues.mSpacingAndPunctuations
+ .mSentenceSeparatorAndSpace;
mConnection.commitText(textToInsert, 1);
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.latinIME_maybeDoubleSpacePeriod(textToInsert,