1
0
Fork 0

1. simplified suggestion scrolling; 2. hopefully fixed the 'spans can not have zero length' warning; 3. fixed repeated words popping over and over again, when scrolling the suggestions in Amazon Kindle app, on the Share Document screen (AppHacks established)

This commit is contained in:
Dimo Karaivanov 2023-08-22 18:22:07 +03:00
parent 77fd0db39b
commit e45744e0b4
5 changed files with 77 additions and 24 deletions

View file

@ -74,8 +74,8 @@ abstract class KeyPadHandler extends InputMethodService {
*/ */
@Override @Override
public void onStartInput(EditorInfo inputField, boolean restarting) { public void onStartInput(EditorInfo inputField, boolean restarting) {
// Logger.d("T9.onStartInput", "inputType: " + inputField.inputType + " fieldId: " + inputField.fieldId + " fieldName: " + inputField.fieldName + " packageName: " + inputField.packageName + " privateImeOptions: " + inputField.privateImeOptions + " imeOptions: " + inputField.imeOptions + " extras: " + inputField.extras);
currentInputConnection = getCurrentInputConnection(); currentInputConnection = getCurrentInputConnection();
// Logger.d("T9.onStartInput", "inputType: " + inputField.inputType + " fieldId: " + inputField.fieldId + " fieldName: " + inputField.fieldName + " packageName: " + inputField.packageName);
onStart(inputField); onStart(inputField);
} }

View file

@ -18,6 +18,7 @@ import java.util.List;
import io.github.sspanak.tt9.Logger; import io.github.sspanak.tt9.Logger;
import io.github.sspanak.tt9.R; import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.db.DictionaryDb; import io.github.sspanak.tt9.db.DictionaryDb;
import io.github.sspanak.tt9.ime.helpers.AppHacks;
import io.github.sspanak.tt9.ime.helpers.InputModeValidator; import io.github.sspanak.tt9.ime.helpers.InputModeValidator;
import io.github.sspanak.tt9.ime.helpers.InputType; import io.github.sspanak.tt9.ime.helpers.InputType;
import io.github.sspanak.tt9.ime.helpers.TextField; import io.github.sspanak.tt9.ime.helpers.TextField;
@ -35,6 +36,7 @@ import io.github.sspanak.tt9.ui.tray.SuggestionsBar;
public class TraditionalT9 extends KeyPadHandler { public class TraditionalT9 extends KeyPadHandler {
// internal settings/data // internal settings/data
private boolean isActive = false; private boolean isActive = false;
@NonNull private AppHacks appHacks = new AppHacks(null, null);
@NonNull private TextField textField = new TextField(null, null); @NonNull private TextField textField = new TextField(null, null);
@NonNull private InputType inputType = new InputType(null, null); @NonNull private InputType inputType = new InputType(null, null);
@NonNull private final Handler autoAcceptHandler = new Handler(Looper.getMainLooper()); @NonNull private final Handler autoAcceptHandler = new Handler(Looper.getMainLooper());
@ -202,6 +204,7 @@ public class TraditionalT9 extends KeyPadHandler {
protected void onStart(EditorInfo input) { protected void onStart(EditorInfo input) {
inputType = new InputType(currentInputConnection, input); inputType = new InputType(currentInputConnection, input);
textField = new TextField(currentInputConnection, input); textField = new TextField(currentInputConnection, input);
appHacks = new AppHacks(input, textField);
if (!inputType.isValid() || inputType.isLimited()) { if (!inputType.isValid() || inputType.isLimited()) {
// When the input is invalid or simple, let Android handle it. // When the input is invalid or simple, let Android handle it.
@ -242,6 +245,10 @@ public class TraditionalT9 extends KeyPadHandler {
public boolean onBackspace() { public boolean onBackspace() {
if (appHacks.onBackspace(mInputMode)) {
return true;
}
// 1. Dialer fields seem to handle backspace on their own and we must ignore it, // 1. Dialer fields seem to handle backspace on their own and we must ignore it,
// otherwise, keyDown race condition occur for all keys. // otherwise, keyDown race condition occur for all keys.
// 2. Allow the assigned key to function normally, when there is no text (e.g. "Back" navigates back) // 2. Allow the assigned key to function normally, when there is no text (e.g. "Back" navigates back)
@ -296,7 +303,7 @@ public class TraditionalT9 extends KeyPadHandler {
} }
if (mInputMode.shouldSelectNextSuggestion() && !isSuggestionViewHidden()) { if (mInputMode.shouldSelectNextSuggestion() && !isSuggestionViewHidden()) {
nextSuggestion(); onKeyScrollSuggestion(false, false);
scheduleAutoAccept(mInputMode.getAutoAcceptTimeout()); scheduleAutoAccept(mInputMode.getAutoAcceptTimeout());
} else { } else {
getSuggestions(); getSuggestions();
@ -311,9 +318,9 @@ public class TraditionalT9 extends KeyPadHandler {
if (isSuggestionViewHidden()) { if (isSuggestionViewHidden()) {
return performOKAction(); return performOKAction();
} else {
acceptCurrentSuggestion(KeyEvent.KEYCODE_ENTER);
} }
acceptCurrentSuggestion(KeyEvent.KEYCODE_ENTER);
return true; return true;
} }
@ -425,10 +432,9 @@ public class TraditionalT9 extends KeyPadHandler {
} }
cancelAutoAccept(); cancelAutoAccept();
if (backward) previousSuggestion(); suggestionBar.scrollToSuggestion(backward ? -1 : 1);
else nextSuggestion();
mInputMode.setWordStem(suggestionBar.getCurrentSuggestion(), true); mInputMode.setWordStem(suggestionBar.getCurrentSuggestion(), true);
textField.setComposingTextWithHighlightedStem(suggestionBar.getCurrentSuggestion(), mInputMode); setComposingTextWithHighlightedStem(suggestionBar.getCurrentSuggestion());
return true; return true;
} }
@ -493,12 +499,18 @@ public class TraditionalT9 extends KeyPadHandler {
@Override @Override
public void onUpdateSelection(int oldSelStart, int oldSelEnd, int newSelStart, int newSelEnd, int candidatesStart, int candidatesEnd) { public void onUpdateSelection(int oldSelStart, int oldSelEnd, int newSelStart, int newSelEnd, int candidatesStart, int candidatesEnd) {
// Logger.d("onUpdateSelection", "oldSelStart: " + oldSelStart + " oldSelEnd: " + oldSelEnd + " newSelStart: " + newSelStart + " oldSelEnd: " + oldSelEnd + " candidatesStart: " + candidatesStart + " candidatesEnd: " + candidatesEnd);
super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart, candidatesEnd); super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart, candidatesEnd);
// If the cursor moves while composing a word (usually, because the user has touched the screen outside the word), we must // If the cursor moves while composing a word (usually, because the user has touched the screen outside the word), we must
// end typing end accept the word. Otherwise, the cursor would jump back at the end of the word, after the next key press. // end typing end accept the word. Otherwise, the cursor would jump back at the end of the word, after the next key press.
// This is confusing from user perspective, so we want to avoid it. // This is confusing from user perspective, so we want to avoid it.
if (!suggestionBar.isEmpty() && (newSelStart != candidatesEnd || newSelEnd != candidatesEnd)) { if (
candidatesStart != -1 && candidatesEnd != -1
&& (newSelStart != candidatesEnd || newSelEnd != candidatesEnd)
&& !suggestionBar.isEmpty()
) {
acceptIncompleteSuggestion(); acceptIncompleteSuggestion();
} }
} }
@ -509,18 +521,6 @@ public class TraditionalT9 extends KeyPadHandler {
} }
private void previousSuggestion() {
suggestionBar.scrollToSuggestion(-1);
textField.setComposingTextWithHighlightedStem(suggestionBar.getCurrentSuggestion(), mInputMode);
}
private void nextSuggestion() {
suggestionBar.scrollToSuggestion(1);
textField.setComposingTextWithHighlightedStem(suggestionBar.getCurrentSuggestion(), mInputMode);
}
private boolean scheduleAutoAccept(int delay) { private boolean scheduleAutoAccept(int delay) {
cancelAutoAccept(); cancelAutoAccept();
@ -624,7 +624,7 @@ public class TraditionalT9 extends KeyPadHandler {
// for a more intuitive experience. // for a more intuitive experience.
String word = suggestionBar.getCurrentSuggestion(); String word = suggestionBar.getCurrentSuggestion();
word = word.substring(0, Math.min(mInputMode.getSequenceLength(), word.length())); word = word.substring(0, Math.min(mInputMode.getSequenceLength(), word.length()));
textField.setComposingTextWithHighlightedStem(word, mInputMode); setComposingTextWithHighlightedStem(word);
} }
@ -665,6 +665,15 @@ public class TraditionalT9 extends KeyPadHandler {
} }
private void setComposingTextWithHighlightedStem(@NonNull String word) {
if (appHacks.setComposingTextWithHighlightedStem(word)) {
Logger.w("highlightComposingText", "Defective text field detected! Text highlighting disabled.");
} else {
textField.setComposingTextWithHighlightedStem(word, mInputMode);
}
}
private void nextInputMode() { private void nextInputMode() {
if (mInputMode.isPassthrough()) { if (mInputMode.isPassthrough()) {
return; return;

View file

@ -0,0 +1,42 @@
package io.github.sspanak.tt9.ime.helpers;
import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import io.github.sspanak.tt9.ime.modes.InputMode;
public class AppHacks {
private final EditorInfo editorInfo;
private final TextField textField;
public AppHacks(EditorInfo inputField, TextField textField) {
this.editorInfo = inputField;
this.textField = textField;
}
private boolean isKindleInvertedTextField() {
return editorInfo != null && editorInfo.inputType == 1 && editorInfo.packageName.contains("com.amazon.kindle");
}
public boolean setComposingTextWithHighlightedStem(@NonNull String word) {
if (isKindleInvertedTextField()) {
textField.setComposingText(word);
return true;
}
return false;
}
public boolean onBackspace(InputMode inputMode) {
if (isKindleInvertedTextField()) {
inputMode.clearWordStem();
}
return false;
}
}

View file

@ -274,13 +274,13 @@ public class TextField {
* the text will be in bold and italic. * the text will be in bold and italic.
*/ */
private CharSequence highlightText(CharSequence word, int start, int end, boolean highlightMore) { private CharSequence highlightText(CharSequence word, int start, int end, boolean highlightMore) {
if (end < start || start < 0) { if (end <= start || start < 0) {
Logger.w("tt9.util.highlightComposingText", "Cannot highlight invalid composing text range: [" + start + ", " + end + "]"); Logger.w("tt9.util.highlightComposingText", "Cannot highlight invalid composing text range: [" + start + ", " + end + "]");
return word; return word;
} }
// nothing to highlight in an empty word // nothing to highlight in an empty word or if the target is beyond the last letter
if (word == null || word.length() == 0) { if (word == null || word.length() == 0 || word.length() <= start) {
return word; return word;
} }

View file

@ -7,6 +7,7 @@ import android.graphics.drawable.Drawable;
import android.os.Handler; import android.os.Handler;
import android.view.View; import android.view.View;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
@ -106,6 +107,7 @@ public class SuggestionsBar {
} }
@NonNull
public String getSuggestion(int id) { public String getSuggestion(int id) {
if (id < 0 || id >= suggestions.size()) { if (id < 0 || id >= suggestions.size()) {
return ""; return "";