diff options
Diffstat (limited to 'java/src/com/android/inputmethod')
14 files changed, 256 insertions, 142 deletions
diff --git a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java index b8a8169bc..9397483ce 100644 --- a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java +++ b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java @@ -158,7 +158,10 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void flushVoiceInputLogs(boolean configurationChanged) { - if (VOICE_INSTALLED && !configurationChanged) { + if (!VOICE_INSTALLED) { + return; + } + if (!configurationChanged) { if (mAfterVoiceInput) { mVoiceInput.flushAllTextModificationCounters(); mVoiceInput.logInputEnded(); @@ -301,6 +304,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void showPunctuationHintIfNecessary() { + if (!VOICE_INSTALLED) { + return; + } InputConnection ic = mService.getCurrentInputConnection(); if (!mImmediatelyAfterVoiceInput && mAfterVoiceInput && ic != null) { if (mHints.showPunctuationHintIfNecessary(ic)) { @@ -375,9 +381,6 @@ public class VoiceProxy implements VoiceInput.UiListener { } private void revertVoiceInput() { - if (!VOICE_INSTALLED) { - return; - } InputConnection ic = mService.getCurrentInputConnection(); if (ic != null) ic.commitText("", 1); mService.updateSuggestions(); @@ -394,7 +397,10 @@ public class VoiceProxy implements VoiceInput.UiListener { } public boolean logAndRevertVoiceInput() { - if (VOICE_INSTALLED && mVoiceInputHighlighted) { + if (!VOICE_INSTALLED) { + return false; + } + if (mVoiceInputHighlighted) { mVoiceInput.incrementTextModificationDeleteCount( mVoiceResults.candidates.get(0).toString().length()); revertVoiceInput(); @@ -505,7 +511,10 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void handleClose() { - if (VOICE_INSTALLED & mRecognizing) { + if (!VOICE_INSTALLED) { + return; + } + if (mRecognizing) { mVoiceInput.cancel(); } } @@ -553,6 +562,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void switchToRecognitionStatusView(final Configuration configuration) { + if (!VOICE_INSTALLED) { + return; + } mHandler.post(new Runnable() { @Override public void run() { @@ -597,6 +609,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } private void switchToLastInputMethod() { + if (!VOICE_INSTALLED) { + return; + } final IBinder token = mService.getWindow().getWindow().getAttributes().token; new AsyncTask<Void, Void, Boolean>() { @Override @@ -662,14 +677,15 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void startListening(final boolean swipe, IBinder token) { + if (!VOICE_INSTALLED) { + return; + } // TODO: remove swipe which is no longer used. - if (VOICE_INSTALLED) { - if (needsToShowWarningDialog()) { - // Calls reallyStartListening if user clicks OK, does nothing if user clicks Cancel. - showVoiceWarningDialog(swipe, token); - } else { - reallyStartListening(swipe); - } + if (needsToShowWarningDialog()) { + // Calls reallyStartListening if user clicks OK, does nothing if user clicks Cancel. + showVoiceWarningDialog(swipe, token); + } else { + reallyStartListening(swipe); } } @@ -704,17 +720,18 @@ public class VoiceProxy implements VoiceInput.UiListener { mLocaleSupportedForVoiceInput = SubtypeSwitcher.getInstance().isVoiceSupported( SubtypeSwitcher.getInstance().getInputLocaleStr()); - if (VOICE_INSTALLED) { - final String voiceMode = sp.getString(PREF_VOICE_MODE, - mService.getString(R.string.voice_mode_main)); - mVoiceButtonEnabled = !voiceMode.equals(mService.getString(R.string.voice_mode_off)) - && shouldShowVoiceButton(makeFieldContext(), attribute); - mVoiceButtonOnPrimary = voiceMode.equals(mService.getString(R.string.voice_mode_main)); - } + final String voiceMode = sp.getString(PREF_VOICE_MODE, + mService.getString(R.string.voice_mode_main)); + mVoiceButtonEnabled = !voiceMode.equals(mService.getString(R.string.voice_mode_off)) + && shouldShowVoiceButton(makeFieldContext(), attribute); + mVoiceButtonOnPrimary = voiceMode.equals(mService.getString(R.string.voice_mode_main)); } public void destroy() { - if (VOICE_INSTALLED && mVoiceInput != null) { + if (!VOICE_INSTALLED) { + return; + } + if (mVoiceInput != null) { mVoiceInput.destroy(); } } @@ -826,10 +843,16 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void cancel() { + if (!VOICE_INSTALLED) { + return; + } if (mVoiceInput != null) mVoiceInput.cancel(); } public void reset() { + if (!VOICE_INSTALLED) { + return; + } if (mVoiceInput != null) mVoiceInput.reset(); } } diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index 33ab511a5..8b8930a86 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -34,6 +34,8 @@ import com.android.inputmethod.keyboard.internal.Row; import com.android.inputmethod.latin.R; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; /** * Class for describing the position and characteristics of a single key in the keyboard. @@ -153,6 +155,38 @@ public class Key { android.R.attr.state_pressed }; + // RTL parenthesis character swapping map. + private static final Map<Integer, Integer> sRtlParenthesisMap = new HashMap<Integer, Integer>(); + + static { + addRtlParenthesisPair('(', ')'); + addRtlParenthesisPair('[', ']'); + addRtlParenthesisPair('{', '}'); + addRtlParenthesisPair('<', '>'); + // \u00ab: LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + // \u00bb: RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + addRtlParenthesisPair('\u00ab', '\u00bb'); + // \u2039: SINGLE LEFT-POINTING ANGLE QUOTATION MARK + // \u203a: SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + addRtlParenthesisPair('\u2039', '\u203a'); + // \u2264: LESS-THAN OR EQUAL TO + // \u2265: GREATER-THAN OR EQUAL TO + addRtlParenthesisPair('\u2264', '\u2265'); + } + + private static void addRtlParenthesisPair(int left, int right) { + sRtlParenthesisMap.put(left, right); + sRtlParenthesisMap.put(right, left); + } + + private static int getRtlParenthesisCode(int code) { + if (sRtlParenthesisMap.containsKey(code)) { + return sRtlParenthesisMap.get(code); + } else { + return code; + } + } + /** * This constructor is being used only for key in popup mini keyboard. */ @@ -174,7 +208,8 @@ public class Key { final String popupSpecification = popupCharacter.toString(); mLabel = PopupCharactersParser.getLabel(popupSpecification); mOutputText = PopupCharactersParser.getOutputText(popupSpecification); - mCode = PopupCharactersParser.getCode(res, popupSpecification); + final int code = PopupCharactersParser.getCode(res, popupSpecification); + mCode = keyboard.isRtlKeyboard() ? getRtlParenthesisCode(code) : code; mIcon = keyboard.mIconsSet.getIcon(PopupCharactersParser.getIconId(popupSpecification)); // Horizontal gap is divided equally to both sides of the key. mX = x + mGap / 2; @@ -298,7 +333,8 @@ public class Key { final int code = style.getInt(keyAttr, R.styleable.Keyboard_Key_code, Keyboard.CODE_UNSPECIFIED); if (code == Keyboard.CODE_UNSPECIFIED && !TextUtils.isEmpty(mLabel)) { - mCode = mLabel.charAt(0); + final int firstChar = mLabel.charAt(0); + mCode = mKeyboard.isRtlKeyboard() ? getRtlParenthesisCode(firstChar) : firstChar; } else if (code != Keyboard.CODE_UNSPECIFIED) { mCode = code; } else { diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index d4a23aa15..19847c5ec 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -110,6 +110,9 @@ public class Keyboard { /** Maximum column for popup keyboard */ private int mMaxPopupColumn; + /** True if Right-To-Left keyboard */ + private boolean mIsRtlKeyboard; + /** List of shift keys in this keyboard and its icons and state */ private final List<Key> mShiftKeys = new ArrayList<Key>(); private final HashMap<Key, Drawable> mShiftedIcons = new HashMap<Key, Drawable>(); @@ -257,6 +260,14 @@ public class Keyboard { mKeyboardHeight = height; } + public boolean isRtlKeyboard() { + return mIsRtlKeyboard; + } + + public void setRtlKeyboard(boolean isRtl) { + mIsRtlKeyboard = isRtl; + } + public int getPopupKeyboardResId() { return mPopupKeyboardResId; } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java index b2600dd3b..a71e31ec6 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java @@ -125,10 +125,10 @@ public class KeyboardId { mEnableShiftLock); } - public KeyboardId cloneWithNewGeometry(int width) { + public KeyboardId cloneWithNewGeometry(int orientation, int width) { if (mWidth == width) return this; - return new KeyboardId(mXmlName, mXmlId, mLocale, mOrientation, width, mMode, mAttribute, + return new KeyboardId(mXmlName, mXmlId, mLocale, orientation, width, mMode, mAttribute, mHasSettingsKey, mF2KeyMode, mClobberSettingsKey, mVoiceKeyEnabled, mHasVoiceKey, mEnableShiftLock); } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 52ecfe236..088c9d140 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -106,7 +106,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha private int mThemeIndex = -1; private Context mThemeContext; - private int mKeyboardWidth; + private int mWindowWidth; private static final KeyboardSwitcher sInstance = new KeyboardSwitcher(); @@ -187,13 +187,24 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha setKeyboard(getKeyboard(id)); } - public void onSizeChanged() { + @SuppressWarnings("unused") + public void onSizeChanged(int w, int h, int oldw, int oldh) { final int width = mInputMethodService.getWindow().getWindow().getDecorView().getWidth(); + // If the window width hasn't fixed yet or keyboard doesn't exist, nothing to do with. if (width == 0 || mCurrentId == null) return; - mKeyboardWidth = width; - // Set keyboard with new width. - final KeyboardId newId = mCurrentId.cloneWithNewGeometry(width); + // The window width is fixed. + mWindowWidth = width; + // If this is the first time the {@link KeyboardView} has been shown, no need to reload + // keyboard. + if (oldw == 0 && oldh == 0) + return; + // Reload keyboard with new width. + final int orientation = mInputMethodService.getResources().getConfiguration().orientation; + final KeyboardId newId = mCurrentId.cloneWithNewGeometry(orientation, width); + // If the new keyboard is the same as the current one, no need to reload it. + if (newId.equals(mCurrentId)) + return; setKeyboard(getKeyboard(newId)); } @@ -289,11 +300,11 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha attribute); final Resources res = mInputMethodService.getResources(); final int orientation = res.getConfiguration().orientation; - if (mKeyboardWidth == 0) - mKeyboardWidth = res.getDisplayMetrics().widthPixels; + if (mWindowWidth == 0) + mWindowWidth = res.getDisplayMetrics().widthPixels; final Locale locale = mSubtypeSwitcher.getInputLocale(); return new KeyboardId( - res.getResourceEntryName(xmlId), xmlId, locale, orientation, mKeyboardWidth, + res.getResourceEntryName(xmlId), xmlId, locale, orientation, mWindowWidth, mode, attribute, hasSettingsKey, f2KeyMode, clobberSettingsKey, mVoiceKeyEnabled, hasVoiceKey, enableShiftLock); } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index 1641dc4a5..1010adbe0 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -73,8 +73,6 @@ import java.util.HashMap; * @attr ref R.styleable#KeyboardView_shadowRadius */ public class KeyboardView extends View implements PointerTracker.DrawingProxy { - private static final boolean DEBUG_KEYBOARD_GRID = false; - // Miscellaneous constants private static final int[] LONG_PRESSABLE_STATE_SET = { android.R.attr.state_long_pressable }; @@ -97,17 +95,15 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { private ViewGroup mPreviewPlacer; // Drawing - /** Whether the keyboard bitmap needs to be redrawn before it's blitted. **/ - private boolean mDrawPending; - /** Notes if the keyboard just changed, so that we could possibly reallocate the mBuffer. */ - private boolean mKeyboardChanged; + /** Whether the keyboard bitmap buffer needs to be redrawn before it's blitted. **/ + private boolean mBufferNeedsUpdate; /** The dirty region in the keyboard bitmap */ private final Rect mDirtyRect = new Rect(); /** The key to invalidate. */ private Key mInvalidatedKey; /** The dirty region for single key drawing */ private final Rect mInvalidatedKeyRect = new Rect(); - /** The keyboard bitmap for faster updates */ + /** The keyboard bitmap buffer for faster updates */ private Bitmap mBuffer; /** The canvas for the above mutable keyboard bitmap */ private Canvas mCanvas; @@ -175,10 +171,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { sendMessageDelayed(obtainMessage(MSG_DISMISS_KEY_PREVIEW, tracker), delay); } - public void cancelDismissKeyPreview(PointerTracker tracker) { - removeMessages(MSG_DISMISS_KEY_PREVIEW, tracker); - } - public void cancelAllDismissKeyPreviews() { removeMessages(MSG_DISMISS_KEY_PREVIEW); } @@ -363,7 +355,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { mKeyboard = keyboard; LatinImeLogger.onSetKeyboard(keyboard); requestLayout(); - mKeyboardChanged = true; + mDirtyRect.set(0, 0, getWidth(), getHeight()); + mBufferNeedsUpdate = true; invalidateAllKeys(); final int keyHeight = keyboard.getRowHeight() - keyboard.getVerticalGap(); mKeyDrawParams.updateKeyHeight(keyHeight); @@ -401,25 +394,21 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { } @Override - public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - // Round up a little - if (mKeyboard == null) { - setMeasuredDimension( - getPaddingLeft() + getPaddingRight(), getPaddingTop() + getPaddingBottom()); + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + if (mKeyboard != null) { + // The main keyboard expands to the display width. + final int height = mKeyboard.getKeyboardHeight() + getPaddingTop() + getPaddingBottom(); + setMeasuredDimension(widthMeasureSpec, height); } else { - int width = mKeyboard.getMinWidth() + getPaddingLeft() + getPaddingRight(); - if (MeasureSpec.getSize(widthMeasureSpec) < width + 10) { - width = MeasureSpec.getSize(widthMeasureSpec); - } - setMeasuredDimension( - width, mKeyboard.getHeight() + getPaddingTop() + getPaddingBottom()); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); - if (mDrawPending || mBuffer == null || mKeyboardChanged) { + if (mBufferNeedsUpdate || mBuffer == null) { + mBufferNeedsUpdate = false; onBufferDraw(); } canvas.drawBitmap(mBuffer, 0, 0, null); @@ -430,14 +419,11 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { final int height = getHeight(); if (width == 0 || height == 0) return; - if (mBuffer == null || mKeyboardChanged) { - mKeyboardChanged = false; - mDirtyRect.union(0, 0, width, height); - } if (mBuffer == null || mBuffer.getWidth() != width || mBuffer.getHeight() != height) { if (mBuffer != null) mBuffer.recycle(); mBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + mDirtyRect.union(0, 0, width, height); if (mCanvas != null) { mCanvas.setBitmap(mBuffer); } else { @@ -471,24 +457,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { } } - // TODO: Move this function to ProximityInfo for getting rid of - // public declarations for - // GRID_WIDTH and GRID_HEIGHT - if (DEBUG_KEYBOARD_GRID) { - Paint p = new Paint(); - p.setStyle(Paint.Style.STROKE); - p.setStrokeWidth(1.0f); - p.setColor(0x800000c0); - int cw = (mKeyboard.getMinWidth() + mKeyboard.GRID_WIDTH - 1) - / mKeyboard.GRID_WIDTH; - int ch = (mKeyboard.getHeight() + mKeyboard.GRID_HEIGHT - 1) - / mKeyboard.GRID_HEIGHT; - for (int i = 0; i <= mKeyboard.GRID_WIDTH; i++) - canvas.drawLine(i * cw, 0, i * cw, ch * mKeyboard.GRID_HEIGHT, p); - for (int i = 0; i <= mKeyboard.GRID_HEIGHT; i++) - canvas.drawLine(0, i * ch, cw * mKeyboard.GRID_WIDTH, i * ch, p); - } - // Overlay a dark rectangle to dim the keyboard if (needsToDimKeyboard()) { mPaint.setColor((int) (mBackgroundDimAmount * 0xFF) << 24); @@ -496,7 +464,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { } mInvalidatedKey = null; - mDrawPending = false; mDirtyRect.setEmpty(); } @@ -866,7 +833,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { */ public void invalidateAllKeys() { mDirtyRect.union(0, 0, getWidth(), getHeight()); - mDrawPending = true; + mBufferNeedsUpdate = true; invalidate(); } @@ -886,7 +853,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { final int y = key.mY + getPaddingTop(); mInvalidatedKeyRect.set(x, y, x + key.mWidth, y + key.mHeight); mDirtyRect.union(mInvalidatedKeyRect); - onBufferDraw(); + mBufferNeedsUpdate = true; invalidate(mInvalidatedKeyRect); } diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java index fb57a2dba..0ad91dbb0 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java @@ -269,7 +269,7 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { // TODO: Should notify InputMethodService instead? - KeyboardSwitcher.getInstance().onSizeChanged(); + KeyboardSwitcher.getInstance().onSizeChanged(w, h, oldw, oldh); } /** diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java index 44f9f195c..95e32755e 100644 --- a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java @@ -34,6 +34,8 @@ public class MiniKeyboard extends Keyboard { // revert the above hacks and uncomment the following lines. //setHorizontalGap(parentKeyboard.getHorizontalGap()); //setVerticalGap(parentKeyboard.getVerticalGap()); + + setRtlKeyboard(parentKeyboard.isRtlKeyboard()); } public void setDefaultCoordX(int pos) { diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index 5b03ef4a1..e66ea7b79 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -199,8 +199,7 @@ public class PointerTracker { public static void dismissAllKeyPreviews() { for (final PointerTracker tracker : sTrackers) { - tracker.setReleasedKeyGraphics(); - tracker.dismissKeyPreview(); + tracker.setReleasedKeyGraphics(tracker.mKeyIndex); } } @@ -323,11 +322,8 @@ public class PointerTracker { return key != null && key.mCode == Keyboard.CODE_SPACE; } - public void setReleasedKeyGraphics() { - setReleasedKeyGraphics(mKeyIndex); - } - private void setReleasedKeyGraphics(int keyIndex) { + mDrawingProxy.dismissKeyPreview(this); final Key key = getKey(keyIndex); if (key != null) { key.onReleased(); @@ -336,6 +332,9 @@ public class PointerTracker { } private void setPressedKeyGraphics(int keyIndex) { + if (isKeyPreviewRequired(keyIndex)) { + mDrawingProxy.showKeyPreview(keyIndex, this); + } final Key key = getKey(keyIndex); if (key != null && key.isEnabled()) { key.onPressed(); @@ -343,6 +342,18 @@ public class PointerTracker { } } + // The modifier key, such as shift key, should not show its key preview. + private boolean isKeyPreviewRequired(int keyIndex) { + final Key key = getKey(keyIndex); + if (key == null || !key.isEnabled()) + return false; + final int code = key.mCode; + if (isModifierCode(code) || code == Keyboard.CODE_DELETE + || code == Keyboard.CODE_ENTER || code == Keyboard.CODE_SPACE) + return false; + return true; + } + public int getLastX() { return mLastX; } @@ -438,7 +449,6 @@ public class PointerTracker { startRepeatKey(keyIndex); startLongPressTimer(keyIndex); - showKeyPreview(keyIndex); setPressedKeyGraphics(keyIndex); } } @@ -471,7 +481,6 @@ public class PointerTracker { keyIndex = onMoveKey(x, y); onMoveToNewKey(keyIndex, x, y); startLongPressTimer(keyIndex); - showKeyPreview(keyIndex); setPressedKeyGraphics(keyIndex); } else if (isMajorEnoughMoveToBeOnNewKey(x, y, keyIndex)) { // The pointer has been slid in to the new key from the previous key, we must call @@ -491,7 +500,6 @@ public class PointerTracker { onMoveToNewKey(keyIndex, x, y); startLongPressTimer(keyIndex); setPressedKeyGraphics(keyIndex); - showKeyPreview(keyIndex); } else { // HACK: On some devices, quick successive touches may be translated to sudden // move by touch panel firmware. This hack detects the case and translates the @@ -503,11 +511,10 @@ public class PointerTracker { if (DEBUG_MODE) Log.w(TAG, String.format("onMoveEvent: sudden move is translated to " + "up[%d,%d]/down[%d,%d] events", lastX, lastY, x, y)); - onUpEventInternal(lastX, lastY, eventTime, true); + onUpEventInternal(lastX, lastY, eventTime); onDownEventInternal(x, y, eventTime); } else { mKeyAlreadyProcessed = true; - dismissKeyPreview(); setReleasedKeyGraphics(oldKeyIndex); } } @@ -524,7 +531,6 @@ public class PointerTracker { onMoveToNewKey(keyIndex, x, y); } else { mKeyAlreadyProcessed = true; - dismissKeyPreview(); } } } @@ -539,27 +545,26 @@ public class PointerTracker { if (isModifier()) { // Before processing an up event of modifier key, all pointers already being // tracked should be released. - queue.releaseAllPointersExcept(this, eventTime, true); + queue.releaseAllPointersExcept(this, eventTime); } else { queue.releaseAllPointersOlderThan(this, eventTime); } queue.remove(this); } - onUpEventInternal(x, y, eventTime, true); + onUpEventInternal(x, y, eventTime); } // Let this pointer tracker know that one of newer-than-this pointer trackers got an up event. // This pointer tracker needs to keep the key top graphics "pressed", but needs to get a // "virtual" up event. - public void onPhantomUpEvent(int x, int y, long eventTime, boolean updateReleasedKeyGraphics) { + public void onPhantomUpEvent(int x, int y, long eventTime) { if (DEBUG_EVENT) printTouchEvent("onPhntEvent:", x, y, eventTime); - onUpEventInternal(x, y, eventTime, updateReleasedKeyGraphics); + onUpEventInternal(x, y, eventTime); mKeyAlreadyProcessed = true; } - private void onUpEventInternal(int x, int y, long eventTime, - boolean updateReleasedKeyGraphics) { + private void onUpEventInternal(int x, int y, long eventTime) { mTimerProxy.cancelKeyTimers(); mDrawingProxy.cancelShowKeyPreview(this); mIsInSlidingKeyInput = false; @@ -573,9 +578,7 @@ public class PointerTracker { keyY = mKeyY; } final int keyIndex = onUpKey(keyX, keyY, eventTime); - dismissKeyPreview(); - if (updateReleasedKeyGraphics) - setReleasedKeyGraphics(keyIndex); + setReleasedKeyGraphics(keyIndex); if (mKeyAlreadyProcessed) return; if (!mIsRepeatableKey) { @@ -585,8 +588,7 @@ public class PointerTracker { public void onLongPressed() { mKeyAlreadyProcessed = true; - setReleasedKeyGraphics(); - dismissKeyPreview(); + setReleasedKeyGraphics(mKeyIndex); final PointerTrackerQueue queue = sPointerTrackerQueue; if (queue != null) { queue.remove(this); @@ -599,7 +601,7 @@ public class PointerTracker { final PointerTrackerQueue queue = sPointerTrackerQueue; if (queue != null) { - queue.releaseAllPointersExcept(this, eventTime, true); + queue.releaseAllPointersExcept(this, eventTime); queue.remove(this); } onCancelEventInternal(); @@ -608,7 +610,6 @@ public class PointerTracker { private void onCancelEventInternal() { mTimerProxy.cancelKeyTimers(); mDrawingProxy.cancelShowKeyPreview(this); - dismissKeyPreview(); setReleasedKeyGraphics(mKeyIndex); mIsInSlidingKeyInput = false; } @@ -616,7 +617,6 @@ public class PointerTracker { private void startRepeatKey(int keyIndex) { final Key key = getKey(keyIndex); if (key != null && key.mRepeatable) { - dismissKeyPreview(); onRepeatKey(keyIndex); mTimerProxy.startKeyRepeatTimer(sDelayBeforeKeyRepeatStart, keyIndex, this); mIsRepeatableKey = true; @@ -646,26 +646,6 @@ public class PointerTracker { } } - // The modifier key, such as shift key, should not show its key preview. - private boolean isKeyPreviewNotRequired(int keyIndex) { - final Key key = getKey(keyIndex); - if (key == null || !key.isEnabled()) - return true; - final int code = key.mCode; - return isModifierCode(code) || code == Keyboard.CODE_DELETE - || code == Keyboard.CODE_ENTER || code == Keyboard.CODE_SPACE; - } - - private void showKeyPreview(int keyIndex) { - if (isKeyPreviewNotRequired(keyIndex)) - return; - mDrawingProxy.showKeyPreview(keyIndex, this); - } - - private void dismissKeyPreview() { - mDrawingProxy.dismissKeyPreview(this); - } - private void startLongPressTimer(int keyIndex) { Key key = getKey(keyIndex); if (key.mCode == Keyboard.CODE_SHIFT) { diff --git a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java index 5ab44d063..a90f57c62 100644 --- a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java @@ -108,6 +108,18 @@ public class PopupMiniKeyboardView extends KeyboardView implements PopupPanel { } @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final Keyboard keyboard = getKeyboard(); + if (keyboard != null) { + final int width = keyboard.getMinWidth() + getPaddingLeft() + getPaddingRight(); + final int height = keyboard.getKeyboardHeight() + getPaddingTop() + getPaddingBottom(); + setMeasuredDimension(width, height); + } else { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + } + + @Override public void setKeyboard(Keyboard keyboard) { super.setKeyboard(keyboard); mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java index 6f7349915..8eae2bb42 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java @@ -222,8 +222,9 @@ public class KeyboardParser { final int height = Math.max( Math.min(keyboardHeight, maxKeyboardHeight), minKeyboardHeight); - keyboard.setKeyboardHeight(height); + keyboard.setRtlKeyboard(keyboardAttr.getBoolean( + R.styleable.Keyboard_isRtlKeyboard, false)); keyboard.setKeyWidth(getDimensionOrFraction(keyboardAttr, R.styleable.Keyboard_keyWidth, displayWidth, displayWidth / 10)); keyboard.setRowHeight(getDimensionOrFraction(keyboardAttr, diff --git a/java/src/com/android/inputmethod/keyboard/internal/MiniKeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/MiniKeyboardBuilder.java index cc89579bb..965c679ea 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/MiniKeyboardBuilder.java +++ b/java/src/com/android/inputmethod/keyboard/internal/MiniKeyboardBuilder.java @@ -218,7 +218,7 @@ public class MiniKeyboardBuilder { mParams = params; keyboard.setRowHeight(params.mRowHeight); - keyboard.setHeight(params.getKeyboardHeight()); + keyboard.setKeyboardHeight(params.getKeyboardHeight()); keyboard.setMinWidth(params.getKeyboardWidth()); keyboard.setDefaultCoordX(params.getDefaultKeyCoordX() + params.mKeyWidth / 2); } diff --git a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java index 545b27fdc..55175e046 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java +++ b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java @@ -37,22 +37,21 @@ public class PointerTrackerQueue { if (t.isModifier()) { oldestPos++; } else { - t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime, true); + t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime); queue.remove(oldestPos); } } } public void releaseAllPointers(long eventTime) { - releaseAllPointersExcept(null, eventTime, true); + releaseAllPointersExcept(null, eventTime); } - public void releaseAllPointersExcept(PointerTracker tracker, long eventTime, - boolean updateReleasedKeyGraphics) { + public void releaseAllPointersExcept(PointerTracker tracker, long eventTime) { for (PointerTracker t : mQueue) { if (t == tracker) continue; - t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime, updateReleasedKeyGraphics); + t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime); } mQueue.clear(); if (tracker != null) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 324a13045..3457ac984 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -174,7 +174,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private int mCorrectionMode; private int mCommittedLength; - private int mOrientation; // Keep track of the last selection range to decide if we need to show word alternatives private int mLastSelectionStart; private int mLastSelectionEnd; @@ -193,6 +192,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // TODO: Move this flag to VoiceProxy private boolean mConfigurationChanging; + // Member variables for remembering the current device orientation. + private int mDisplayOrientation; + private int mDisplayWidth; + private int mDisplayHeight; + // Object for reacting to adding/removing a dictionary pack. private BroadcastReceiver mDictionaryPackInstallReceiver = new DictionaryPackInstallBroadcastReceiver(this); @@ -200,7 +204,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // Keeps track of most recently inserted text (multi-character key) for reverting private CharSequence mEnteredText; - public final UIHandler mHandler = new UIHandler(this); public static class UIHandler extends StaticInnerHandlerWrapper<LatinIME> { @@ -212,6 +215,29 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private static final int MSG_DISMISS_LANGUAGE_ON_SPACEBAR = 5; private static final int MSG_SPACE_TYPED = 6; private static final int MSG_SET_BIGRAM_PREDICTIONS = 7; + private static final int MSG_CONFIRM_ORIENTATION_CHANGE = 8; + private static final int MSG_START_INPUT_VIEW = 9; + + private static class OrientationChangeArgs { + public final int mOldWidth; + public final int mOldHeight; + private int mRetryCount; + + public OrientationChangeArgs(int oldw, int oldh) { + mOldWidth = oldw; + mOldHeight = oldh; + mRetryCount = 0; + } + + public boolean hasTimedOut() { + mRetryCount++; + return mRetryCount >= 10; + } + + public boolean hasOrientationChangeFinished(DisplayMetrics dm) { + return dm.widthPixels != mOldWidth && dm.heightPixels != mOldHeight; + } + } public UIHandler(LatinIME outerInstance) { super(outerInstance); @@ -260,6 +286,21 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar (LatinKeyboard)msg.obj); } break; + case MSG_CONFIRM_ORIENTATION_CHANGE: { + final OrientationChangeArgs args = (OrientationChangeArgs)msg.obj; + final Resources res = latinIme.mResources; + final DisplayMetrics dm = res.getDisplayMetrics(); + if (args.hasTimedOut() || args.hasOrientationChangeFinished(dm)) { + latinIme.setDisplayGeometry(res.getConfiguration(), dm); + } else { + // It seems orientation changing is on going. + postConfirmOrientationChange(args); + } + break; + } + case MSG_START_INPUT_VIEW: + latinIme.onStartInputView((EditorInfo)msg.obj, false); + break; } } @@ -349,6 +390,33 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar public boolean isAcceptingDoubleSpaces() { return hasMessages(MSG_SPACE_TYPED); } + + private void postConfirmOrientationChange(OrientationChangeArgs args) { + removeMessages(MSG_CONFIRM_ORIENTATION_CHANGE); + // Will confirm whether orientation change has finished or not after 2ms again. + sendMessageDelayed(obtainMessage(MSG_CONFIRM_ORIENTATION_CHANGE, args), 2); + } + + public void startOrientationChanging(int oldw, int oldh) { + postConfirmOrientationChange(new OrientationChangeArgs(oldw, oldh)); + } + + public boolean postStartInputView(EditorInfo attribute) { + if (hasMessages(MSG_CONFIRM_ORIENTATION_CHANGE) || hasMessages(MSG_START_INPUT_VIEW)) { + removeMessages(MSG_START_INPUT_VIEW); + // Postpone onStartInputView 20ms afterward and see if orientation change has + // finished. + sendMessageDelayed(obtainMessage(MSG_START_INPUT_VIEW, attribute), 20); + return true; + } + return false; + } + } + + private void setDisplayGeometry(Configuration conf, DisplayMetrics metric) { + mDisplayOrientation = conf.orientation; + mDisplayWidth = metric.widthPixels; + mDisplayHeight = metric.heightPixels; } @Override @@ -388,7 +456,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } - mOrientation = res.getConfiguration().orientation; + setDisplayGeometry(res.getConfiguration(), res.getDisplayMetrics()); // Register to receive ringer mode change and network state change. // Also receive installation and removal of a dictionary pack. @@ -486,11 +554,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar public void onConfigurationChanged(Configuration conf) { mSubtypeSwitcher.onConfigurationChanged(conf); // If orientation changed while predicting, commit the change - if (conf.orientation != mOrientation) { + if (conf.orientation != mDisplayOrientation) { + mHandler.startOrientationChanging(mDisplayWidth, mDisplayHeight); InputConnection ic = getCurrentInputConnection(); commitTyped(ic); if (ic != null) ic.finishComposingText(); // For voice input - mOrientation = conf.orientation; if (isShowingOptionDialog()) mOptionsDialog.dismiss(); } @@ -527,6 +595,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar @Override public void onStartInputView(EditorInfo attribute, boolean restarting) { + if (mHandler.postStartInputView(attribute)) { + return; + } + final KeyboardSwitcher switcher = mKeyboardSwitcher; LatinKeyboardView inputView = switcher.getKeyboardView(); @@ -1446,7 +1518,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar public boolean isShowingSuggestionsStrip() { return (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_VALUE) || (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE - && mOrientation == Configuration.ORIENTATION_PORTRAIT); + && mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT); } public boolean isCandidateStripVisible() { |