am 1fdb8f31: Define shortcuts for toggling IME layouts.
* commit '1fdb8f31562eeef78167585a878eb0450310036b': Define shortcuts for toggling IME layouts.main
commit
1194ad63ee
|
@ -91,4 +91,22 @@
|
||||||
<fraction name="config_emoji_keyboard_row_height">33%p</fraction>
|
<fraction name="config_emoji_keyboard_row_height">33%p</fraction>
|
||||||
<fraction name="config_emoji_keyboard_key_letter_size">68%p</fraction>
|
<fraction name="config_emoji_keyboard_key_letter_size">68%p</fraction>
|
||||||
<integer name="config_emoji_keyboard_max_page_key_count">21</integer>
|
<integer name="config_emoji_keyboard_max_page_key_count">21</integer>
|
||||||
|
|
||||||
|
<!-- Key codes of hardware keys that can be used to toggle the Emoji layout.
|
||||||
|
Each array defines a comma-separated tuple containing:
|
||||||
|
1. Key code constant from android.view.KeyEvent
|
||||||
|
2. Meta mask (if any) from android.view.KeyEvent
|
||||||
|
Used in EmojiAltPhysicalKeyDetector and KeyboardSwitcher. -->
|
||||||
|
<string-array name="keyboard_switcher_emoji" translatable="false">
|
||||||
|
<item>57,16</item> <!-- KeyEvent.KEYCODE_ALT_LEFT , KeyEvent.META_ALT_LEFT_ON -->
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<!-- Key codes of hardware keys that can be used to toggle the Symbols (Shifted) layout.
|
||||||
|
Each array defines a comma-separated tuple containing:
|
||||||
|
1. Key code constant from android.view.KeyEvent
|
||||||
|
2. Meta mask (if any) from android.view.KeyEvent
|
||||||
|
Used in EmojiAltPhysicalKeyDetector and KeyboardSwitcher. -->
|
||||||
|
<string-array name="keyboard_switcher_symbols_shifted" translatable="false">
|
||||||
|
<item>58,32</item> <!-- KeyEvent.KEYCODE_ALT_RIGHT , KeyEvent.META_ALT_RIGHT_ON -->
|
||||||
|
</string-array>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -44,6 +44,8 @@ import com.android.inputmethod.latin.utils.RecapitalizeStatus;
|
||||||
import com.android.inputmethod.latin.utils.ResourceUtils;
|
import com.android.inputmethod.latin.utils.ResourceUtils;
|
||||||
import com.android.inputmethod.latin.utils.ScriptUtils;
|
import com.android.inputmethod.latin.utils.ScriptUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
private static final String TAG = KeyboardSwitcher.class.getSimpleName();
|
private static final String TAG = KeyboardSwitcher.class.getSimpleName();
|
||||||
|
|
||||||
|
@ -139,15 +141,18 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setKeyboard(final Keyboard keyboard) {
|
private void setKeyboard(
|
||||||
|
@Nonnull final int keyboardId,
|
||||||
|
@Nonnull final KeyboardSwitchState toggleState) {
|
||||||
// Make {@link MainKeyboardView} visible and hide {@link EmojiPalettesView}.
|
// Make {@link MainKeyboardView} visible and hide {@link EmojiPalettesView}.
|
||||||
final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent();
|
final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent();
|
||||||
setMainKeyboardFrame(currentSettingsValues);
|
setMainKeyboardFrame(currentSettingsValues, toggleState);
|
||||||
// TODO: pass this object to setKeyboard instead of getting the current values.
|
// TODO: pass this object to setKeyboard instead of getting the current values.
|
||||||
final MainKeyboardView keyboardView = mKeyboardView;
|
final MainKeyboardView keyboardView = mKeyboardView;
|
||||||
final Keyboard oldKeyboard = keyboardView.getKeyboard();
|
final Keyboard oldKeyboard = keyboardView.getKeyboard();
|
||||||
keyboardView.setKeyboard(keyboard);
|
final Keyboard newKeyboard = mKeyboardLayoutSet.getKeyboard(keyboardId);
|
||||||
mCurrentInputView.setKeyboardTopPadding(keyboard.mTopPadding);
|
keyboardView.setKeyboard(newKeyboard);
|
||||||
|
mCurrentInputView.setKeyboardTopPadding(newKeyboard.mTopPadding);
|
||||||
keyboardView.setKeyPreviewPopupEnabled(
|
keyboardView.setKeyPreviewPopupEnabled(
|
||||||
currentSettingsValues.mKeyPreviewPopupOn,
|
currentSettingsValues.mKeyPreviewPopupOn,
|
||||||
currentSettingsValues.mKeyPreviewPopupDismissDelay);
|
currentSettingsValues.mKeyPreviewPopupDismissDelay);
|
||||||
|
@ -161,9 +166,9 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
currentSettingsValues.mKeyPreviewDismissDuration);
|
currentSettingsValues.mKeyPreviewDismissDuration);
|
||||||
keyboardView.updateShortcutKey(mRichImm.isShortcutImeReady());
|
keyboardView.updateShortcutKey(mRichImm.isShortcutImeReady());
|
||||||
final boolean subtypeChanged = (oldKeyboard == null)
|
final boolean subtypeChanged = (oldKeyboard == null)
|
||||||
|| !keyboard.mId.mSubtype.equals(oldKeyboard.mId.mSubtype);
|
|| !newKeyboard.mId.mSubtype.equals(oldKeyboard.mId.mSubtype);
|
||||||
final int languageOnSpacebarFormatType = LanguageOnSpacebarUtils
|
final int languageOnSpacebarFormatType = LanguageOnSpacebarUtils
|
||||||
.getLanguageOnSpacebarFormatType(keyboard.mId.mSubtype);
|
.getLanguageOnSpacebarFormatType(newKeyboard.mId.mSubtype);
|
||||||
final boolean hasMultipleEnabledIMEsOrSubtypes = mRichImm
|
final boolean hasMultipleEnabledIMEsOrSubtypes = mRichImm
|
||||||
.hasMultipleEnabledIMEsOrSubtypes(true /* shouldIncludeAuxiliarySubtypes */);
|
.hasMultipleEnabledIMEsOrSubtypes(true /* shouldIncludeAuxiliarySubtypes */);
|
||||||
keyboardView.startDisplayLanguageOnSpacebar(subtypeChanged, languageOnSpacebarFormatType,
|
keyboardView.startDisplayLanguageOnSpacebar(subtypeChanged, languageOnSpacebarFormatType,
|
||||||
|
@ -205,7 +210,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
if (DEBUG_ACTION) {
|
if (DEBUG_ACTION) {
|
||||||
Log.d(TAG, "setAlphabetKeyboard");
|
Log.d(TAG, "setAlphabetKeyboard");
|
||||||
}
|
}
|
||||||
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET));
|
setKeyboard(KeyboardId.ELEMENT_ALPHABET, KeyboardSwitchState.OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements {@link KeyboardState.SwitchActions}.
|
// Implements {@link KeyboardState.SwitchActions}.
|
||||||
|
@ -214,7 +219,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
if (DEBUG_ACTION) {
|
if (DEBUG_ACTION) {
|
||||||
Log.d(TAG, "setAlphabetManualShiftedKeyboard");
|
Log.d(TAG, "setAlphabetManualShiftedKeyboard");
|
||||||
}
|
}
|
||||||
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED));
|
setKeyboard(KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED, KeyboardSwitchState.OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements {@link KeyboardState.SwitchActions}.
|
// Implements {@link KeyboardState.SwitchActions}.
|
||||||
|
@ -223,7 +228,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
if (DEBUG_ACTION) {
|
if (DEBUG_ACTION) {
|
||||||
Log.d(TAG, "setAlphabetAutomaticShiftedKeyboard");
|
Log.d(TAG, "setAlphabetAutomaticShiftedKeyboard");
|
||||||
}
|
}
|
||||||
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED));
|
setKeyboard(KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED, KeyboardSwitchState.OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements {@link KeyboardState.SwitchActions}.
|
// Implements {@link KeyboardState.SwitchActions}.
|
||||||
|
@ -232,7 +237,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
if (DEBUG_ACTION) {
|
if (DEBUG_ACTION) {
|
||||||
Log.d(TAG, "setAlphabetShiftLockedKeyboard");
|
Log.d(TAG, "setAlphabetShiftLockedKeyboard");
|
||||||
}
|
}
|
||||||
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED));
|
setKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED, KeyboardSwitchState.OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements {@link KeyboardState.SwitchActions}.
|
// Implements {@link KeyboardState.SwitchActions}.
|
||||||
|
@ -241,7 +246,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
if (DEBUG_ACTION) {
|
if (DEBUG_ACTION) {
|
||||||
Log.d(TAG, "setAlphabetShiftLockShiftedKeyboard");
|
Log.d(TAG, "setAlphabetShiftLockShiftedKeyboard");
|
||||||
}
|
}
|
||||||
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED));
|
setKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED, KeyboardSwitchState.OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements {@link KeyboardState.SwitchActions}.
|
// Implements {@link KeyboardState.SwitchActions}.
|
||||||
|
@ -250,11 +255,29 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
if (DEBUG_ACTION) {
|
if (DEBUG_ACTION) {
|
||||||
Log.d(TAG, "setSymbolsKeyboard");
|
Log.d(TAG, "setSymbolsKeyboard");
|
||||||
}
|
}
|
||||||
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_SYMBOLS));
|
setKeyboard(KeyboardId.ELEMENT_SYMBOLS, KeyboardSwitchState.OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMainKeyboardFrame(final SettingsValues settingsValues) {
|
// Implements {@link KeyboardState.SwitchActions}.
|
||||||
final int visibility = settingsValues.mHasHardwareKeyboard ? View.GONE : View.VISIBLE;
|
@Override
|
||||||
|
public void setSymbolsShiftedKeyboard() {
|
||||||
|
if (DEBUG_ACTION) {
|
||||||
|
Log.d(TAG, "setSymbolsShiftedKeyboard");
|
||||||
|
}
|
||||||
|
setKeyboard(KeyboardId.ELEMENT_SYMBOLS_SHIFTED, KeyboardSwitchState.SYMBOLS_SHIFTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isImeSuppressedByHardwareKeyboard(
|
||||||
|
@Nonnull final SettingsValues settingsValues,
|
||||||
|
@Nonnull final KeyboardSwitchState toggleState) {
|
||||||
|
return settingsValues.mHasHardwareKeyboard && toggleState == KeyboardSwitchState.HIDDEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setMainKeyboardFrame(
|
||||||
|
@Nonnull final SettingsValues settingsValues,
|
||||||
|
@Nonnull final KeyboardSwitchState toggleState) {
|
||||||
|
final int visibility = isImeSuppressedByHardwareKeyboard(settingsValues, toggleState)
|
||||||
|
? View.GONE : View.VISIBLE;
|
||||||
mKeyboardView.setVisibility(visibility);
|
mKeyboardView.setVisibility(visibility);
|
||||||
// The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}.
|
// The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}.
|
||||||
// @see #getVisibleKeyboardView() and
|
// @see #getVisibleKeyboardView() and
|
||||||
|
@ -282,24 +305,55 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
mEmojiPalettesView.setVisibility(View.VISIBLE);
|
mEmojiPalettesView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onToggleEmojiKeyboard() {
|
public enum KeyboardSwitchState {
|
||||||
final boolean needsToLoadKeyboard = (mKeyboardLayoutSet == null);
|
HIDDEN(-1),
|
||||||
if (needsToLoadKeyboard || !isShowingEmojiPalettes()) {
|
SYMBOLS_SHIFTED(KeyboardId.ELEMENT_SYMBOLS_SHIFTED),
|
||||||
mLatinIME.startShowingInputView(needsToLoadKeyboard);
|
EMOJI(KeyboardId.ELEMENT_EMOJI_RECENTS),
|
||||||
setEmojiKeyboard();
|
OTHER(-1);
|
||||||
} else {
|
|
||||||
mLatinIME.stopShowingInputView();
|
final int mKeyboardId;
|
||||||
setAlphabetKeyboard();
|
|
||||||
|
KeyboardSwitchState(int keyboardId) {
|
||||||
|
mKeyboardId = keyboardId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements {@link KeyboardState.SwitchActions}.
|
public KeyboardSwitchState getKeyboardSwitchState() {
|
||||||
@Override
|
boolean hidden = !isShowingEmojiPalettes()
|
||||||
public void setSymbolsShiftedKeyboard() {
|
&& (mKeyboardLayoutSet == null
|
||||||
if (DEBUG_ACTION) {
|
|| mKeyboardView == null
|
||||||
Log.d(TAG, "setSymbolsShiftedKeyboard");
|
|| !mKeyboardView.isShown());
|
||||||
|
KeyboardSwitchState state;
|
||||||
|
if (hidden) {
|
||||||
|
return KeyboardSwitchState.HIDDEN;
|
||||||
|
} else if (isShowingEmojiPalettes()) {
|
||||||
|
return KeyboardSwitchState.EMOJI;
|
||||||
|
} else if (isShowingKeyboardId(KeyboardId.ELEMENT_SYMBOLS_SHIFTED)) {
|
||||||
|
return KeyboardSwitchState.SYMBOLS_SHIFTED;
|
||||||
|
}
|
||||||
|
return KeyboardSwitchState.OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onToggleKeyboard(@Nonnull final KeyboardSwitchState toggleState) {
|
||||||
|
KeyboardSwitchState currentState = getKeyboardSwitchState();
|
||||||
|
Log.w(TAG, "onToggleKeyboard() : Current = " + currentState + " : Toggle = " + toggleState);
|
||||||
|
if (currentState == toggleState) {
|
||||||
|
mLatinIME.stopShowingInputView();
|
||||||
|
mLatinIME.hideWindow();
|
||||||
|
setAlphabetKeyboard();
|
||||||
|
} else {
|
||||||
|
mLatinIME.startShowingInputView(true);
|
||||||
|
if (toggleState == KeyboardSwitchState.EMOJI) {
|
||||||
|
setEmojiKeyboard();
|
||||||
|
} else {
|
||||||
|
mEmojiPalettesView.stopEmojiPalettes();
|
||||||
|
mEmojiPalettesView.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
mMainKeyboardFrame.setVisibility(View.VISIBLE);
|
||||||
|
mKeyboardView.setVisibility(View.VISIBLE);
|
||||||
|
setKeyboard(toggleState.mKeyboardId, toggleState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_SYMBOLS_SHIFTED));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Future method for requesting an updating to the shift state.
|
// Future method for requesting an updating to the shift state.
|
||||||
|
@ -355,6 +409,19 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
mState.onEvent(event, currentAutoCapsState, currentRecapitalizeState);
|
mState.onEvent(event, currentAutoCapsState, currentRecapitalizeState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isShowingKeyboardId(@Nonnull int... keyboardIds) {
|
||||||
|
if (mKeyboardView == null || !mKeyboardView.isShown()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int activeKeyboardId = mKeyboardView.getKeyboard().mId.mElementId;
|
||||||
|
for (int keyboardId : keyboardIds) {
|
||||||
|
if (activeKeyboardId == keyboardId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isShowingEmojiPalettes() {
|
public boolean isShowingEmojiPalettes() {
|
||||||
return mEmojiPalettesView != null && mEmojiPalettesView.isShown();
|
return mEmojiPalettesView != null && mEmojiPalettesView.isShown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,88 +16,140 @@
|
||||||
|
|
||||||
package com.android.inputmethod.latin;
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
|
|
||||||
import com.android.inputmethod.keyboard.KeyboardSwitcher;
|
import com.android.inputmethod.keyboard.KeyboardSwitcher;
|
||||||
import com.android.inputmethod.latin.settings.Settings;
|
import com.android.inputmethod.latin.settings.Settings;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class for detecting Emoji-Alt physical key.
|
* A class for detecting Emoji-Alt physical key.
|
||||||
*/
|
*/
|
||||||
final class EmojiAltPhysicalKeyDetector {
|
final class EmojiAltPhysicalKeyDetector {
|
||||||
private static final String TAG = "EmojiAltPhysicalKeyDetector";
|
private static final String TAG = "EmojiAltPhysicalKeyDetector";
|
||||||
|
|
||||||
private final RichInputConnection mRichInputConnection;
|
private final Map<Integer, Integer> mEmojiSwitcherMap;
|
||||||
|
private final Map<Integer, Integer> mSymbolsShiftedSwitcherMap;
|
||||||
|
private final Map<Integer, Integer> mCombinedSwitcherMap;
|
||||||
|
|
||||||
// True if the Alt key has been used as a modifier. In this case the Alt key up isn't
|
// Set of keys codes that have been used as modifiers.
|
||||||
// recognized as an emoji key.
|
private Set<Integer> mActiveModifiers;
|
||||||
private boolean mAltHasBeenUsedAsAModifier;
|
|
||||||
|
|
||||||
public EmojiAltPhysicalKeyDetector(final RichInputConnection richInputConnection) {
|
public EmojiAltPhysicalKeyDetector(@Nonnull final Resources resources) {
|
||||||
mRichInputConnection = richInputConnection;
|
mEmojiSwitcherMap = parseSwitchDefinition(resources, R.array.keyboard_switcher_emoji);
|
||||||
|
mSymbolsShiftedSwitcherMap = parseSwitchDefinition(
|
||||||
|
resources, R.array.keyboard_switcher_symbols_shifted);
|
||||||
|
mCombinedSwitcherMap = new HashMap<>();
|
||||||
|
mCombinedSwitcherMap.putAll(mEmojiSwitcherMap);
|
||||||
|
mCombinedSwitcherMap.putAll(mSymbolsShiftedSwitcherMap);
|
||||||
|
mActiveModifiers = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<Integer, Integer> parseSwitchDefinition(
|
||||||
|
@Nonnull final Resources resources,
|
||||||
|
final int resourceId) {
|
||||||
|
final Map<Integer, Integer> definition = new HashMap<>();
|
||||||
|
final String name = resources.getResourceEntryName(resourceId);
|
||||||
|
final String[] values = resources.getStringArray(resourceId);
|
||||||
|
for (int i = 0; values != null && i < values.length; i++) {
|
||||||
|
String[] valuePair = values[i].split(",");
|
||||||
|
if (valuePair.length != 2) {
|
||||||
|
Log.w(TAG, "Expected 2 integers in " + name + "[" + i + "] : " + values[i]);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
definition.put(Integer.parseInt(valuePair[0]), Integer.parseInt(valuePair[1]));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Log.w(TAG, "Failed to parse " + name + "[" + i + "] : " + values[i], e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return definition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record a down key event.
|
* Determine whether an up key event came from a mapped modifier key.
|
||||||
* @param keyEvent a down key event.
|
*
|
||||||
*/
|
|
||||||
public void onKeyDown(final KeyEvent keyEvent) {
|
|
||||||
if (isAltKey(keyEvent)) {
|
|
||||||
mAltHasBeenUsedAsAModifier = false;
|
|
||||||
}
|
|
||||||
if (containsAltModifier(keyEvent)) {
|
|
||||||
mAltHasBeenUsedAsAModifier = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether an up key event is a special key up or not.
|
|
||||||
* @param keyEvent an up key event.
|
* @param keyEvent an up key event.
|
||||||
*/
|
*/
|
||||||
public void onKeyUp(final KeyEvent keyEvent) {
|
public void onKeyUp(@Nonnull final KeyEvent keyEvent) {
|
||||||
|
Log.d(TAG, "onKeyUp() : " + keyEvent);
|
||||||
|
if (!Settings.getInstance().getCurrent().mEnableEmojiAltPhysicalKey) {
|
||||||
|
// The feature is disabled.
|
||||||
|
Log.d(TAG, "onKeyUp() : Disabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (keyEvent.isCanceled()) {
|
if (keyEvent.isCanceled()) {
|
||||||
// This key up event was a part of key combinations and should be ignored.
|
// This key up event was a part of key combinations and should be ignored.
|
||||||
|
Log.d(TAG, "onKeyUp() : Canceled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!isAltKey(keyEvent)) {
|
final Integer mappedModifier = getMappedModifier(keyEvent);
|
||||||
mAltHasBeenUsedAsAModifier |= containsAltModifier(keyEvent);
|
if (mappedModifier != null) {
|
||||||
|
// If the key was modified by a mapped key, then ignore the next time
|
||||||
|
// the same modifier key comes up.
|
||||||
|
Log.d(TAG, "onKeyUp() : Using Modifier: " + mappedModifier);
|
||||||
|
mActiveModifiers.add(mappedModifier);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (containsAltModifier(keyEvent)) {
|
|
||||||
mAltHasBeenUsedAsAModifier = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!Settings.getInstance().getCurrent().mEnableEmojiAltPhysicalKey) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mAltHasBeenUsedAsAModifier) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
onEmojiAltKeyDetected();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void onEmojiAltKeyDetected() {
|
|
||||||
KeyboardSwitcher.getInstance().onToggleEmojiKeyboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isAltKey(final KeyEvent keyEvent) {
|
|
||||||
final int keyCode = keyEvent.getKeyCode();
|
final int keyCode = keyEvent.getKeyCode();
|
||||||
return keyCode == KeyEvent.KEYCODE_ALT_LEFT || keyCode == KeyEvent.KEYCODE_ALT_RIGHT;
|
if (mActiveModifiers.contains(keyCode)) {
|
||||||
|
// Used as a modifier, not a standalone key press.
|
||||||
|
Log.d(TAG, "onKeyUp() : Used as Modifier: " + keyCode);
|
||||||
|
mActiveModifiers.remove(keyCode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isMappedKeyCode(keyEvent)) {
|
||||||
|
// Nothing special about this key.
|
||||||
|
Log.d(TAG, "onKeyUp() : Not Mapped: " + keyCode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final KeyboardSwitcher switcher = KeyboardSwitcher.getInstance();
|
||||||
|
if (mEmojiSwitcherMap.keySet().contains(keyCode)) {
|
||||||
|
switcher.onToggleKeyboard(KeyboardSwitcher.KeyboardSwitchState.EMOJI);
|
||||||
|
} else if (mSymbolsShiftedSwitcherMap.keySet().contains(keyCode)) {
|
||||||
|
switcher.onToggleKeyboard(KeyboardSwitcher.KeyboardSwitchState.SYMBOLS_SHIFTED);
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "Cannot toggle on keyCode: " + keyCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean containsAltModifier(final KeyEvent keyEvent) {
|
/**
|
||||||
final int metaState = keyEvent.getMetaState();
|
* @param keyEvent pressed key event
|
||||||
// TODO: Support multiple keyboards. Take device id into account.
|
* @return true iff the user pressed a mapped modifier key.
|
||||||
switch (keyEvent.getKeyCode()) {
|
*/
|
||||||
case KeyEvent.KEYCODE_ALT_LEFT:
|
private boolean isMappedKeyCode(@Nonnull final KeyEvent keyEvent) {
|
||||||
// Return true if Left-Alt is pressed with Right-Alt pressed.
|
return mCombinedSwitcherMap.get(keyEvent.getKeyCode()) != null;
|
||||||
return (metaState & KeyEvent.META_ALT_RIGHT_ON) != 0;
|
|
||||||
case KeyEvent.KEYCODE_ALT_RIGHT:
|
|
||||||
// Return true if Right-Alt is pressed with Left-Alt pressed.
|
|
||||||
return (metaState & KeyEvent.META_ALT_LEFT_ON) != 0;
|
|
||||||
default:
|
|
||||||
return (metaState & (KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_RIGHT_ON)) != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param keyEvent pressed key event
|
||||||
|
* @return the mapped modifier used with this key opress, if any.
|
||||||
|
*/
|
||||||
|
private Integer getMappedModifier(@Nonnull final KeyEvent keyEvent) {
|
||||||
|
final int keyCode = keyEvent.getKeyCode();
|
||||||
|
final int metaState = keyEvent.getMetaState();
|
||||||
|
for (int mappedKeyCode : mCombinedSwitcherMap.keySet()) {
|
||||||
|
if (keyCode == mappedKeyCode) {
|
||||||
|
Log.d(TAG, "getMappedModifier() : KeyCode = MappedKeyCode = " + mappedKeyCode);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final Integer mappedMeta = mCombinedSwitcherMap.get(mappedKeyCode);
|
||||||
|
if (mappedMeta == null || mappedMeta.intValue() == -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((metaState & mappedMeta) != 0) {
|
||||||
|
Log.d(TAG, "getMappedModifier() : MetaState(" + metaState
|
||||||
|
+ ") contains MappedMeta(" + mappedMeta + ")");
|
||||||
|
return mappedKeyCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,8 +142,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
private RichInputMethodManager mRichImm;
|
private RichInputMethodManager mRichImm;
|
||||||
@UsedForTesting final KeyboardSwitcher mKeyboardSwitcher;
|
@UsedForTesting final KeyboardSwitcher mKeyboardSwitcher;
|
||||||
private final SubtypeState mSubtypeState = new SubtypeState();
|
private final SubtypeState mSubtypeState = new SubtypeState();
|
||||||
private final EmojiAltPhysicalKeyDetector mEmojiAltPhysicalKeyDetector =
|
private EmojiAltPhysicalKeyDetector mEmojiAltPhysicalKeyDetector;
|
||||||
new EmojiAltPhysicalKeyDetector(mInputLogic.mConnection);
|
|
||||||
private StatsUtilsManager mStatsUtilsManager;
|
private StatsUtilsManager mStatsUtilsManager;
|
||||||
// Working variable for {@link #startShowingInputView()} and
|
// Working variable for {@link #startShowingInputView()} and
|
||||||
// {@link #onEvaluateInputViewShown()}.
|
// {@link #onEvaluateInputViewShown()}.
|
||||||
|
@ -702,6 +701,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
mInputLogic.recycle();
|
mInputLogic.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isImeSuppressedByHardwareKeyboard() {
|
||||||
|
final KeyboardSwitcher switcher = KeyboardSwitcher.getInstance();
|
||||||
|
return switcher.isImeSuppressedByHardwareKeyboard(
|
||||||
|
mSettings.getCurrent(), switcher.getKeyboardSwitchState());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConfigurationChanged(final Configuration conf) {
|
public void onConfigurationChanged(final Configuration conf) {
|
||||||
SettingsValues settingsValues = mSettings.getCurrent();
|
SettingsValues settingsValues = mSettings.getCurrent();
|
||||||
|
@ -716,7 +721,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
// have a change in hardware keyboard configuration.
|
// have a change in hardware keyboard configuration.
|
||||||
loadSettings();
|
loadSettings();
|
||||||
settingsValues = mSettings.getCurrent();
|
settingsValues = mSettings.getCurrent();
|
||||||
if (settingsValues.mHasHardwareKeyboard) {
|
if (isImeSuppressedByHardwareKeyboard()) {
|
||||||
// We call cleanupInternalStateForFinishInput() because it's the right thing to do;
|
// We call cleanupInternalStateForFinishInput() because it's the right thing to do;
|
||||||
// however, it seems at the moment the framework is passing us a seemingly valid
|
// however, it seems at the moment the framework is passing us a seemingly valid
|
||||||
// but actually non-functional InputConnection object. So if this bug ever gets
|
// but actually non-functional InputConnection object. So if this bug ever gets
|
||||||
|
@ -874,7 +879,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
// can go into the correct mode, so we need to do some housekeeping here.
|
// can go into the correct mode, so we need to do some housekeeping here.
|
||||||
final boolean needToCallLoadKeyboardLater;
|
final boolean needToCallLoadKeyboardLater;
|
||||||
final Suggest suggest = mInputLogic.mSuggest;
|
final Suggest suggest = mInputLogic.mSuggest;
|
||||||
if (!currentSettingsValues.mHasHardwareKeyboard) {
|
if (!isImeSuppressedByHardwareKeyboard()) {
|
||||||
// The app calling setText() has the effect of clearing the composing
|
// The app calling setText() has the effect of clearing the composing
|
||||||
// span, so we should reset our state unconditionally, even if restarting is true.
|
// span, so we should reset our state unconditionally, even if restarting is true.
|
||||||
// We also tell the input logic about the combining rules for the current subtype, so
|
// We also tell the input logic about the combining rules for the current subtype, so
|
||||||
|
@ -1118,8 +1123,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final int inputHeight = mInputView.getHeight();
|
final int inputHeight = mInputView.getHeight();
|
||||||
final boolean hasHardwareKeyboard = settingsValues.mHasHardwareKeyboard;
|
if (isImeSuppressedByHardwareKeyboard() && !visibleKeyboardView.isShown()) {
|
||||||
if (hasHardwareKeyboard && visibleKeyboardView.getVisibility() == View.GONE) {
|
|
||||||
// If there is a hardware keyboard and a visible software keyboard view has been hidden,
|
// If there is a hardware keyboard and a visible software keyboard view has been hidden,
|
||||||
// no visual element will be shown on the screen.
|
// no visual element will be shown on the screen.
|
||||||
outInsets.contentTopInsets = inputHeight;
|
outInsets.contentTopInsets = inputHeight;
|
||||||
|
@ -1165,7 +1169,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onShowInputRequested(final int flags, final boolean configChange) {
|
public boolean onShowInputRequested(final int flags, final boolean configChange) {
|
||||||
if (Settings.getInstance().getCurrent().mHasHardwareKeyboard) {
|
if (isImeSuppressedByHardwareKeyboard()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return super.onShowInputRequested(flags, configChange);
|
return super.onShowInputRequested(flags, configChange);
|
||||||
|
@ -1182,7 +1186,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
@Override
|
@Override
|
||||||
public boolean onEvaluateFullscreenMode() {
|
public boolean onEvaluateFullscreenMode() {
|
||||||
final SettingsValues settingsValues = mSettings.getCurrent();
|
final SettingsValues settingsValues = mSettings.getCurrent();
|
||||||
if (settingsValues.mHasHardwareKeyboard) {
|
if (isImeSuppressedByHardwareKeyboard()) {
|
||||||
// If there is a hardware keyboard, disable full screen mode.
|
// If there is a hardware keyboard, disable full screen mode.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1646,8 +1650,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
// Hooks for hardware keyboard
|
// Hooks for hardware keyboard
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) {
|
public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) {
|
||||||
// TODO: This should be processed in {@link InputLogic}.
|
|
||||||
mEmojiAltPhysicalKeyDetector.onKeyDown(keyEvent);
|
|
||||||
if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) {
|
if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) {
|
||||||
return super.onKeyDown(keyCode, keyEvent);
|
return super.onKeyDown(keyCode, keyEvent);
|
||||||
}
|
}
|
||||||
|
@ -1668,7 +1670,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyUp(final int keyCode, final KeyEvent keyEvent) {
|
public boolean onKeyUp(final int keyCode, final KeyEvent keyEvent) {
|
||||||
// TODO: This should be processed in {@link InputLogic}.
|
if (mEmojiAltPhysicalKeyDetector == null) {
|
||||||
|
mEmojiAltPhysicalKeyDetector = new EmojiAltPhysicalKeyDetector(
|
||||||
|
getApplicationContext().getResources());
|
||||||
|
}
|
||||||
mEmojiAltPhysicalKeyDetector.onKeyUp(keyEvent);
|
mEmojiAltPhysicalKeyDetector.onKeyUp(keyEvent);
|
||||||
if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) {
|
if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) {
|
||||||
return super.onKeyUp(keyCode, keyEvent);
|
return super.onKeyUp(keyCode, keyEvent);
|
||||||
|
|
Loading…
Reference in New Issue