Loading java/src/com/android/inputmethod/event/CombinerChain.java +14 −4 Original line number Diff line number Diff line Loading @@ -82,6 +82,13 @@ public class CombinerChain { } } private void updateStateFeedback() { mStateFeedback.clear(); for (int i = mCombiners.size() - 1; i >= 0; --i) { mStateFeedback.append(mCombiners.get(i).getCombiningStateFeedback()); } } /** * Process an event through the combining chain, and return a processed event to apply. * @param previousEvents the list of previous events in this composition Loading @@ -97,7 +104,13 @@ public class CombinerChain { // 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 (event.isConsumed()) { // If the event is consumed, then we don't pass it to subsequent combiners: // they should not see it at all. break; } } updateStateFeedback(); return event; } Loading @@ -121,10 +134,7 @@ public class CombinerChain { } } } mStateFeedback.clear(); for (int i = mCombiners.size() - 1; i >= 0; --i) { mStateFeedback.append(mCombiners.get(i).getCombiningStateFeedback()); } updateStateFeedback(); } /** Loading java/src/com/android/inputmethod/event/DeadKeyCombiner.java +7 −1 Original line number Diff line number Diff line Loading @@ -36,10 +36,16 @@ public class DeadKeyCombiner implements Combiner { @Nonnull public Event processEvent(final ArrayList<Event> previousEvents, final Event event) { if (TextUtils.isEmpty(mDeadSequence)) { // No dead char is currently being tracked: this is the most common case. if (event.isDead()) { // The event was a dead key. Start tracking it. mDeadSequence.appendCodePoint(event.mCodePoint); } return Event.createConsumedEvent(event); } // Regular keystroke when not keeping track of a dead key. Simply said, there are // no dead keys at all in the current input, so this combiner has nothing to do and // simply returns the event as is. The majority of events will go through this path. return event; } else { // TODO: Allow combining for several dead chars rather than only the first one. // The framework doesn't know how to do this now. Loading java/src/com/android/inputmethod/event/Event.java +4 −0 Original line number Diff line number Diff line Loading @@ -227,6 +227,7 @@ public class Event { * @return an identical event marked as consumed. */ public static Event createConsumedEvent(final Event source) { // A consumed event should not input any text at all, so we pass the empty string as text. return new Event(source.mEventType, source.mText, source.mCodePoint, source.mKeyCode, source.mX, source.mY, source.mSuggestedWordInfo, source.mFlags | FLAG_CONSUMED, source.mNextEvent); Loading Loading @@ -267,6 +268,9 @@ public class Event { } public CharSequence getTextToCommit() { if (isConsumed()) { return ""; // A consumed event should input no text. } switch (mEventType) { case EVENT_TYPE_MODE_KEY: case EVENT_TYPE_NOT_HANDLED: Loading java/src/com/android/inputmethod/latin/WordComposer.java +3 −0 Original line number Diff line number Diff line Loading @@ -184,6 +184,9 @@ public final class WordComposer { @Nonnull public Event processEvent(final Event event) { final Event processedEvent = mCombinerChain.processEvent(mEvents, event); // The retained state of the combiner chain may have changed while processing the event, // so we need to update our cache. refreshTypedWordCache(); mEvents.add(event); return processedEvent; } Loading java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +18 −2 Original line number Diff line number Diff line Loading @@ -206,7 +206,7 @@ public final class InputLogic { final int keyboardShiftMode, // TODO: remove this argument final LatinIME.UIHandler handler) { final String rawText = event.mText.toString(); final String rawText = event.getTextToCommit().toString(); final InputTransaction inputTransaction = new InputTransaction(settingsValues, event, SystemClock.uptimeMillis(), mSpaceState, getActualCapsMode(settingsValues, keyboardShiftMode)); Loading Loading @@ -416,6 +416,8 @@ public final class InputLogic { mLastKeyTime = inputTransaction.mTimestamp; mConnection.beginBatchEdit(); if (!mWordComposer.isComposingWord()) { // TODO: is this useful? It doesn't look like it should be done here, but rather after // a word is committed. mIsAutoCorrectionIndicatorOn = false; } Loading @@ -425,7 +427,21 @@ public final class InputLogic { } boolean didAutoCorrect = false; if (processedEvent.isFunctionalKeyEvent()) { if (processedEvent.isConsumed()) { // A consumed event may have text to commit and an update to the composing state, so // we evaluate both. With some combiners, it's possible than an event contains both // and we enter both of the following if clauses. final CharSequence textToCommit = processedEvent.getTextToCommit(); if (!TextUtils.isEmpty(textToCommit)) { mConnection.commitText(textToCommit, 1); inputTransaction.setDidAffectContents(); } if (mWordComposer.isComposingWord()) { mConnection.setComposingText(mWordComposer.getTypedWord(), 1); inputTransaction.setDidAffectContents(); inputTransaction.setRequiresUpdateSuggestions(); } } else if (processedEvent.isFunctionalKeyEvent()) { // A special key, like delete, shift, emoji, or the settings key. switch (processedEvent.mKeyCode) { case Constants.CODE_DELETE: Loading Loading
java/src/com/android/inputmethod/event/CombinerChain.java +14 −4 Original line number Diff line number Diff line Loading @@ -82,6 +82,13 @@ public class CombinerChain { } } private void updateStateFeedback() { mStateFeedback.clear(); for (int i = mCombiners.size() - 1; i >= 0; --i) { mStateFeedback.append(mCombiners.get(i).getCombiningStateFeedback()); } } /** * Process an event through the combining chain, and return a processed event to apply. * @param previousEvents the list of previous events in this composition Loading @@ -97,7 +104,13 @@ public class CombinerChain { // 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 (event.isConsumed()) { // If the event is consumed, then we don't pass it to subsequent combiners: // they should not see it at all. break; } } updateStateFeedback(); return event; } Loading @@ -121,10 +134,7 @@ public class CombinerChain { } } } mStateFeedback.clear(); for (int i = mCombiners.size() - 1; i >= 0; --i) { mStateFeedback.append(mCombiners.get(i).getCombiningStateFeedback()); } updateStateFeedback(); } /** Loading
java/src/com/android/inputmethod/event/DeadKeyCombiner.java +7 −1 Original line number Diff line number Diff line Loading @@ -36,10 +36,16 @@ public class DeadKeyCombiner implements Combiner { @Nonnull public Event processEvent(final ArrayList<Event> previousEvents, final Event event) { if (TextUtils.isEmpty(mDeadSequence)) { // No dead char is currently being tracked: this is the most common case. if (event.isDead()) { // The event was a dead key. Start tracking it. mDeadSequence.appendCodePoint(event.mCodePoint); } return Event.createConsumedEvent(event); } // Regular keystroke when not keeping track of a dead key. Simply said, there are // no dead keys at all in the current input, so this combiner has nothing to do and // simply returns the event as is. The majority of events will go through this path. return event; } else { // TODO: Allow combining for several dead chars rather than only the first one. // The framework doesn't know how to do this now. Loading
java/src/com/android/inputmethod/event/Event.java +4 −0 Original line number Diff line number Diff line Loading @@ -227,6 +227,7 @@ public class Event { * @return an identical event marked as consumed. */ public static Event createConsumedEvent(final Event source) { // A consumed event should not input any text at all, so we pass the empty string as text. return new Event(source.mEventType, source.mText, source.mCodePoint, source.mKeyCode, source.mX, source.mY, source.mSuggestedWordInfo, source.mFlags | FLAG_CONSUMED, source.mNextEvent); Loading Loading @@ -267,6 +268,9 @@ public class Event { } public CharSequence getTextToCommit() { if (isConsumed()) { return ""; // A consumed event should input no text. } switch (mEventType) { case EVENT_TYPE_MODE_KEY: case EVENT_TYPE_NOT_HANDLED: Loading
java/src/com/android/inputmethod/latin/WordComposer.java +3 −0 Original line number Diff line number Diff line Loading @@ -184,6 +184,9 @@ public final class WordComposer { @Nonnull public Event processEvent(final Event event) { final Event processedEvent = mCombinerChain.processEvent(mEvents, event); // The retained state of the combiner chain may have changed while processing the event, // so we need to update our cache. refreshTypedWordCache(); mEvents.add(event); return processedEvent; } Loading
java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +18 −2 Original line number Diff line number Diff line Loading @@ -206,7 +206,7 @@ public final class InputLogic { final int keyboardShiftMode, // TODO: remove this argument final LatinIME.UIHandler handler) { final String rawText = event.mText.toString(); final String rawText = event.getTextToCommit().toString(); final InputTransaction inputTransaction = new InputTransaction(settingsValues, event, SystemClock.uptimeMillis(), mSpaceState, getActualCapsMode(settingsValues, keyboardShiftMode)); Loading Loading @@ -416,6 +416,8 @@ public final class InputLogic { mLastKeyTime = inputTransaction.mTimestamp; mConnection.beginBatchEdit(); if (!mWordComposer.isComposingWord()) { // TODO: is this useful? It doesn't look like it should be done here, but rather after // a word is committed. mIsAutoCorrectionIndicatorOn = false; } Loading @@ -425,7 +427,21 @@ public final class InputLogic { } boolean didAutoCorrect = false; if (processedEvent.isFunctionalKeyEvent()) { if (processedEvent.isConsumed()) { // A consumed event may have text to commit and an update to the composing state, so // we evaluate both. With some combiners, it's possible than an event contains both // and we enter both of the following if clauses. final CharSequence textToCommit = processedEvent.getTextToCommit(); if (!TextUtils.isEmpty(textToCommit)) { mConnection.commitText(textToCommit, 1); inputTransaction.setDidAffectContents(); } if (mWordComposer.isComposingWord()) { mConnection.setComposingText(mWordComposer.getTypedWord(), 1); inputTransaction.setDidAffectContents(); inputTransaction.setRequiresUpdateSuggestions(); } } else if (processedEvent.isFunctionalKeyEvent()) { // A special key, like delete, shift, emoji, or the settings key. switch (processedEvent.mKeyCode) { case Constants.CODE_DELETE: Loading