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
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();
// Logger.d("T9.onStartInput", "inputType: " + inputField.inputType + " fieldId: " + inputField.fieldId + " fieldName: " + inputField.fieldName + " packageName: " + inputField.packageName);
onStart(inputField);
}

View file

@ -18,6 +18,7 @@ import java.util.List;
import io.github.sspanak.tt9.Logger;
import io.github.sspanak.tt9.R;
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.InputType;
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 {
// internal settings/data
private boolean isActive = false;
@NonNull private AppHacks appHacks = new AppHacks(null, null);
@NonNull private TextField textField = new TextField(null, null);
@NonNull private InputType inputType = new InputType(null, null);
@NonNull private final Handler autoAcceptHandler = new Handler(Looper.getMainLooper());
@ -202,6 +204,7 @@ public class TraditionalT9 extends KeyPadHandler {
protected void onStart(EditorInfo input) {
inputType = new InputType(currentInputConnection, input);
textField = new TextField(currentInputConnection, input);
appHacks = new AppHacks(input, textField);
if (!inputType.isValid() || inputType.isLimited()) {
// When the input is invalid or simple, let Android handle it.
@ -242,6 +245,10 @@ public class TraditionalT9 extends KeyPadHandler {
public boolean onBackspace() {
if (appHacks.onBackspace(mInputMode)) {
return true;
}
// 1. Dialer fields seem to handle backspace on their own and we must ignore it,
// 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)
@ -296,7 +303,7 @@ public class TraditionalT9 extends KeyPadHandler {
}
if (mInputMode.shouldSelectNextSuggestion() && !isSuggestionViewHidden()) {
nextSuggestion();
onKeyScrollSuggestion(false, false);
scheduleAutoAccept(mInputMode.getAutoAcceptTimeout());
} else {
getSuggestions();
@ -311,9 +318,9 @@ public class TraditionalT9 extends KeyPadHandler {
if (isSuggestionViewHidden()) {
return performOKAction();
} else {
acceptCurrentSuggestion(KeyEvent.KEYCODE_ENTER);
}
acceptCurrentSuggestion(KeyEvent.KEYCODE_ENTER);
return true;
}
@ -425,10 +432,9 @@ public class TraditionalT9 extends KeyPadHandler {
}
cancelAutoAccept();
if (backward) previousSuggestion();
else nextSuggestion();
suggestionBar.scrollToSuggestion(backward ? -1 : 1);
mInputMode.setWordStem(suggestionBar.getCurrentSuggestion(), true);
textField.setComposingTextWithHighlightedStem(suggestionBar.getCurrentSuggestion(), mInputMode);
setComposingTextWithHighlightedStem(suggestionBar.getCurrentSuggestion());
return true;
}
@ -493,12 +499,18 @@ public class TraditionalT9 extends KeyPadHandler {
@Override
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);
// 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.
// 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();
}
}
@ -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) {
cancelAutoAccept();
@ -624,7 +624,7 @@ public class TraditionalT9 extends KeyPadHandler {
// for a more intuitive experience.
String word = suggestionBar.getCurrentSuggestion();
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() {
if (mInputMode.isPassthrough()) {
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.
*/
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 + "]");
return word;
}
// nothing to highlight in an empty word
if (word == null || word.length() == 0) {
// nothing to highlight in an empty word or if the target is beyond the last letter
if (word == null || word.length() == 0 || word.length() <= start) {
return word;
}

View file

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