Skip to content

Commit

Permalink
Deletion cleanup (#397)
Browse files Browse the repository at this point in the history
* Translations

* Switch to Code event for deletion and ComposingText for recapitalization

* Remove text composition logic

* More cleanups
  • Loading branch information
rkkr authored May 1, 2023
1 parent 7e94eb3 commit addeabb
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 138 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ android {
applicationId "rkr.simplekeyboard.inputmethod"
minSdkVersion 19
targetSdkVersion 33
versionCode 98
versionName "5.13"
versionCode 99
versionName "5.14"
}
buildTypes {
release {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import rkr.simplekeyboard.inputmethod.latin.common.Constants;
import rkr.simplekeyboard.inputmethod.latin.common.StringUtils;

import static rkr.simplekeyboard.inputmethod.keyboard.internal.KeyboardIconsSet.ICON_UNDEFINED;
import static rkr.simplekeyboard.inputmethod.latin.common.Constants.CODE_OUTPUT_TEXT;
import static rkr.simplekeyboard.inputmethod.latin.common.Constants.CODE_SHIFT;
import static rkr.simplekeyboard.inputmethod.latin.common.Constants.CODE_SWITCH_ALPHA_SYMBOL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,6 @@ public final class RichInputConnection {
* text, if any. It is refreshed when the cursor moves by calling upon the TextView.
*/
private final StringBuilder mCommittedTextBeforeComposingText = new StringBuilder();
/**
* This contains the currently composing text, as LatinIME thinks the TextView is seeing it.
*/
private final StringBuilder mComposingText = new StringBuilder();

/**
* This variable is a temporary object used in {@link #commitText(CharSequence,int)}
Expand Down Expand Up @@ -120,8 +116,7 @@ private void checkConsistencyForDebug() {
final ExtractedText et = mIC.getExtractedText(r, 0);
final CharSequence beforeCursor = getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE,
0);
final StringBuilder internal = new StringBuilder(mCommittedTextBeforeComposingText)
.append(mComposingText);
final StringBuilder internal = new StringBuilder(mCommittedTextBeforeComposingText);
if (null == et || null == beforeCursor) return;
final int actualLength = Math.min(beforeCursor.length(), internal.length());
if (internal.length() > actualLength) {
Expand Down Expand Up @@ -186,7 +181,6 @@ public boolean resetCachesUponCursorMoveAndReturnSuccess(final int newSelStart,
final int newSelEnd) {
mExpectedSelStart = newSelStart;
mExpectedSelEnd = newSelEnd;
mComposingText.setLength(0);
final boolean didReloadTextSuccessfully = reloadTextCache();
if (!didReloadTextSuccessfully) {
Log.d(TAG, "Will try to retrieve text later.");
Expand Down Expand Up @@ -230,19 +224,6 @@ private void checkBatchEdit() {
}
}

public void finishComposingText() {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
// TODO: this is not correct! The cursor is not necessarily after the composing text.
// In the practice right now this is only called when input ends so it will be reset so
// it works, but it's wrong and should be fixed.
mCommittedTextBeforeComposingText.append(mComposingText);
mComposingText.setLength(0);
if (isConnected()) {
mIC.finishComposingText();
}
}

/**
* Calls {@link InputConnection#commitText(CharSequence, int)}.
*
Expand All @@ -258,10 +239,9 @@ public void commitText(final CharSequence text, final int newCursorPosition) {
// middle of the composing word mComposingText only holds the part of the composing text
// that is before the cursor, so this actually works, but it's terribly confusing. Fix this.
if (hasCursorPosition()) {
mExpectedSelStart += text.length() - mComposingText.length();
mExpectedSelStart += text.length();
mExpectedSelEnd = mExpectedSelStart;
}
mComposingText.setLength(0);
if (isConnected()) {
mTempObjectForCommitText.clear();
mTempObjectForCommitText.append(text);
Expand Down Expand Up @@ -315,10 +295,6 @@ public int getCursorCapsMode(final int inputType, final SpacingAndPunctuations s
if (!isConnected()) {
return Constants.TextUtils.CAP_MODE_OFF;
}
if (!TextUtils.isEmpty(mComposingText)) {
// We have some composing text - we should be in MODE_CHARACTERS only.
return TextUtils.CAP_MODE_CHARACTERS & inputType;
}
// TODO: this will generally work, but there may be cases where the buffer contains SOME
// information but not enough to determine the caps mode accurately. This may happen after
// heavy pressing of delete, for example DEFAULT_TEXT_CACHE_SIZE - 5 times or so.
Expand All @@ -345,8 +321,7 @@ public int getCodePointBeforeCursor() {
}

public CharSequence getTextBeforeCursor(final int n, final int flags) {
final int cachedLength =
mCommittedTextBeforeComposingText.length() + mComposingText.length();
final int cachedLength = mCommittedTextBeforeComposingText.length();
// If we have enough characters to satisfy the request, or if we have all characters in
// the text field, then we can return the cached version right away.
// However, if we don't have an expected cursor position, then we should always
Expand All @@ -362,7 +337,6 @@ public CharSequence getTextBeforeCursor(final int n, final int flags) {
// so we call #toString() on it. That will result in the return value being strictly
// speaking wrong, but since this is used for basing bigram probability off, and
// it's only going to matter for one getSuggestions call, it's fine in the practice.
s.append(mComposingText.toString());
if (s.length() > n) {
s.delete(0, s.length() - n);
}
Expand Down Expand Up @@ -413,34 +387,10 @@ private void detectLaggyConnection(final int operation, final long timeout, fina
}
}

public void deleteTextBeforeCursor(final int beforeLength) {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
// TODO: the following is incorrect if the cursor is not immediately after the composition.
// Right now we never come here in this case because we reset the composing state before we
// come here in this case, but we need to fix this.
final int remainingChars = mComposingText.length() - beforeLength;
if (remainingChars >= 0) {
mComposingText.setLength(remainingChars);
} else {
mComposingText.setLength(0);
// Never cut under 0
final int len = Math.max(mCommittedTextBeforeComposingText.length()
+ remainingChars, 0);
mCommittedTextBeforeComposingText.setLength(len);
}
if (mExpectedSelStart > beforeLength) {
mExpectedSelStart -= beforeLength;
mExpectedSelEnd -= beforeLength;
} else {
// There are fewer characters before the cursor in the buffer than we are being asked to
// delete. Only delete what is there, and update the end with the amount deleted.
mExpectedSelEnd -= mExpectedSelStart;
mExpectedSelStart = 0;
}
if (isConnected()) {
mIC.deleteSurroundingText(beforeLength, 0);
}
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
public void replaceText(final int startPosition, final int endPosition, CharSequence text) {
mIC.setComposingRegion(startPosition, endPosition);
mIC.setComposingText(text, startPosition);
mIC.finishComposingText();
}

public void performEditorAction(final int actionId) {
Expand Down Expand Up @@ -469,14 +419,10 @@ public void sendKeyEvent(final KeyEvent keyEvent) {
}
break;
case KeyEvent.KEYCODE_DEL:
if (0 == mComposingText.length()) {
if (mCommittedTextBeforeComposingText.length() > 0) {
mCommittedTextBeforeComposingText.delete(
mCommittedTextBeforeComposingText.length() - 1,
mCommittedTextBeforeComposingText.length());
}
} else {
mComposingText.delete(mComposingText.length() - 1, mComposingText.length());
if (mCommittedTextBeforeComposingText.length() > 0) {
mCommittedTextBeforeComposingText.delete(
mCommittedTextBeforeComposingText.length() - 1,
mCommittedTextBeforeComposingText.length());
}

if (mExpectedSelStart > 0 && mExpectedSelStart == mExpectedSelEnd) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ private TextUtils() {
}

public static final int NOT_A_CODE = -1;
public static final int NOT_A_CURSOR_POSITION = -1;
// TODO: replace the following constants with state in InputTransaction?
public static final int NOT_A_COORDINATE = -1;

// A hint on how many characters to cache from the TextView. A good value of this is given by
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,8 @@ public void onSubtypeChanged() {
public InputTransaction onTextInput(final SettingsValues settingsValues, final Event event) {
final String rawText = event.getTextToCommit().toString();
final InputTransaction inputTransaction = new InputTransaction(settingsValues);
mConnection.beginBatchEdit();
final String text = performSpecificTldProcessingOnTextInput(rawText);
mConnection.commitText(text, 1);
mConnection.endBatchEdit();
// Space state must be updated before calling updateShiftState
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
return inputTransaction;
Expand Down Expand Up @@ -128,7 +126,6 @@ public boolean onUpdateSelection(final int newSelStart, final int newSelEnd) {
*/
public InputTransaction onCodeInput(final SettingsValues settingsValues, final Event event) {
final InputTransaction inputTransaction = new InputTransaction(settingsValues);
mConnection.beginBatchEdit();

Event currentEvent = event;
while (null != currentEvent) {
Expand All @@ -141,7 +138,6 @@ public InputTransaction onCodeInput(final SettingsValues settingsValues, final E
}
currentEvent = currentEvent.mNextEvent;
}
mConnection.endBatchEdit();
return inputTransaction;
}

Expand Down Expand Up @@ -321,51 +317,7 @@ private void handleBackspaceEvent(final Event event, final InputTransaction inpu
? InputTransaction.SHIFT_UPDATE_LATER : InputTransaction.SHIFT_UPDATE_NOW;
inputTransaction.requireShiftUpdate(shiftUpdateKind);

// No cancelling of commit/double space/swap: we have a regular backspace.
// We should backspace one char and restart suggestion if at the end of a word.
if (mConnection.hasSelection()) {
// If there is a selection, remove it.
// We also need to unlearn the selected text.
final int numCharsDeleted = mConnection.getExpectedSelectionEnd()
- mConnection.getExpectedSelectionStart();
mConnection.setSelection(mConnection.getExpectedSelectionEnd(),
mConnection.getExpectedSelectionEnd());
mConnection.deleteTextBeforeCursor(numCharsDeleted);
} else {
// There is no selection, just delete one character.
if (inputTransaction.mSettingsValues.mInputAttributes.isTypeNull()
|| Constants.NOT_A_CURSOR_POSITION
== mConnection.getExpectedSelectionEnd()) {
// There are three possible reasons to send a key event: either the field has
// type TYPE_NULL, in which case the keyboard should send events, or we are
// running in backward compatibility mode, or we don't know the cursor position.
// Before Jelly bean, the keyboard would simulate a hardware keyboard event on
// pressing enter or delete. This is bad for many reasons (there are race
// conditions with commits) but some applications are relying on this behavior
// so we continue to support it for older apps, so we retain this behavior if
// the app has target SDK < JellyBean.
// As for the case where we don't know the cursor position, it can happen
// because of bugs in the framework. But the framework should know, so the next
// best thing is to leave it to whatever it thinks is best.
sendDownUpKeyEvent(KeyEvent.KEYCODE_DEL);
} else {
final int codePointBeforeCursor = mConnection.getCodePointBeforeCursor();
if (codePointBeforeCursor == Constants.NOT_A_CODE) {
// HACK for backward compatibility with broken apps that haven't realized
// yet that hardware keyboards are not the only way of inputting text.
// Nothing to delete before the cursor. We should not do anything, but many
// broken apps expect something to happen in this case so that they can
// catch it and have their broken interface react. If you need the keyboard
// to do this, you're doing it wrong -- please fix your app.
mConnection.deleteTextBeforeCursor(1);
// TODO: Add a new StatsUtils method onBackspaceWhenNoText()
return;
}
final int lengthToDelete =
Character.isSupplementaryCodePoint(codePointBeforeCursor) ? 2 : 1;
mConnection.deleteTextBeforeCursor(lengthToDelete);
}
}
sendDownUpKeyEvent(KeyEvent.KEYCODE_DEL);
}

/**
Expand Down Expand Up @@ -401,13 +353,12 @@ private void performRecapitalization(final SettingsValues settingsValues) {
// We trim leading and trailing whitespace.
mRecapitalizeStatus.trim();
}
mConnection.finishComposingText();
mConnection.beginBatchEdit();
mConnection.setSelection(selectionStart, selectionStart);
mRecapitalizeStatus.rotate();
mConnection.setSelection(selectionEnd, selectionEnd);
mConnection.deleteTextBeforeCursor(numCharsSelected);
mConnection.commitText(mRecapitalizeStatus.getRecapitalizedString(), 0);
mConnection.setSelection(mRecapitalizeStatus.getNewCursorStart(),
mRecapitalizeStatus.getNewCursorEnd());
mConnection.replaceText(selectionStart, selectionEnd, mRecapitalizeStatus.getRecapitalizedString());
mConnection.setSelection(mRecapitalizeStatus.getNewCursorStart(), mRecapitalizeStatus.getNewCursorEnd());
mConnection.endBatchEdit();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,8 @@
import android.content.res.Resources;
import android.view.inputmethod.EditorInfo;

import java.util.Locale;

import rkr.simplekeyboard.inputmethod.R;
import rkr.simplekeyboard.inputmethod.latin.InputAttributes;
import rkr.simplekeyboard.inputmethod.latin.RichInputMethodManager;

// Non-final for testing via mock library.
public class SettingsValues {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup;
import android.preference.SwitchPreference;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/res/values-ml-rIN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<string name="sound_on_keypress">"കീയമർത്തുമ്പോൾ ശബ്ദം"</string>
<string name="popup_on_keypress">"കീയമർത്തുമ്പോൾ പോപ്പപ്പ്"</string>
<string name="settings_screen_preferences">"മുൻഗണനകൾ"</string>
<string name="settings_screen_appearance">"രൂപം"</string>
<string name="settings_screen_theme">"തീം"</string>
<string name="abbreviation_unit_milliseconds">"<xliff:g id="MILLISECONDS">%s</xliff:g>മി.സെ"</string>
<string name="settings_system_default">"സ്ഥിരമായ സിസ്റ്റം"</string>
Expand All @@ -42,4 +43,16 @@
<string name="prefs_keypress_sound_volume_settings">"കീ അമർത്തുമ്പോഴുള്ള ശബ്‌ദ വോളിയം"</string>
<string name="prefs_key_longpress_timeout_settings">"കീ അമർത്തിപ്പിടിക്കുന്നതിലെ കാലതാമസം"</string>
<string name="button_default">"സ്ഥിരമായത്"</string>
<string name="prefs_keyboard_height_settings">"കീബോർഡ് ഉയരം"</string>
<string name="keyboard_color">"ഇഷ്ടാനുസൃത കീബോർഡ് നിറം സജ്ജമാക്കുക"</string>
<string name="hide_special_chars">"പ്രത്യേക പ്രതീകങ്ങൾ മറയ്ക്കുക"</string>
<string name="hide_language_switch_key">Hide language switch key</string>
<string name="pref_enable_ime_switch">"മറ്റ് കീബോർഡുകളിലേക്ക് മാറുക"</string>
<string name="show_number_row">"വേറിട്ട നമ്പർ വരി കാണിക്കുക"</string>
<string name="delete_swipe">"നീക്കി ഇല്ലാതാക്കുക"</string>
<string name="user_languages">"പ്രവർത്തനക്ഷമമാക്കിയ കീബോർഡ് ഭാഷകൾ"</string>
<string name="add_language">"ഭാഷ ചേർക്കുക"</string>
<string name="remove_language">"ഭാഷ നീക്കം ചെയ്യുക"</string>
<string name="generic_language_layouts"><xliff:g id="LANGUAGE_NAME" example="English (US)">%s</xliff:g> കീബോർഡ് രേഖാചിത്രങ്ങൾ</string>
<string name="change_keyboard">"കീബോർഡ് മാറ്റുക"</string>
</resources>
Loading

0 comments on commit addeabb

Please sign in to comment.