Skip to content

Commit

Permalink
1. simplified suggestion scrolling; 2. hopefully fixed the 'spans can…
Browse files Browse the repository at this point in the history
… 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)
  • Loading branch information
sspanak committed Aug 23, 2023
1 parent 6f0ee86 commit ca68d36
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/io/github/sspanak/tt9/ime/KeyPadHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ public View onCreateInputView() {
*/
@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);
}

Expand Down
45 changes: 27 additions & 18 deletions src/io/github/sspanak/tt9/ime/TraditionalT9.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
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;
Expand All @@ -35,6 +36,7 @@
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());
Expand Down Expand Up @@ -202,6 +204,7 @@ private void initUi() {
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.
Expand Down Expand Up @@ -242,6 +245,10 @@ public boolean onBack() {


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)
Expand Down Expand Up @@ -296,7 +303,7 @@ protected boolean onNumber(int key, boolean hold, int repeat) {
}

if (mInputMode.shouldSelectNextSuggestion() && !isSuggestionViewHidden()) {
nextSuggestion();
onKeyScrollSuggestion(false, false);
scheduleAutoAccept(mInputMode.getAutoAcceptTimeout());
} else {
getSuggestions();
Expand Down Expand Up @@ -430,10 +437,9 @@ public boolean onKeyScrollSuggestion(boolean validateOnly, boolean backward) {
}

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;
}

Expand Down Expand Up @@ -499,12 +505,18 @@ public boolean onKeyShowSettings(boolean validateOnly) {

@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();
}
}
Expand All @@ -515,18 +527,6 @@ private boolean isSuggestionViewHidden() {
}


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();

Expand Down Expand Up @@ -630,7 +630,7 @@ private void handleSuggestions() {
// 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);
}


Expand Down Expand Up @@ -671,6 +671,15 @@ private void refreshComposingText() {
}


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;
Expand Down
42 changes: 42 additions & 0 deletions src/io/github/sspanak/tt9/ime/helpers/AppHacks.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
17 changes: 14 additions & 3 deletions src/io/github/sspanak/tt9/ime/helpers/TextField.java
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,17 @@ public void deletePrecedingSpace(String word) {
}


/**
* deletePrecedingCharacters
* Deletes N characters before the cursor or does nothing on invalid input.
*/
public void deletePrecedingCharacters(int numberOfChars) {
if (numberOfChars > 0 && connection != null) {
connection.deleteSurroundingText(numberOfChars, 0);
}
}


/**
* setText
* A fail-safe setter that appends text to the field, ignoring NULL input.
Expand Down Expand Up @@ -274,13 +285,13 @@ public void finishComposingText() {
* 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;
}

Expand Down
2 changes: 2 additions & 0 deletions src/io/github/sspanak/tt9/ui/tray/SuggestionsBar.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
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;
Expand Down Expand Up @@ -106,6 +107,7 @@ public String getCurrentSuggestion() {
}


@NonNull
public String getSuggestion(int id) {
if (id < 0 || id >= suggestions.size()) {
return "";
Expand Down

0 comments on commit ca68d36

Please sign in to comment.