Merge "Retain keyboard layout while orientation change"
This commit is contained in:
commit
eedfef0308
2 changed files with 119 additions and 24 deletions
|
@ -82,6 +82,8 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
// system navigation bar.
|
||||
private WindowWidthCache mWindowWidthCache;
|
||||
|
||||
private KeyboardLayoutState mSavedKeyboardState = new KeyboardLayoutState();
|
||||
|
||||
/** mIsAutoCorrectionActive indicates that auto corrected word will be input instead of
|
||||
* what user actually typed. */
|
||||
private boolean mIsAutoCorrectionActive;
|
||||
|
@ -174,6 +176,51 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
}
|
||||
}
|
||||
|
||||
public class KeyboardLayoutState {
|
||||
private boolean mIsValid;
|
||||
private boolean mIsAlphabetMode;
|
||||
private boolean mIsShiftLocked;
|
||||
private boolean mIsShifted;
|
||||
|
||||
public boolean isValid() {
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
public void save() {
|
||||
mIsAlphabetMode = isAlphabetMode();
|
||||
mIsShiftLocked = mIsAlphabetMode && isShiftLocked();
|
||||
mIsShifted = !mIsShiftLocked && isShiftedOrShiftLocked();
|
||||
mIsValid = true;
|
||||
}
|
||||
|
||||
public KeyboardId getKeyboardId() {
|
||||
if (!mIsValid) return mMainKeyboardId;
|
||||
|
||||
if (mIsAlphabetMode) {
|
||||
return mMainKeyboardId;
|
||||
} else {
|
||||
return mIsShifted ? mSymbolsShiftedKeyboardId : mSymbolsKeyboardId;
|
||||
}
|
||||
}
|
||||
|
||||
public void restore() {
|
||||
if (!mIsValid) return;
|
||||
mIsValid = false;
|
||||
|
||||
if (mIsAlphabetMode) {
|
||||
final boolean isAlphabetMode = isAlphabetMode();
|
||||
final boolean isShiftLocked = isAlphabetMode && isShiftLocked();
|
||||
final boolean isShifted = !isShiftLocked && isShiftedOrShiftLocked();
|
||||
if (mIsShiftLocked != isShiftLocked) {
|
||||
toggleCapsLock();
|
||||
} else if (mIsShifted != isShifted) {
|
||||
onPressShift(false);
|
||||
onReleaseShift(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static KeyboardSwitcher getInstance() {
|
||||
return sInstance;
|
||||
}
|
||||
|
@ -220,22 +267,34 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
}
|
||||
|
||||
public void loadKeyboard(EditorInfo editorInfo, Settings.Values settingsValues) {
|
||||
mSwitchState = SWITCH_STATE_ALPHA;
|
||||
try {
|
||||
mMainKeyboardId = getKeyboardId(editorInfo, false, false, settingsValues);
|
||||
mSymbolsKeyboardId = getKeyboardId(editorInfo, true, false, settingsValues);
|
||||
mSymbolsShiftedKeyboardId = getKeyboardId(editorInfo, true, true, settingsValues);
|
||||
setKeyboard(getKeyboard(mMainKeyboardId));
|
||||
setKeyboard(getKeyboard(mSavedKeyboardState.getKeyboardId()));
|
||||
updateShiftState();
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(TAG, "loading keyboard failed: " + mMainKeyboardId, e);
|
||||
LatinImeLogger.logOnException(mMainKeyboardId.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public KeyboardLayoutState getKeyboardState() {
|
||||
return mSavedKeyboardState;
|
||||
}
|
||||
|
||||
public void onFinishInputView() {
|
||||
mIsAutoCorrectionActive = false;
|
||||
}
|
||||
|
||||
public void onHideWindow() {
|
||||
mIsAutoCorrectionActive = false;
|
||||
}
|
||||
|
||||
public void registerWindowWidth() {
|
||||
mWindowWidthCache.registerWidth();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
// TODO: This hack should be removed when display metric returns a proper width.
|
||||
|
@ -248,21 +307,41 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
return;
|
||||
// Reload keyboard with new width.
|
||||
final KeyboardId newId = mCurrentId.cloneWithNewGeometry(conf.orientation, width);
|
||||
mInputMethodService.mHandler.postRestoreKeyboardLayout();
|
||||
setKeyboard(getKeyboard(newId));
|
||||
}
|
||||
|
||||
private void setKeyboard(final Keyboard newKeyboard) {
|
||||
private void setKeyboard(final Keyboard keyboard) {
|
||||
final Keyboard oldKeyboard = mKeyboardView.getKeyboard();
|
||||
mKeyboardView.setKeyboard(newKeyboard);
|
||||
mCurrentId = newKeyboard.mId;
|
||||
mKeyboardView.setKeyboard(keyboard);
|
||||
mCurrentId = keyboard.mId;
|
||||
mSwitchState = getSwitchState(mCurrentId);
|
||||
updateShiftLockState(keyboard);
|
||||
mKeyboardView.setKeyPreviewPopupEnabled(
|
||||
Settings.Values.isKeyPreviewPopupEnabled(mPrefs, mResources),
|
||||
Settings.Values.getKeyPreviewPopupDismissDelay(mPrefs, mResources));
|
||||
final boolean localeChanged = (oldKeyboard == null)
|
||||
|| !newKeyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale);
|
||||
|| !keyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale);
|
||||
mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(localeChanged);
|
||||
}
|
||||
|
||||
private int getSwitchState(KeyboardId id) {
|
||||
return id.equals(mMainKeyboardId) ? SWITCH_STATE_ALPHA : SWITCH_STATE_SYMBOL_BEGIN;
|
||||
}
|
||||
|
||||
private void updateShiftLockState(Keyboard keyboard) {
|
||||
if (mCurrentId.equals(mSymbolsShiftedKeyboardId)) {
|
||||
// Symbol keyboard may have an ALT key that has a caps lock style indicator (a.k.a.
|
||||
// sticky shift key). To show or dismiss the indicator, we need to call setShiftLocked()
|
||||
// that takes care of the current keyboard having such ALT key or not.
|
||||
keyboard.setShiftLocked(keyboard.hasShiftLockKey());
|
||||
} else if (mCurrentId.equals(mSymbolsKeyboardId)) {
|
||||
// Symbol keyboard has an ALT key that has a caps lock style indicator. To disable the
|
||||
// indicator, we need to call setShiftLocked(false).
|
||||
keyboard.setShiftLocked(false);
|
||||
}
|
||||
}
|
||||
|
||||
private LatinKeyboard getKeyboard(KeyboardId id) {
|
||||
final SoftReference<LatinKeyboard> ref = mKeyboardCache.get(id);
|
||||
LatinKeyboard keyboard = (ref == null) ? null : ref.get();
|
||||
|
@ -605,7 +684,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
+ " symbolKeyState=" + mSymbolKeyState);
|
||||
mShiftKeyState.onOtherKeyPressed();
|
||||
mSymbolKeyState.onOtherKeyPressed();
|
||||
mWindowWidthCache.registerWidth();
|
||||
}
|
||||
|
||||
public void onCancelInput() {
|
||||
|
@ -626,15 +704,8 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
if (mCurrentId.equals(mSymbolsKeyboardId)
|
||||
|| !mCurrentId.equals(mSymbolsShiftedKeyboardId)) {
|
||||
keyboard = getKeyboard(mSymbolsShiftedKeyboardId);
|
||||
// Symbol keyboard may have an ALT key that has a caps lock style indicator (a.k.a.
|
||||
// sticky shift key). To show or dismiss the indicator, we need to call setShiftLocked()
|
||||
// that takes care of the current keyboard having such ALT key or not.
|
||||
keyboard.setShiftLocked(keyboard.hasShiftLockKey());
|
||||
} else {
|
||||
keyboard = getKeyboard(mSymbolsKeyboardId);
|
||||
// Symbol keyboard has an ALT key that has a caps lock style indicator. To disable the
|
||||
// indicator, we need to call setShiftLocked(false).
|
||||
keyboard.setShiftLocked(false);
|
||||
}
|
||||
setKeyboard(keyboard);
|
||||
}
|
||||
|
@ -655,10 +726,8 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
private void toggleKeyboardMode() {
|
||||
if (mCurrentId.equals(mMainKeyboardId)) {
|
||||
setKeyboard(getKeyboard(mSymbolsKeyboardId));
|
||||
mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
|
||||
} else {
|
||||
setKeyboard(getKeyboard(mMainKeyboardId));
|
||||
mSwitchState = SWITCH_STATE_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ import com.android.inputmethod.keyboard.Key;
|
|||
import com.android.inputmethod.keyboard.Keyboard;
|
||||
import com.android.inputmethod.keyboard.KeyboardActionListener;
|
||||
import com.android.inputmethod.keyboard.KeyboardSwitcher;
|
||||
import com.android.inputmethod.keyboard.KeyboardSwitcher.KeyboardLayoutState;
|
||||
import com.android.inputmethod.keyboard.KeyboardView;
|
||||
import com.android.inputmethod.keyboard.LatinKeyboard;
|
||||
import com.android.inputmethod.keyboard.LatinKeyboardView;
|
||||
|
@ -112,6 +113,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
// Key events coming any faster than this are long-presses.
|
||||
private static final int QUICK_PRESS = 200;
|
||||
|
||||
private static final int SCREEN_ORIENTATION_CHANGE_DETECTION_DELAY = 2;
|
||||
private static final int ACCUMULATE_START_INPUT_VIEW_DELAY = 20;
|
||||
private static final int RESTORE_KEYBOARD_STATE_DELAY = 200;
|
||||
|
||||
/**
|
||||
* The name of the scheme used by the Package Manager to warn of a new package installation,
|
||||
* replacement or removal.
|
||||
|
@ -218,6 +223,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
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 final int MSG_RESTORE_KEYBOARD_LAYOUT = 10;
|
||||
|
||||
private static class OrientationChangeArgs {
|
||||
public final int mOldWidth;
|
||||
|
@ -302,6 +308,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
case MSG_START_INPUT_VIEW:
|
||||
latinIme.onStartInputView((EditorInfo)msg.obj, false);
|
||||
break;
|
||||
case MSG_RESTORE_KEYBOARD_LAYOUT:
|
||||
removeMessages(MSG_UPDATE_SHIFT_STATE);
|
||||
((KeyboardLayoutState)msg.obj).restore();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,14 +402,29 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
return hasMessages(MSG_SPACE_TYPED);
|
||||
}
|
||||
|
||||
public void postRestoreKeyboardLayout() {
|
||||
final LatinIME latinIme = getOuterInstance();
|
||||
final KeyboardLayoutState state = latinIme.mKeyboardSwitcher.getKeyboardState();
|
||||
if (state.isValid()) {
|
||||
removeMessages(MSG_RESTORE_KEYBOARD_LAYOUT);
|
||||
sendMessageDelayed(
|
||||
obtainMessage(MSG_RESTORE_KEYBOARD_LAYOUT, state),
|
||||
RESTORE_KEYBOARD_STATE_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
// Will confirm whether orientation change has finished or not again.
|
||||
sendMessageDelayed(obtainMessage(MSG_CONFIRM_ORIENTATION_CHANGE, args),
|
||||
SCREEN_ORIENTATION_CHANGE_DETECTION_DELAY);
|
||||
}
|
||||
|
||||
public void startOrientationChanging(int oldw, int oldh) {
|
||||
postConfirmOrientationChange(new OrientationChangeArgs(oldw, oldh));
|
||||
final LatinIME latinIme = getOuterInstance();
|
||||
latinIme.mKeyboardSwitcher.getKeyboardState().save();
|
||||
postRestoreKeyboardLayout();
|
||||
}
|
||||
|
||||
public boolean postStartInputView(EditorInfo attribute) {
|
||||
|
@ -407,7 +432,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
removeMessages(MSG_START_INPUT_VIEW);
|
||||
// Postpone onStartInputView 20ms afterward and see if orientation change has
|
||||
// finished.
|
||||
sendMessageDelayed(obtainMessage(MSG_START_INPUT_VIEW, attribute), 20);
|
||||
sendMessageDelayed(obtainMessage(MSG_START_INPUT_VIEW, attribute),
|
||||
ACCUMULATE_START_INPUT_VIEW_DELAY);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -596,6 +622,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
|
||||
@Override
|
||||
public void onStartInputView(EditorInfo attribute, boolean restarting) {
|
||||
mHandler.postRestoreKeyboardLayout();
|
||||
if (mHandler.postStartInputView(attribute)) {
|
||||
return;
|
||||
}
|
||||
|
@ -649,7 +676,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
|
||||
if (mSubtypeSwitcher.isKeyboardMode()) {
|
||||
switcher.loadKeyboard(attribute, mSettingsValues);
|
||||
switcher.updateShiftState();
|
||||
}
|
||||
|
||||
if (mCandidateView != null)
|
||||
|
@ -738,7 +764,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
super.onFinishInput();
|
||||
|
||||
LatinImeLogger.commit();
|
||||
mKeyboardSwitcher.onAutoCorrectionStateChanged(false);
|
||||
|
||||
mVoiceProxy.flushVoiceInputLogs(mConfigurationChanging);
|
||||
|
||||
|
@ -751,6 +776,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
@Override
|
||||
public void onFinishInputView(boolean finishingInput) {
|
||||
super.onFinishInputView(finishingInput);
|
||||
mKeyboardSwitcher.onFinishInputView();
|
||||
KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
|
||||
if (inputView != null) inputView.cancelAllMessages();
|
||||
// Remove pending messages related to update suggestions
|
||||
|
@ -1962,16 +1988,16 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), mSettingsValues);
|
||||
initSuggest();
|
||||
loadSettings();
|
||||
mKeyboardSwitcher.updateShiftState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPress(int primaryCode, boolean withSliding) {
|
||||
if (mKeyboardSwitcher.isVibrateAndSoundFeedbackRequired()) {
|
||||
final KeyboardSwitcher switcher = mKeyboardSwitcher;
|
||||
switcher.registerWindowWidth();
|
||||
if (switcher.isVibrateAndSoundFeedbackRequired()) {
|
||||
vibrate();
|
||||
playKeyClick(primaryCode);
|
||||
}
|
||||
KeyboardSwitcher switcher = mKeyboardSwitcher;
|
||||
final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
|
||||
if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) {
|
||||
switcher.onPressShift(withSliding);
|
||||
|
|
Loading…
Reference in a new issue