aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/event/DeadKeyCombiner.java8
-rw-r--r--java/src/com/android/inputmethod/event/Event.java96
-rw-r--r--java/src/com/android/inputmethod/event/HardwareKeyboardEventDecoder.java22
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java20
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java21
5 files changed, 120 insertions, 47 deletions
diff --git a/java/src/com/android/inputmethod/event/DeadKeyCombiner.java b/java/src/com/android/inputmethod/event/DeadKeyCombiner.java
index 52987d571..ae8639713 100644
--- a/java/src/com/android/inputmethod/event/DeadKeyCombiner.java
+++ b/java/src/com/android/inputmethod/event/DeadKeyCombiner.java
@@ -43,19 +43,19 @@ public class DeadKeyCombiner implements Combiner {
final int resultingCodePoint =
KeyCharacterMap.getDeadChar(deadCodePoint, event.mCodePoint);
if (0 == resultingCodePoint) {
- // We can't combine both characters. We need to commit the dead key as a committable
+ // We can't combine both characters. We need to commit the dead key as a separate
// character, and the next char too unless it's a space (because as a special case,
// dead key + space should result in only the dead key being committed - that's
// how dead keys work).
// If the event is a space, we should commit the dead char alone, but if it's
// not, we need to commit both.
- return Event.createCommittableEvent(deadCodePoint,
+ return Event.createHardwareKeypressEvent(deadCodePoint, event.mKeyCode,
Constants.CODE_SPACE == event.mCodePoint ? null : event /* next */);
} else {
// We could combine the characters.
- return Event.createCommittableEvent(resultingCodePoint, null /* next */);
+ return Event.createHardwareKeypressEvent(resultingCodePoint, event.mKeyCode,
+ null /* next */);
}
}
}
-
}
diff --git a/java/src/com/android/inputmethod/event/Event.java b/java/src/com/android/inputmethod/event/Event.java
index 1f3320eb7..31092f176 100644
--- a/java/src/com/android/inputmethod/event/Event.java
+++ b/java/src/com/android/inputmethod/event/Event.java
@@ -16,6 +16,8 @@
package com.android.inputmethod.event;
+import com.android.inputmethod.latin.Constants;
+
/**
* Class representing a generic input event as handled by Latin IME.
*
@@ -33,61 +35,103 @@ public class Event {
// but probably a bit too much
// An event we don't handle in Latin IME, for example pressing Ctrl on a hardware keyboard.
final public static int EVENT_NOT_HANDLED = 0;
- // A character that is already final, for example pressing an alphabetic character on a
- // hardware qwerty keyboard.
- final public static int EVENT_COMMITTABLE = 1;
- // A dead key, which means a character that should combine with what is coming next. Examples
- // include the "^" character on an azerty keyboard which combines with "e" to make "ê", or
- // AltGr+' on a dvorak international keyboard which combines with "e" to make "é". This is
- // true regardless of the language or combining mode, and should be seen as a property of the
- // key - a dead key followed by another key with which it can combine should be regarded as if
- // the keyboard actually had such a key.
- final public static int EVENT_DEAD = 2;
+ // A key press that is part of input, for example pressing an alphabetic character on a
+ // hardware qwerty keyboard. It may be part of a sequence that will be re-interpreted later
+ // through combination.
+ final public static int EVENT_INPUT_KEYPRESS = 1;
// A toggle event is triggered by a key that affects the previous character. An example would
// be a numeric key on a 10-key keyboard, which would toggle between 1 - a - b - c with
// repeated presses.
- final public static int EVENT_TOGGLE = 3;
+ final public static int EVENT_TOGGLE = 2;
// A mode event instructs the combiner to change modes. The canonical example would be the
// hankaku/zenkaku key on a Japanese keyboard, or even the caps lock key on a qwerty keyboard
// if handled at the combiner level.
- final public static int EVENT_MODE_KEY = 4;
+ final public static int EVENT_MODE_KEY = 3;
+ // An event corresponding to a gesture.
+ final public static int EVENT_GESTURE = 4;
+
+ // 0 is a valid code point, so we use -1 here.
+ final public static int NOT_A_CODE_POINT = -1;
+ // -1 is a valid key code, so we use 0 here.
+ final public static int NOT_A_KEY_CODE = 0;
- final private static int NOT_A_CODE_POINT = 0;
+ final private static int FLAG_NONE = 0;
+ // This event is a dead character, usually input by a dead key. Examples include dead-acute
+ // or dead-abovering.
+ final private static int FLAG_DEAD = 0x1;
final private int mType; // The type of event - one of the constants above
// The code point associated with the event, if relevant. This is a unicode code point, and
// has nothing to do with other representations of the key. It is only relevant if this event
- // is the right type: COMMITTABLE or DEAD or TOGGLE, but for a mode key like hankaku/zenkaku or
- // ctrl, there is no code point associated so this should be NOT_A_CODE_POINT to avoid
- // unintentional use of its value when it's not relevant.
+ // is of KEYPRESS type, but for a mode key like hankaku/zenkaku or ctrl, there is no code point
+ // associated so this should be NOT_A_CODE_POINT to avoid unintentional use of its value when
+ // it's not relevant.
final public int mCodePoint;
+
+ // The key code associated with the event, if relevant. This is relevant whenever this event
+ // has been triggered by a key press, but not for a gesture for example. This has conceptually
+ // no link to the code point, although keys that enter a straight code point may often set
+ // this to be equal to mCodePoint for convenience. If this is not a key, this must contain
+ // NOT_A_KEY_CODE.
+ final public int mKeyCode;
+
+ // Coordinates of the touch event, if relevant. If useful, we may want to replace this with
+ // a MotionEvent or something in the future. This is only relevant when the keypress is from
+ // a software keyboard obviously, unless there are touch-sensitive hardware keyboards in the
+ // future or some other awesome sauce.
+ final public int mX;
+ final public int mY;
+
+ // Some flags that can't go into the key code. It's a bit field of FLAG_*
+ final private int mFlags;
+
// The next event, if any. Null if there is no next event yet.
final public Event mNextEvent;
// This method is private - to create a new event, use one of the create* utility methods.
- private Event(final int type, final int codePoint, final Event next) {
+ private Event(final int type, final int codePoint, final int keyCode, final int x, final int y,
+ final int flags, final Event next) {
mType = type;
mCodePoint = codePoint;
+ mKeyCode = keyCode;
+ mX = x;
+ mY = y;
+ mFlags = flags;
mNextEvent = next;
}
- public static Event createDeadEvent(final int codePoint, final Event next) {
- return new Event(EVENT_DEAD, codePoint, next);
+ public static Event createSoftwareKeypressEvent(final int codePoint, final int keyCode,
+ final int x, final int y) {
+ return new Event(EVENT_INPUT_KEYPRESS, codePoint, keyCode, x, y, FLAG_NONE, null);
}
- public static Event createCommittableEvent(final int codePoint, final Event next) {
- return new Event(EVENT_COMMITTABLE, codePoint, next);
+ public static Event createHardwareKeypressEvent(final int codePoint, final int keyCode,
+ final Event next) {
+ return new Event(EVENT_INPUT_KEYPRESS, codePoint, keyCode,
+ Constants.EXTERNAL_KEYBOARD_COORDINATE, Constants.EXTERNAL_KEYBOARD_COORDINATE,
+ FLAG_NONE, next);
}
- public static Event createNotHandledEvent() {
- return new Event(EVENT_NOT_HANDLED, NOT_A_CODE_POINT, null);
+ // This creates an input event for a dead character. @see {@link #FLAG_DEAD}
+ public static Event createDeadEvent(final int codePoint, final int keyCode, final Event next) {
+ // TODO: add an argument or something if we ever create a software layout with dead keys.
+ return new Event(EVENT_INPUT_KEYPRESS, codePoint, keyCode,
+ Constants.EXTERNAL_KEYBOARD_COORDINATE, Constants.EXTERNAL_KEYBOARD_COORDINATE,
+ FLAG_DEAD, next);
}
- public boolean isCommittable() {
- return EVENT_COMMITTABLE == mType;
+ public static Event createNotHandledEvent() {
+ return new Event(EVENT_NOT_HANDLED, NOT_A_CODE_POINT, NOT_A_KEY_CODE,
+ Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, FLAG_NONE, null);
}
+ // Returns whether this event is for a dead character. @see {@link #FLAG_DEAD}
public boolean isDead() {
- return EVENT_DEAD == mType;
+ return 0 != (FLAG_DEAD & mFlags);
+ }
+
+ // TODO: remove this method - we should not have to test this
+ public boolean isCommittable() {
+ return EVENT_INPUT_KEYPRESS == mType || EVENT_MODE_KEY == mType || EVENT_TOGGLE == mType;
}
}
diff --git a/java/src/com/android/inputmethod/event/HardwareKeyboardEventDecoder.java b/java/src/com/android/inputmethod/event/HardwareKeyboardEventDecoder.java
index 720d07433..da6780e08 100644
--- a/java/src/com/android/inputmethod/event/HardwareKeyboardEventDecoder.java
+++ b/java/src/com/android/inputmethod/event/HardwareKeyboardEventDecoder.java
@@ -47,27 +47,33 @@ public class HardwareKeyboardEventDecoder implements HardwareEventDecoder {
// the key for 'A' or Space, but also Backspace or Ctrl or Caps Lock.
final int keyCode = keyEvent.getKeyCode();
if (KeyEvent.KEYCODE_DEL == keyCode) {
- return Event.createCommittableEvent(Constants.CODE_DELETE, null /* next */);
+ return Event.createHardwareKeypressEvent(Event.NOT_A_CODE_POINT, Constants.CODE_DELETE,
+ null /* next */);
}
if (keyEvent.isPrintingKey() || KeyEvent.KEYCODE_SPACE == keyCode
|| KeyEvent.KEYCODE_ENTER == keyCode) {
if (0 != (codePointAndFlags & KeyCharacterMap.COMBINING_ACCENT)) {
// A dead key.
return Event.createDeadEvent(
- codePointAndFlags & KeyCharacterMap.COMBINING_ACCENT_MASK, null /* next */);
+ codePointAndFlags & KeyCharacterMap.COMBINING_ACCENT_MASK, keyCode,
+ null /* next */);
}
if (KeyEvent.KEYCODE_ENTER == keyCode) {
// The Enter key. If the Shift key is not being pressed, this should send a
// CODE_ENTER to trigger the action if any, or a carriage return otherwise. If the
// Shift key is being pressed, this should send a CODE_SHIFT_ENTER and let
// Latin IME decide what to do with it.
- return Event.createCommittableEvent(keyEvent.isShiftPressed()
- ? Constants.CODE_SHIFT_ENTER : Constants.CODE_ENTER,
- null /* next */);
+ if (keyEvent.isShiftPressed()) {
+ return Event.createHardwareKeypressEvent(Event.NOT_A_CODE_POINT,
+ Constants.CODE_SHIFT_ENTER, null /* next */);
+ } else {
+ return Event.createHardwareKeypressEvent(Constants.CODE_ENTER, keyCode,
+ null /* next */);
+ }
}
- // If not Enter, then we have a committable character. This should be committed
- // right away, taking into account the current state.
- return Event.createCommittableEvent(codePointAndFlags, null /* next */);
+ // If not Enter, then this is just a regular keypress event for a normal character
+ // that can be committed right away, taking into account the current state.
+ return Event.createHardwareKeypressEvent(keyCode, codePointAndFlags, null /* next */);
}
return Event.createNotHandledEvent();
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index a9e548060..222e73529 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -59,6 +59,7 @@ import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
import com.android.inputmethod.dictionarypack.DictionaryPackConstants;
+import com.android.inputmethod.event.Event;
import com.android.inputmethod.event.InputTransaction;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardActionListener;
@@ -1266,8 +1267,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSubtypeSwitcher.switchToShortcutIME(this);
// Still call the *#onCodeInput methods for readability.
}
+ final Event event = createSoftwareKeypressEvent(codeToSend, keyX, keyY);
final InputTransaction completeInputTransaction =
- mInputLogic.onCodeInput(mSettings.getCurrent(), codeToSend, keyX, keyY,
+ mInputLogic.onCodeInput(mSettings.getCurrent(), event,
mKeyboardSwitcher.getKeyboardShiftMode(), mHandler);
switch (completeInputTransaction.getRequiredShiftUpdate()) {
case InputTransaction.SHIFT_UPDATE_LATER:
@@ -1281,6 +1283,22 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mKeyboardSwitcher.onCodeInput(codePoint);
}
+ // A helper method to split the code point and the key code. Ultimately, they should not be
+ // squashed into the same variable, and this method should be removed.
+ private static Event createSoftwareKeypressEvent(final int keyCodeOrCodePoint, final int keyX,
+ final int keyY) {
+ final int keyCode;
+ final int codePoint;
+ if (keyCodeOrCodePoint <= 0) {
+ keyCode = keyCodeOrCodePoint;
+ codePoint = Event.NOT_A_CODE_POINT;
+ } else {
+ keyCode = Event.NOT_A_KEY_CODE;
+ codePoint = keyCodeOrCodePoint;
+ }
+ return Event.createSoftwareKeypressEvent(codePoint, keyCode, keyX, keyY);
+ }
+
// Called from PointerTracker through the KeyboardActionListener interface
@Override
public void onTextInput(final String rawText) {
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index dd9d6e8a9..f7e528648 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -27,6 +27,7 @@ import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.compat.SuggestionSpanUtils;
+import com.android.inputmethod.event.Event;
import com.android.inputmethod.event.EventInterpreter;
import com.android.inputmethod.event.InputTransaction;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
@@ -205,9 +206,9 @@ public final class InputLogic {
LatinImeLogger.logOnManualSuggestion("", suggestion, index, suggestedWords);
// Rely on onCodeInput to do the complicated swapping/stripping logic consistently.
final int primaryCode = suggestion.charAt(0);
- onCodeInput(settingsValues, primaryCode,
- Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE,
- keyboardSwitcher.getKeyboardShiftMode(), handler);
+ final Event event = Event.createSoftwareKeypressEvent(primaryCode, Event.NOT_A_KEY_CODE,
+ Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE);
+ onCodeInput(settingsValues, event, keyboardSwitcher.getKeyboardShiftMode(), handler);
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.latinIME_punctuationSuggestion(index, suggestion,
false /* isBatchMode */, suggestedWords.mIsPrediction);
@@ -354,17 +355,21 @@ public final class InputLogic {
* the entry point for gesture input; see the onBatchInput* family of functions for this.
*
* @param settingsValues the current settings values.
- * @param code the code to handle. It may be a code point, or an internal key code.
- * @param x the x-coordinate where the user pressed the key, or NOT_A_COORDINATE.
- * @param y the y-coordinate where the user pressed the key, or NOT_A_COORDINATE.
+ * @param event the event to handle.
* @param keyboardShiftMode the current shift mode of the keyboard, as returned by
* {@link com.android.inputmethod.keyboard.KeyboardSwitcher#getKeyboardShiftMode()}
* @return the complete transaction object
*/
- public InputTransaction onCodeInput(final SettingsValues settingsValues, final int code,
- final int x, final int y, final int keyboardShiftMode,
+ public InputTransaction onCodeInput(final SettingsValues settingsValues, final Event event,
+ final int keyboardShiftMode,
// TODO: remove this argument
final LatinIME.UIHandler handler) {
+ // TODO: rework the following to not squash the keycode and the code point into the same
+ // var because it's confusing. Instead the switch() should handle this in a readable manner.
+ final int code =
+ Event.NOT_A_CODE_POINT == event.mCodePoint ? event.mKeyCode : event.mCodePoint;
+ final int x = event.mX;
+ final int y = event.mY;
final InputTransaction inputTransaction = new InputTransaction(settingsValues, code, x, y,
SystemClock.uptimeMillis(), mSpaceState,
getActualCapsMode(settingsValues, keyboardShiftMode));