diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/InputAttributes.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/InputAttributes.java index 0f722989c..b2beb3d41 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/InputAttributes.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/InputAttributes.java @@ -27,7 +27,7 @@ public final class InputAttributes { private final String TAG = InputAttributes.class.getSimpleName(); final public String mTargetApplicationPackageName; - final public boolean mInputTypeNoAutoCorrect; + final public boolean mInputTypeShouldAutoCorrect; final public boolean mIsPasswordField; final public boolean mShouldShowSuggestions; final public boolean mMayOverrideShowingSuggestions; @@ -42,7 +42,7 @@ public final class InputAttributes { */ final public boolean mDisableGestureFloatingPreviewText; final public boolean mIsGeneralTextInput; - final private int mInputType; + final public int mInputType; final private EditorInfo mEditorInfo; final private String mPackageNameForPrivateImeOptions; @@ -73,7 +73,7 @@ public final class InputAttributes { } mShouldShowSuggestions = false; mMayOverrideShowingSuggestions = false; - mInputTypeNoAutoCorrect = false; + mInputTypeShouldAutoCorrect = false; mApplicationSpecifiedCompletionOn = false; mShouldInsertSpacesAutomatically = false; mShouldShowVoiceInputKey = false; @@ -82,6 +82,7 @@ public final class InputAttributes { mNoLearning = false; return; } + // inputClass == InputType.TYPE_CLASS_TEXT final int variation = inputType & InputType.TYPE_MASK_VARIATION; final boolean flagNoSuggestions = 0 != (inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); @@ -106,14 +107,16 @@ public final class InputAttributes { mDisableGestureFloatingPreviewText = InputAttributes.inPrivateImeOptions( mPackageNameForPrivateImeOptions, NO_FLOATING_GESTURE_PREVIEW, editorInfo); - // If it's a browser edit field and auto correct is not ON explicitly, then - // disable auto correction, but keep suggestions on. - // If NO_SUGGESTIONS is set, don't do prediction. - // If it's not multiline and the autoCorrect flag is not set, then don't correct - mInputTypeNoAutoCorrect = - (variation == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT && !flagAutoCorrect) - || flagNoSuggestions - || (!flagAutoCorrect && !flagMultiLine); + // autocorrect if explicitly wanted, but also for most multi-line input types (like AOSP keyboard) + // originally, URI and email were always excluded from autocorrect (in Suggest.java), but this is + // and unexpected place, and if the input field explicitly requests autocorrect we should follow the flag + mInputTypeShouldAutoCorrect = flagAutoCorrect || ( + flagMultiLine + && variation != InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT + && variation != InputType.TYPE_TEXT_VARIATION_URI + && !InputTypeUtils.isEmailVariation(variation) + && !flagNoSuggestions + ); mApplicationSpecifiedCompletionOn = flagAutoComplete && isFullscreenMode; @@ -274,7 +277,7 @@ public final class InputAttributes { return String.format( "%s: inputType=0x%08x%s%s%s%s%s targetApp=%s\n", getClass().getSimpleName(), mInputType, - (mInputTypeNoAutoCorrect ? " noAutoCorrect" : ""), + (mInputTypeShouldAutoCorrect ? " noAutoCorrect" : ""), (mIsPasswordField ? " password" : ""), (mShouldShowSuggestions ? " shouldShowSuggestions" : ""), (mApplicationSpecifiedCompletionOn ? " appSpecified" : ""), diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/LatinIME.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/LatinIME.java index 3be84da93..9a27a8f88 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/LatinIME.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/LatinIME.java @@ -724,7 +724,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mDictionaryFacilitator.resetDictionaries(this, locale, settingsValues.mUseContactsDictionary, settingsValues.mUsePersonalizedDicts, false, settingsValues.mAccount, "", this); - if (settingsValues.mAutoCorrectionEnabledPerUserSettings) { + if (settingsValues.mAutoCorrectEnabled) { mInputLogic.mSuggest.setAutoCorrectionThreshold(settingsValues.mAutoCorrectionThreshold); } } @@ -1036,7 +1036,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mainKeyboardView.closing(); currentSettingsValues = mSettings.getCurrent(); - if (currentSettingsValues.mAutoCorrectionEnabledPerUserSettings) { + if (currentSettingsValues.mAutoCorrectEnabled) { suggest.setAutoCorrectionThreshold(currentSettingsValues.mAutoCorrectionThreshold); } switcher.loadKeyboard(editorInfo, currentSettingsValues, getCurrentAutoCapsState(), getCurrentRecapitalizeState()); diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/Suggest.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/Suggest.java index 641f461da..edfac8b0a 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/Suggest.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/Suggest.java @@ -11,7 +11,6 @@ import org.dslul.openboard.inputmethod.latin.utils.Log; import org.dslul.openboard.inputmethod.annotations.UsedForTesting; import org.dslul.openboard.inputmethod.keyboard.Keyboard; -import org.dslul.openboard.inputmethod.keyboard.KeyboardId; import org.dslul.openboard.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import org.dslul.openboard.inputmethod.latin.common.ComposedData; import org.dslul.openboard.inputmethod.latin.common.Constants; @@ -201,7 +200,6 @@ public final class Suggest { settingsValuesForSuggestion, inputStyleIfNotPrediction, first.getWord(), typedWordString); }, isCorrectionEnabled, - keyboard.mId.mMode, wordComposer, suggestionResults, firstOccurrenceOfTypedWordInSuggestions, @@ -289,7 +287,6 @@ public final class Suggest { final List firstAndTypedWordEmptyInfos, final Runnable putEmptyWordSuggestions, final boolean isCorrectionEnabled, - final int keyboardIdMode, final WordComposer wordComposer, final SuggestionResults suggestionResults, final int firstOccurrenceOfTypedWordInSuggestions, @@ -336,6 +333,8 @@ public final class Suggest { // If correction is not enabled, we never auto-correct. This is for example for when // the setting "Auto-correction" is "off": we still suggest, but we don't auto-correct. if (!isCorrectionEnabled + // todo: can some parts be moved to isCorrectionEnabled? e.g. keyboardIdMode only depends on input type + // i guess then not mAutoCorrectionEnabledPerUserSettings should be read, but rather some isAutocorrectEnabled() // If the word does not allow to be auto-corrected, then we don't auto-correct. || !allowsToBeAutoCorrected // If we are doing prediction, then we never auto-correct of course @@ -351,10 +350,6 @@ public final class Suggest { || wordComposer.isMostlyCaps() // We never auto-correct when suggestions are resumed because it would be unexpected || wordComposer.isResumed() - // We don't autocorrect in URL or email input, since websites and emails can be - // deliberate misspellings of actual words - || keyboardIdMode == KeyboardId.MODE_URL - || keyboardIdMode == KeyboardId.MODE_EMAIL // If we don't have a main dictionary, we never want to auto-correct. The reason // for this is, the user may have a contact whose name happens to match a valid // word in their language, and it will unexpectedly auto-correct. For example, if diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/inputlogic/InputLogic.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/inputlogic/InputLogic.java index aa4006449..ccd349518 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/inputlogic/InputLogic.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/inputlogic/InputLogic.java @@ -999,7 +999,7 @@ public final class InputLogic { } // isComposingWord() may have changed since we stored wasComposing if (mWordComposer.isComposingWord()) { - if (settingsValues.mAutoCorrectionEnabledPerUserSettings) { + if (settingsValues.mAutoCorrectEnabled) { final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR : StringUtils.newSingleCodePointString(codePoint); commitCurrentAutoCorrection(settingsValues, separator, handler); @@ -2111,10 +2111,8 @@ public final class InputLogic { private boolean textBeforeCursorMayBeUrlOrSimilar(final SettingsValues settingsValues, final Boolean forAutoSpace) { final EditorInfo ei = getCurrentInputEditorInfo(); - // URL field and no space -> may be URL - // for whatever absurd reason long message, postal address and email subject have type values that return true when filtering for URI, see https://developer.android.com/reference/android/text/InputType - // so we really need to specifically require URI as only type variation - if (ei != null && (ei.inputType & 0x000000f0) == 0x00000010 && + // URL / mail field and no space -> may be URL + if (ei != null && (InputTypeUtils.isUriOrEmailType(ei.inputType)) && // we never want to commit the first part of the url, but we want to insert autospace if text might be a normal word (forAutoSpace ? mConnection.nonWordCodePointAndNoSpaceBeforeCursor(settingsValues.mSpacingAndPunctuations) // avoid detecting URL if it could be a word : !mConnection.spaceBeforeCursor())) @@ -2349,7 +2347,7 @@ public final class InputLogic { mWordComposer.isComposingWord() ? 2 : 1), keyboard, settingsValues.mSettingsValuesForSuggestion, - settingsValues.mAutoCorrectionEnabledPerUserSettings, + settingsValues.mAutoCorrectEnabled, inputStyle, sequenceNumber, callback); } diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/CorrectionSettingsFragment.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/CorrectionSettingsFragment.java index f0adb0fa1..9451a70b4 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/CorrectionSettingsFragment.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/CorrectionSettingsFragment.java @@ -74,6 +74,7 @@ public final class CorrectionSettingsFragment extends SubScreenFragment private void refreshEnabledSettings() { setPreferenceVisible(Settings.PREF_AUTO_CORRECTION_CONFIDENCE, Settings.readAutoCorrectEnabled(getSharedPreferences())); + setPreferenceVisible(Settings.PREF_MORE_AUTO_CORRECTION, Settings.readAutoCorrectEnabled(getSharedPreferences())); setPreferenceVisible(Settings.PREF_ADD_TO_PERSONAL_DICTIONARY, getSharedPreferences().getBoolean(Settings.PREF_KEY_USE_PERSONALIZED_DICTS, true)); setPreferenceVisible(Settings.PREF_ALWAYS_SHOW_SUGGESTIONS, getSharedPreferences().getBoolean(Settings.PREF_SHOW_SUGGESTIONS, true)); turnOffLookupContactsIfNoPermission(); diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java index 1453d5c57..e1c09d451 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java @@ -80,6 +80,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_COLOR_BACKGROUND_SUFFIX = "background"; public static final String PREF_AUTO_USER_COLOR_SUFFIX = "_auto"; public static final String PREF_AUTO_CORRECTION = "pref_key_auto_correction"; + public static final String PREF_MORE_AUTO_CORRECTION = "pref_more_auto_correction"; public static final String PREF_AUTO_CORRECTION_CONFIDENCE = "pref_key_auto_correction_confidence"; public static final String PREF_SHOW_SUGGESTIONS = "show_suggestions"; public static final String PREF_ALWAYS_SHOW_SUGGESTIONS = "pref_always_show_suggestions"; @@ -264,6 +265,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang return prefs.getBoolean(PREF_AUTO_CORRECTION, true); } + public static boolean readMoreAutoCorrectEnabled(final SharedPreferences prefs) { + return prefs.getBoolean(PREF_MORE_AUTO_CORRECTION, true); + } + public void toggleAutoCorrect() { mPrefs.edit().putBoolean(Settings.PREF_AUTO_CORRECTION, !readAutoCorrectEnabled(mPrefs)).apply(); } diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java index 3115a40af..3e06c9cef 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java @@ -11,7 +11,6 @@ import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.res.Configuration; import android.content.res.Resources; -import org.dslul.openboard.inputmethod.latin.utils.Log; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodSubtype; @@ -26,6 +25,8 @@ import org.dslul.openboard.inputmethod.latin.RichInputMethodManager; import org.dslul.openboard.inputmethod.latin.common.Colors; import org.dslul.openboard.inputmethod.latin.spellcheck.AndroidSpellCheckerService; import org.dslul.openboard.inputmethod.latin.utils.AsyncResultHolder; +import org.dslul.openboard.inputmethod.latin.utils.InputTypeUtils; +import org.dslul.openboard.inputmethod.latin.utils.Log; import org.dslul.openboard.inputmethod.latin.utils.MoreKeysUtilsKt; import org.dslul.openboard.inputmethod.latin.utils.ScriptUtils; import org.dslul.openboard.inputmethod.latin.utils.SubtypeSettingsKt; @@ -113,10 +114,10 @@ public class SettingsValues { // Deduced settings public final int mKeypressVibrationDuration; public final float mKeypressSoundVolume; - private final boolean mAutoCorrectEnabled; + public final boolean mAutoCorrectionEnabledPerUserSettings; + public final boolean mAutoCorrectEnabled; public final float mAutoCorrectionThreshold; public final int mScoreLimitForAutocorrect; - public final boolean mAutoCorrectionEnabledPerUserSettings; private final boolean mSuggestionsEnabledPerUserSettings; private final boolean mOverrideShowingSuggestions; public final SettingsValuesForSuggestion mSettingsValuesForSuggestion; @@ -159,7 +160,11 @@ public class SettingsValues { mUseDoubleSpacePeriod = prefs.getBoolean(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true) && inputAttributes.mIsGeneralTextInput; mBlockPotentiallyOffensive = Settings.readBlockPotentiallyOffensive(prefs, res); - mAutoCorrectEnabled = Settings.readAutoCorrectEnabled(prefs); + mUrlDetectionEnabled = prefs.getBoolean(Settings.PREF_URL_DETECTION, false); + mAutoCorrectionEnabledPerUserSettings = Settings.readAutoCorrectEnabled(prefs); + mAutoCorrectEnabled = mAutoCorrectionEnabledPerUserSettings + && (mInputAttributes.mInputTypeShouldAutoCorrect || Settings.readMoreAutoCorrectEnabled(prefs)) + && (mUrlDetectionEnabled || !InputTypeUtils.isUriOrEmailType(mInputAttributes.mInputType)); mAutoCorrectionThreshold = mAutoCorrectEnabled ? readAutoCorrectionThreshold(res, prefs) : AUTO_CORRECTION_DISABLED_THRESHOLD; @@ -187,8 +192,6 @@ public class SettingsValues { mAccount = null; // remove? or can it be useful somewhere? mGestureFloatingPreviewTextEnabled = !mInputAttributes.mDisableGestureFloatingPreviewText && prefs.getBoolean(Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, true); - mAutoCorrectionEnabledPerUserSettings = mAutoCorrectEnabled; - //&& !mInputAttributes.mInputTypeNoAutoCorrect; // follow that request or not? mOverrideShowingSuggestions = mInputAttributes.mMayOverrideShowingSuggestions && readSuggestionsOverrideEnabled(prefs); mSuggestionsEnabledPerUserSettings = (mInputAttributes.mShouldShowSuggestions && readSuggestionsEnabled(prefs)) || mOverrideShowingSuggestions; @@ -240,7 +243,6 @@ public class SettingsValues { mBlockPotentiallyOffensive, prefs.getBoolean(Settings.PREF_GESTURE_SPACE_AWARE, false) ); - mUrlDetectionEnabled = prefs.getBoolean(Settings.PREF_URL_DETECTION, false); mSpacingAndPunctuations = new SpacingAndPunctuations(res, mUrlDetectionEnabled); mBottomPaddingScale = prefs.getFloat(Settings.PREF_BOTTOM_PADDING_SCALE, DEFAULT_SIZE_SCALE); } @@ -251,7 +253,7 @@ public class SettingsValues { public boolean needsToLookupSuggestions() { return (mInputAttributes.mShouldShowSuggestions || mOverrideShowingSuggestions) - && (mAutoCorrectionEnabledPerUserSettings || isSuggestionsEnabledPerUserSettings()); + && (mAutoCorrectEnabled || isSuggestionsEnabledPerUserSettings()); } public boolean isSuggestionsEnabledPerUserSettings() { diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/utils/InputTypeUtils.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/utils/InputTypeUtils.java index 3fc348c4d..03d95c306 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/utils/InputTypeUtils.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/utils/InputTypeUtils.java @@ -64,6 +64,11 @@ public final class InputTypeUtils implements InputType { || isWebEmailAddressVariation(variation); } + public static boolean isUriOrEmailType(final int inputType) { + final int maskedInputType = inputType & TYPE_MASK_VARIATION; + return maskedInputType == TYPE_TEXT_VARIATION_URI || isEmailVariation(maskedInputType); + } + public static boolean isWebInputType(final int inputType) { final int maskedInputType = inputType & (TYPE_MASK_CLASS | TYPE_MASK_VARIATION); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 17de8fbab..a6ede47de 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -109,11 +109,14 @@ Block offensive words Do not suggest potentially offensive words - - + Auto-correction Spacebar and punctuation automatically correct mistyped words + + More auto-correction + + Auto-correct even when not explicitly requested by the input field Auto-correction confidence diff --git a/app/src/main/res/xml/prefs_screen_correction.xml b/app/src/main/res/xml/prefs_screen_correction.xml index 0d18317eb..efb09119d 100644 --- a/app/src/main/res/xml/prefs_screen_correction.xml +++ b/app/src/main/res/xml/prefs_screen_correction.xml @@ -31,6 +31,13 @@ android:defaultValue="true" android:persistent="true" /> + +