add options for language switch key, fixes #15

This commit is contained in:
Helium314 2023-09-09 08:29:06 +02:00
parent ed7e6cff04
commit cbca99843b
95 changed files with 189 additions and 341 deletions

View file

@ -133,7 +133,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
builder.setSubtype(mRichImm.getCurrentSubtype());
builder.setVoiceInputKeyEnabled(settingsValues.mShowsVoiceInputKey);
builder.setNumberRowEnabled(settingsValues.mShowsNumberRow);
builder.setLanguageSwitchKeyEnabled(mLatinIME.shouldShowLanguageSwitchKey());
builder.setLanguageSwitchKeyEnabled(settingsValues.isLanguageSwitchKeyEnabled());
builder.setEmojiKeyEnabled(settingsValues.mShowsEmojiKey);
builder.setSplitLayoutEnabledByUser(ProductionFlags.IS_SPLIT_KEYBOARD_SUPPORTED
&& settingsValues.mIsSplitKeyboardEnabled);

View file

@ -716,7 +716,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
final boolean selected = keyboardLayoutSetMatched && keyboardLayoutSetElementMatched
&& keyboardThemeMacthed && modeMatched && navigateNextMatched
&& navigatePreviousMatched && passwordInputMatched && clobberSettingsKeyMatched
&& hasShortcutKeyMatched && numberRowEnabledMatched && languageSwitchKeyEnabledMatched
&& hasShortcutKeyMatched && numberRowEnabledMatched && languageSwitchKeyEnabledMatched
&& emojiKeyEnabledMatched && isMultiLineMatched && imeActionMatched && isIconDefinedMatched
&& localeCodeMatched && languageCodeMatched && countryCodeMatched
&& splitLayoutMatched && oneHandedModeEnabledMatched;

View file

@ -62,7 +62,6 @@ import org.dslul.openboard.inputmethod.keyboard.KeyboardSwitcher;
import org.dslul.openboard.inputmethod.keyboard.MainKeyboardView;
import org.dslul.openboard.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
import org.dslul.openboard.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import org.dslul.openboard.inputmethod.latin.common.Colors;
import org.dslul.openboard.inputmethod.latin.common.Constants;
import org.dslul.openboard.inputmethod.latin.common.CoordinateUtils;
import org.dslul.openboard.inputmethod.latin.common.InputPointers;
@ -159,7 +158,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@UsedForTesting final KeyboardSwitcher mKeyboardSwitcher;
private final SubtypeState mSubtypeState = new SubtypeState();
private EmojiAltPhysicalKeyDetector mEmojiAltPhysicalKeyDetector;
private StatsUtilsManager mStatsUtilsManager;
private final StatsUtilsManager mStatsUtilsManager;
// Working variable for {@link #startShowingInputView()} and
// {@link #onEvaluateInputViewShown()}.
private boolean mIsExecutingStartShowingInputView;
@ -1418,13 +1417,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public boolean onCustomRequest(final int requestCode) {
if (isShowingOptionDialog()) return false;
switch (requestCode) {
case Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER:
if (mRichImm.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) {
InputMethodPickerKt.showInputMethodPicker(this, mRichImm, mKeyboardSwitcher.getMainKeyboardView().getWindowToken());
return true; // todo: don't show and return if dialog already shown? but how can this happen?
}
return false;
if (requestCode == Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER) {
if (mRichImm.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) {
InputMethodPickerKt.showInputMethodPicker(this, mRichImm, mKeyboardSwitcher.getMainKeyboardView().getWindowToken());
return true; // todo: don't show and return if dialog already shown? but how can this happen?
}
return false;
}
return false;
}
@ -1474,30 +1472,59 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return mOptionsDialog != null && mOptionsDialog.isShowing();
}
// TODO: Revise the language switch key behavior to make it much smarter and more reasonable.
// called when language switch key is pressed (either the keyboard key, or long-press comma)
public void switchToNextSubtype() {
if (shouldSwitchToOtherInputMethods()) {
// todo: this is the old behavior, is this actually wanted?
// maybe make the language switch key more configurable
boolean moreThanOneSubtype = mRichImm.getMyEnabledInputMethodSubtypeList(false).size() > 1;
final InputMethodSubtype nextSubtype = mRichImm.getNextSubtypeInThisIme(moreThanOneSubtype);
if (nextSubtype != null) {
switchToSubtype(nextSubtype);
} else {
// we are at end of the internal subtype list, switch to next input method
// (for now) don't care about which input method and subtype exactly, let the system choose
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
switchToNextInputMethod(false);
} else {
final IBinder token = getWindow().getWindow().getAttributes().token;
mRichImm.getInputMethodManager().switchToNextInputMethod(token, false);
}
}
final boolean switchSubtype = mSettings.getCurrent().mLanguageSwitchKeyToOtherSubtypes;
final boolean switchIme = mSettings.getCurrent().mLanguageSwitchKeyToOtherImes;
// switch IME if wanted and possible
if (switchIme && !switchSubtype && switchInputMethod())
return;
final boolean hasMoreThanOneSubtype = mRichImm.getMyEnabledInputMethodSubtypeList(false).size() > 1;
// switch subtype if wanted and possible
if (switchSubtype && !switchIme && hasMoreThanOneSubtype) {
// switch to previous subtype if current one was used, otherwise cycle through list
mSubtypeState.switchSubtype(mRichImm);
return;
}
// language key set to switch both, or language key is not shown on keyboard -> switch both
if (hasMoreThanOneSubtype && mSubtypeState.mCurrentSubtypeHasBeenUsed) {
mSubtypeState.switchSubtype(mRichImm);
return;
}
if (shouldSwitchToOtherInputMethods()) {
final InputMethodSubtype nextSubtype = mRichImm.getNextSubtypeInThisIme(false);
// todo (later): this will switch IME if we are at the end of the list, but ideally we
// want to switch IME only if all internal subtypes are unused
// -> need to store used/unused subtypes in mSubtypeState
if (nextSubtype != null) {
switchToSubtype(nextSubtype);
return;
} else if (switchInputMethod()){
return;
}
}
mSubtypeState.switchSubtype(mRichImm);
}
private boolean switchInputMethod() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
return switchToNextInputMethod(false);
final IBinder token = getWindow().getWindow().getAttributes().token;
return mRichImm.getInputMethodManager().switchToNextInputMethod(token, false);
}
@SuppressWarnings("deprecation")
public boolean shouldSwitchToOtherInputMethods() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
return shouldOfferSwitchingToNextInputMethod();
final IBinder token = getWindow().getWindow().getAttributes().token;
if (token == null) {
return mSettings.getCurrent().mLanguageSwitchKeyToOtherImes;
}
return mRichImm.getInputMethodManager().shouldOfferSwitchingToNextInputMethod(token);
}
public void switchInputMethodAndSubtype(final InputMethodInfo imi, final InputMethodSubtype subtype) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
switchInputMethod(imi.getId(), subtype);
@ -1972,10 +1999,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void debugDumpStateAndCrashWithException(final String context) {
final SettingsValues settingsValues = mSettings.getCurrent();
final StringBuilder s = new StringBuilder(settingsValues.toString());
s.append("\nAttributes : ").append(settingsValues.mInputAttributes)
.append("\nContext : ").append(context);
throw new RuntimeException(s.toString());
String s = settingsValues.toString() + "\nAttributes : " + settingsValues.mInputAttributes +
"\nContext : " + context;
throw new RuntimeException(s);
}
@Override
@ -1995,26 +2021,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// TODO: Dump all settings values
}
public boolean shouldSwitchToOtherInputMethods() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
return shouldOfferSwitchingToNextInputMethod();
// TODO: Revisit here to reorganize the settings. Probably we can/should use different
// strategy once the implementation of
// {@link InputMethodManager#shouldOfferSwitchingToNextInputMethod} is defined well.
final IBinder token = getWindow().getWindow().getAttributes().token;
if (token == null) {
return mSettings.getCurrent().mIncludesOtherImesInLanguageSwitchList;
}
return mRichImm.getInputMethodManager().shouldOfferSwitchingToNextInputMethod(token);
}
public boolean shouldShowLanguageSwitchKey() {
// TODO: Revisit here to reorganize the settings. Probably we can/should use different
// strategy once the implementation of
// {@link InputMethodManager#shouldOfferSwitchingToNextInputMethod} is defined well.
return mSettings.getCurrent().isLanguageSwitchKeyEnabled();
}
// slightly modified from Simple Keyboard: https://github.com/rkkr/simple-keyboard/blob/master/app/src/main/java/rkr/simplekeyboard/inputmethod/latin/LatinIME.java
private void setNavigationBarColor() {
final SettingsValues settingsValues = mSettings.getCurrent();

View file

@ -101,12 +101,6 @@ public final class Constants {
*/
public static final String EMOJI_CAPABLE = "EmojiCapable";
/**
* The subtype extra value used to indicate that this subtype requires a network
* connection to work.
*/
public static final String REQ_NETWORK_CONNECTIVITY = "requireNetworkConnectivity";
/**
* The subtype extra value used to indicate that the display name of this subtype
* contains a "%s" for printf-like replacement and it should be replaced by

View file

@ -95,7 +95,7 @@ public final class PreferencesSettingsFragment extends SubScreenFragment {
}
private void setupKeypressVibrationDurationSettings() {
final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(
final SeekBarDialogPreference pref = findPreference(
Settings.PREF_VIBRATION_DURATION_SETTINGS);
if (pref == null) {
return;
@ -139,7 +139,7 @@ public final class PreferencesSettingsFragment extends SubScreenFragment {
}
private void setupKeypressSoundVolumeSettings() {
final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(
final SeekBarDialogPreference pref = findPreference(
Settings.PREF_KEYPRESS_SOUND_VOLUME);
if (pref == null) {
return;
@ -197,7 +197,7 @@ public final class PreferencesSettingsFragment extends SubScreenFragment {
private void setupHistoryRetentionTimeSettings() {
final SharedPreferences prefs = getSharedPreferences();
final Resources res = getResources();
final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(
final SeekBarDialogPreference pref = findPreference(
Settings.PREF_CLIPBOARD_HISTORY_RETENTION_TIME);
if (pref == null) {
return;

View file

@ -96,14 +96,12 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT;
public static final boolean SHOULD_SHOW_LXX_SUGGESTION_UI =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
public static final String PREF_SHOW_LANGUAGE_SWITCH_KEY =
"pref_show_language_switch_key";
public static final String PREF_LANGUAGE_SWITCH_KEY =
"pref_language_switch_key";
public static final String PREF_SHOW_EMOJI_KEY =
"pref_show_emoji_key";
public static final String PREF_SHOW_CLIPBOARD_KEY =
"pref_show_clipboard_key";
public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST =
"pref_include_other_imes_in_language_switch_list";
public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles";
public static final String PREF_ENABLE_SPLIT_KEYBOARD = "pref_split_keyboard";
public static final String PREF_KEYBOARD_HEIGHT_SCALE = "pref_keyboard_height_scale";

View file

@ -71,11 +71,11 @@ public class SettingsValues {
public final boolean mSoundOn;
public final boolean mKeyPreviewPopupOn;
public final boolean mShowsVoiceInputKey;
public final boolean mIncludesOtherImesInLanguageSwitchList;
public final boolean mLanguageSwitchKeyToOtherImes;
public final boolean mLanguageSwitchKeyToOtherSubtypes;
public final boolean mShowsNumberRow;
public final boolean mShowsHints;
public final boolean mSpaceForLangChange;
public final boolean mShowsLanguageSwitchKey;
public final boolean mShowsEmojiKey;
public final boolean mShowsClipboardKey;
public final boolean mUsePersonalizedDicts;
@ -161,11 +161,12 @@ public class SettingsValues {
mSlidingKeyInputPreviewEnabled = prefs.getBoolean(
DebugSettings.PREF_SLIDING_KEY_INPUT_PREVIEW, true);
mShowsVoiceInputKey = needsToShowVoiceInputKey(prefs, res) && mInputAttributes.mShouldShowVoiceInputKey;
mIncludesOtherImesInLanguageSwitchList = !Settings.ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS || prefs.getBoolean(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, false) /* forcibly */;
final String languagePref = prefs.getString(Settings.PREF_LANGUAGE_SWITCH_KEY, "off");
mLanguageSwitchKeyToOtherImes = languagePref.equals("input_method") || languagePref.equals("both");
mLanguageSwitchKeyToOtherSubtypes = languagePref.equals("internal") || languagePref.equals("both");
mShowsNumberRow = prefs.getBoolean(Settings.PREF_SHOW_NUMBER_ROW, false);
mShowsHints = prefs.getBoolean(Settings.PREF_SHOW_HINTS, true);
mSpaceForLangChange = prefs.getBoolean(Settings.PREF_SPACE_TO_CHANGE_LANG, true);
mShowsLanguageSwitchKey = prefs.getBoolean(Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY, false);
mShowsEmojiKey = prefs.getBoolean(Settings.PREF_SHOW_EMOJI_KEY, false);
mShowsClipboardKey = prefs.getBoolean(Settings.PREF_SHOW_CLIPBOARD_KEY, false);
mUsePersonalizedDicts = prefs.getBoolean(Settings.PREF_KEY_USE_PERSONALIZED_DICTS, true);
@ -306,14 +307,18 @@ public class SettingsValues {
}
public boolean isLanguageSwitchKeyEnabled() {
if (!mShowsLanguageSwitchKey) {
if (!mLanguageSwitchKeyToOtherImes && !mLanguageSwitchKeyToOtherSubtypes) {
return false;
}
final RichInputMethodManager imm = RichInputMethodManager.getInstance();
if (mIncludesOtherImesInLanguageSwitchList) {
if (!mLanguageSwitchKeyToOtherSubtypes) {
return imm.hasMultipleEnabledIMEsOrSubtypes(false /* include aux subtypes */);
}
return imm.hasMultipleEnabledSubtypesInThisIme(false /* include aux subtypes */);
if (!mLanguageSwitchKeyToOtherImes) {
return imm.hasMultipleEnabledSubtypesInThisIme(false /* include aux subtypes */);
}
return imm.hasMultipleEnabledSubtypesInThisIme(false /* include aux subtypes */)
|| imm.hasMultipleEnabledIMEsOrSubtypes(false /* include aux subtypes */);
}
public boolean isSameInputType(final EditorInfo editorInfo) {
@ -410,10 +415,10 @@ public class SettingsValues {
sb.append("" + mKeyPreviewPopupOn);
sb.append("\n mShowsVoiceInputKey = ");
sb.append("" + mShowsVoiceInputKey);
sb.append("\n mIncludesOtherImesInLanguageSwitchList = ");
sb.append("" + mIncludesOtherImesInLanguageSwitchList);
sb.append("\n mShowsLanguageSwitchKey = ");
sb.append("" + mShowsLanguageSwitchKey);
sb.append("\n mLanguageSwitchKeyToOtherImes = ");
sb.append("" + mLanguageSwitchKeyToOtherImes);
sb.append("\n mLanguageSwitchKeyToOtherSubtypes = ");
sb.append("" + mLanguageSwitchKeyToOtherSubtypes);
sb.append("\n mUsePersonalizedDicts = ");
sb.append("" + mUsePersonalizedDicts);
sb.append("\n mUseDoubleSpacePeriod = ");