1
0
Fork 0

fixed invalid input mode state, causing invalid composing text popping up and invlalid status icon being displayed, when focusing different inputs of the same application

This commit is contained in:
Dimo Karaivanov 2023-02-13 13:57:51 +02:00
parent 74909aeb7e
commit 0f028cc572
5 changed files with 71 additions and 25 deletions

View file

@ -1,7 +1,6 @@
package io.github.sspanak.tt9.ime;
import android.inputmethodservice.InputMethodService;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
@ -84,22 +83,24 @@ abstract class KeyPadHandler extends InputMethodService {
public void onStartInput(EditorInfo inputField, boolean restarting) {
currentInputConnection = getCurrentInputConnection();
// Logger.d("T9.onStartInput", "inputType: " + inputField.inputType + " fieldId: " + inputField.fieldId + " fieldName: " + inputField.fieldName + " packageName: " + inputField.packageName);
mEditing = NON_EDIT;
// https://developer.android.com/reference/android/text/InputType#TYPE_NULL
// Special or limited input type. This means the input connection is not rich,
// or it can not process or show things like candidate text, nor retrieve the current text.
// We just let Android handle this input.
if (currentInputConnection == null || inputField == null || inputField.inputType == InputType.TYPE_NULL) {
onFinish();
return;
}
onStart(inputField);
}
@Override
public void onStartInputView(EditorInfo inputField, boolean restarting) {
onRestart(inputField);
}
@Override
public void onFinishInputView(boolean finishingInput) {
super.onFinishInputView(finishingInput);
if (mEditing == EDITING || mEditing == EDITING_NOSHOW) {
onFinishTyping();
}
}
/**
* This is called when the user is done editing a field. We can use this to
* reset our state.
@ -109,7 +110,7 @@ abstract class KeyPadHandler extends InputMethodService {
super.onFinishInput();
// Logger.d("onFinishInput", "When is this called?");
if (mEditing == EDITING || mEditing == EDITING_NOSHOW) {
onFinish();
onStop();
}
}
@ -333,6 +334,8 @@ abstract class KeyPadHandler extends InputMethodService {
// helpers
abstract protected void onInit();
abstract protected void onStart(EditorInfo inputField);
abstract protected void onFinish();
abstract protected void onRestart(EditorInfo inputField);
abstract protected void onFinishTyping();
abstract protected void onStop();
abstract protected View createSoftKeyView();
}

View file

@ -25,6 +25,7 @@ import io.github.sspanak.tt9.ui.UI;
public class TraditionalT9 extends KeyPadHandler {
// internal settings/data
private boolean isActive = false;
private EditorInfo inputField;
// input mode
@ -87,13 +88,12 @@ public class TraditionalT9 extends KeyPadHandler {
}
protected void onStart(EditorInfo inputField) {
this.inputField = inputField;
private void initTyping() {
// in case we are back from Settings screen, update the language list
mEnabledLanguages = settings.getEnabledLanguageIds();
validateLanguages();
// some input fields support only numbers or do not accept predictions
// some input fields support only numbers or are not suited for predictions (e.g. password fields)
determineAllowedInputModes();
mInputMode = InputModeValidator.validateMode(settings, mInputMode, allowedInputModes);
@ -101,8 +101,10 @@ public class TraditionalT9 extends KeyPadHandler {
// Some modes may want to change the default text case based on grammar rules.
determineNextTextCase();
InputModeValidator.validateTextCase(settings, mInputMode, settings.getTextCase());
}
// build the UI
private void initUi() {
UI.updateStatusIcon(this, mLanguage, mInputMode);
clearSuggestions();
@ -118,15 +120,43 @@ public class TraditionalT9 extends KeyPadHandler {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && mEditing != EDITING_STRICT_NUMERIC && mEditing != EDITING_DIALER) {
requestShowSelf(1);
}
restoreAddedWordIfAny();
}
protected void onFinish() {
clearSuggestions();
protected void onStart(EditorInfo input) {
this.inputField = input;
if (currentInputConnection == null || inputField == null || InputFieldHelper.isLimitedField(inputField)) {
// When the input is invalid or simple, let Android handle it.
onStop();
return;
}
initTyping();
initUi();
restoreAddedWordIfAny();
isActive = true;
}
protected void onRestart(EditorInfo inputField) {
if (!isActive) {
onStart(inputField);
}
}
protected void onFinishTyping() {
isActive = false;
hideStatusIcon();
mEditing = NON_EDIT;
}
protected void onStop() {
onFinishTyping();
clearSuggestions();
hideWindow();
softKeyHandler.hide();
@ -337,7 +367,7 @@ public class TraditionalT9 extends KeyPadHandler {
private boolean isSuggestionViewHidden() {
return mSuggestionView == null || !mSuggestionView.isShown();
return mSuggestionView == null || !mSuggestionView.hasElements();
}

View file

@ -38,6 +38,18 @@ public class InputFieldHelper {
}
/**
* isLimitedField
* Special or limited input type means the input connection is not rich,
* or it can not process or show things like candidate text, nor retrieve the current text.
*
* https://developer.android.com/reference/android/text/InputType#TYPE_NULL
*/
public static boolean isLimitedField(EditorInfo inputField) {
return inputField != null && inputField.inputType == InputType.TYPE_NULL;
}
/**
* isDialerField
* Dialer fields seem to take care of numbers and backspace on their own,

View file

@ -45,6 +45,7 @@ public class InputModeValidator {
public static InputMode validateMode(SettingsStore settings, InputMode inputMode, ArrayList<Integer> allowedModes) {
if (allowedModes.size() > 0 && allowedModes.contains(inputMode.getId())) {
inputMode.reset();
return inputMode;
}

View file

@ -82,7 +82,7 @@ public class SuggestionsView {
}
public boolean isShown() {
public boolean hasElements() {
return suggestions.size() > 0;
}