Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions java/res/values/strings-uix.xml
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,9 @@
<string name="swipe_settings_enable_swipe_typing">Enable swipe typing</string>
<string name="swipe_settings_enable_swipe_typing_subtitle">Allow swiping from key to key to write words.</string>

<string name="swipe_settings_delete_word_swipe">Swipe to delete word</string>
<string name="swipe_settings_delete_word_swipe_subtitle">Swipe left on the keyboard to delete the last word. Only works when swipe typing is off.</string>

<string name="swipe_settings_sensitive_swipe">Increase sensitivity</string>
<string name="swipe_settings_sensitive_swipe_subtitle">Make swipe trigger more often</string>

Expand Down
1 change: 1 addition & 0 deletions java/src/org/futo/inputmethod/engine/IMEInterface.kt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ interface IMEInterface {

fun onMovePointer(steps: Int, stepOverWords: Boolean, select: Boolean?)
fun onMoveDeletePointer(steps: Int)
fun onSelectWordLeft()
fun onUpWithDeletePointerActive()
fun onUpWithPointerActive()
fun onSwipeLanguage(direction: Int)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class ActionInputTransactionIME(val helper: IMEHelper) : IMEInterface, ActionInp
override fun onCustomRequest(requestCode: Int): Boolean = false
override fun onMovePointer(steps: Int, stepOverWords: Boolean, select: Boolean?) {}
override fun onMoveDeletePointer(steps: Int) {}
override fun onSelectWordLeft() {}
override fun onUpWithDeletePointerActive() {}
override fun onUpWithPointerActive() {}
override fun onSwipeLanguage(direction: Int) {}
Expand Down
1 change: 1 addition & 0 deletions java/src/org/futo/inputmethod/engine/general/ChineseIME.kt
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,7 @@ class ChineseIME(val helper: IMEHelper) : IMEInterface, SuggestionStripViewAcces
}
connect?.setSelection(lBound, currentMovingCursor)
}
override fun onSelectWordLeft() {}
override fun onUpWithDeletePointerActive() {
anchorOutOfDate = true
val selection: CharSequence? = connect?.getSelectedText(0)
Expand Down
9 changes: 9 additions & 0 deletions java/src/org/futo/inputmethod/engine/general/GeneralIME.kt
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,15 @@ class GeneralIME(val helper: IMEHelper) : IMEInterface, WordLearner, SuggestionS
}
}

override fun onSelectWordLeft() {
// Select exactly one word to the left, regardless of the backspace-mode setting.
// Used by the "left swipe anywhere to delete one word" gesture.
setNeutralSuggestionStrip()
if (inputLogic.mConnection.hasCursorPosition()) {
inputLogic.cursorLeft(-1, true, true)
}
}

override fun onUpWithDeletePointerActive() {
if (inputLogic.mConnection.hasSelection()) {
val selection: CharSequence? = inputLogic.mConnection.getSelectedText(0)
Expand Down
2 changes: 2 additions & 0 deletions java/src/org/futo/inputmethod/engine/general/JapaneseIME.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,8 @@ class JapaneseIME(val helper: IMEHelper) : IMEInterface {

}

override fun onSelectWordLeft() {}

override fun onUpWithDeletePointerActive() {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public interface KeyboardActionListener {

public void onMovePointer(int steps);
public void onMoveDeletePointer(int steps);
public void onSelectWordLeft();
public void onUpWithDeletePointerActive();
public void onUpWithPointerActive();
public void onSwipeLanguage(int direction);
Expand Down Expand Up @@ -138,6 +139,8 @@ public void onMovePointer(int steps) {}
@Override
public void onMoveDeletePointer(int steps) {}
@Override
public void onSelectWordLeft() {}
@Override
public void onUpWithDeletePointerActive() {}
@Override
public void onUpWithPointerActive() {}
Expand Down
40 changes: 39 additions & 1 deletion java/src/org/futo/inputmethod/keyboard/PointerTracker.java
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ public static void setStateHint(StateHint stateHint) {
private long mStartTime;
private boolean mStartedOnFastLongPress;
private boolean mCursorMoved = false;
private boolean mIsLeftSwipeDeleteWord = false;
private boolean mSpacebarLongPressed = false;

// true if keyboard layout has been changed.
Expand Down Expand Up @@ -761,6 +762,7 @@ private void onDownEventInternal(final int x, final int y, final long eventTime)
mStartedOnFastLongPress = key.isFastLongPress();
mSpacebarLongPressed = false;

mIsLeftSwipeDeleteWord = false;
mIsSlidingCursor = key.getCode() == Constants.CODE_DELETE || key.getCode() == Constants.CODE_SPACE;
mIsFlickingKey = !mIsSlidingCursor && key.getHasFlick();
mFlickDirection = key.flickDirection(0, 0);
Expand Down Expand Up @@ -1021,6 +1023,37 @@ private void onMoveEventInternal(final int x, final int y, final long eventTime)
return;
}

// Left swipe anywhere on the alphabet keyboard deletes exactly one word to the left.
// This only fires when glide/swipe typing is off, the stroke starts on a regular key
// (not Delete or Space), and the motion is predominantly horizontal and leftward.
// Mirror direction for RTL: in RTL, swiping right (toward line start) triggers the
// delete, so we negate dx before checking.
if (mIsLeftSwipeDeleteWord) {
// Already latched: consume remaining moves silently, no normal handling.
mLastX = x;
mLastY = y;
return;
}

if (!sInGesture && !settingsValues.mGestureInputEnabled
&& !mIsSlidingCursor
&& settingsValues.mDeleteWordSwipeEnabled
&& mKeyboard != null && mKeyboard.mId.isAlphabetKeyboard()) {
final int dx = x - mStartX;
final int dy = y - mStartY;
final int threshold = sPointerBigStep;
final int adjustedDx = settingsValues.mIsRTL ? -dx : dx;
if (adjustedDx <= -threshold && Math.abs(dx) > 2 * Math.abs(dy)) {
mIsLeftSwipeDeleteWord = true;
mCursorMoved = true;
sListener.onSelectWordLeft();
mLastX = x;
mLastY = y;
return;
}
// Non-qualifying move: fall through to normal drag/flick handling below.
}

if(mIsFlickingKey && oldKey != null) {
final Direction prevDirection = mFlickDirection;
mFlickDirection = oldKey.flickDirection(x - mStartX, y - mStartY);
Expand Down Expand Up @@ -1132,11 +1165,14 @@ private void onUpEventInternal(final int x, final int y, final long eventTime) {

if(mCursorMoved && currentKey != null && currentKey.getCode() == Constants.CODE_DELETE) {
sListener.onUpWithDeletePointerActive();
} else if(mIsLeftSwipeDeleteWord) {
sListener.onUpWithDeletePointerActive();
mIsLeftSwipeDeleteWord = false;
} else if(mCursorMoved) {
sListener.onUpWithPointerActive();
}

if(mIsFlickingKey && currentKey != null) {
if(mIsFlickingKey && currentKey != null && !mCursorMoved) {
final Key flickedKey = currentKey.flick(x - mStartX, y - mStartY);
detectAndSendKey(flickedKey, mKeyX, mKeyY, eventTime);

Expand Down Expand Up @@ -1192,6 +1228,7 @@ public void cancelTrackingForAction() {
return;
}
mIsTrackingForActionDisabled = true;
mIsLeftSwipeDeleteWord = false;
}

public boolean isInOperation() {
Expand Down Expand Up @@ -1284,6 +1321,7 @@ private void onCancelEventInternal() {
setReleasedKeyGraphics(mCurrentKey, true /* withAnimation */);
resetKeySelectionByDraggingFinger();
dismissMoreKeysPanel();
mIsLeftSwipeDeleteWord = false;
}

private boolean isMajorEnoughMoveToBeOnNewKey(final int x, final int y, final long eventTime,
Expand Down
7 changes: 7 additions & 0 deletions java/src/org/futo/inputmethod/latin/LatinIMELegacy.java
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,13 @@ public void onMoveDeletePointer(int steps) {
).onMoveDeletePointer(steps);
}

@Override
public void onSelectWordLeft() {
mImeManager.getActiveIME(
mSettings.getCurrent()
).onSelectWordLeft();
}

@Override
public void onUpWithDeletePointerActive() {
mImeManager.getActiveIME(
Expand Down
1 change: 1 addition & 0 deletions java/src/org/futo/inputmethod/latin/settings/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_BIGRAM_PREDICTIONS = "next_word_prediction";
public static final String PREF_GESTURE_INPUT = "gesture_input";
public static final String PREF_GESTURE_INPUT_SENSITIVITY = "gesture_input_sensitivity";
public static final String PREF_DELETE_WORD_SWIPE = "delete_word_swipe";
public static final String PREF_VIBRATION_DURATION_SETTINGS =
"pref_vibration_duration_settings";
public static final String PREF_KEYPRESS_SOUND_VOLUME = "pref_keypress_sound_volume";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ public class SettingsValues {
public final boolean mTransformerPredictionEnabled;
public final boolean mGestureInputEnabled;
public final boolean mGestureInputSensitive;
public final boolean mDeleteWordSwipeEnabled;
public final boolean mGestureTrailEnabled;
public final boolean mGestureFloatingPreviewTextEnabled;
public final boolean mSlidingKeyInputPreviewEnabled;
Expand Down Expand Up @@ -233,6 +234,7 @@ public SettingsValues(final Context context, final SharedPreferences prefs, fina
mPlausibilityThreshold = Settings.readPlausibilityThreshold(res);
mGestureInputEnabled = Settings.readGestureInputEnabled(prefs, res);
mGestureInputSensitive = prefs.getBoolean(Settings.PREF_GESTURE_INPUT_SENSITIVITY, false);
mDeleteWordSwipeEnabled = prefs.getBoolean(Settings.PREF_DELETE_WORD_SWIPE, true);
mGestureTrailEnabled = prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true);
mCloudSyncEnabled = prefs.getBoolean(LocalSettingsConstants.PREF_ENABLE_CLOUD_SYNC, false);
mAccount = prefs.getString(LocalSettingsConstants.PREF_ACCOUNT_NAME,
Expand Down Expand Up @@ -496,6 +498,8 @@ public String dump() {
sb.append("" + mTransformerPredictionEnabled);
sb.append("\n mGestureInputEnabled = ");
sb.append("" + mGestureInputEnabled);
sb.append("\n mDeleteWordSwipeEnabled = ");
sb.append("" + mDeleteWordSwipeEnabled);
sb.append("\n mGestureTrailEnabled = ");
sb.append("" + mGestureTrailEnabled);
sb.append("\n mGestureFloatingPreviewTextEnabled = ");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import org.futo.inputmethod.latin.uix.settings.UserSetting
import org.futo.inputmethod.latin.uix.settings.UserSettingsMenu
import org.futo.inputmethod.latin.uix.settings.useDataStore
import org.futo.inputmethod.latin.uix.settings.useDataStoreValue
import org.futo.inputmethod.latin.uix.settings.useSharedPrefsBool
import org.futo.inputmethod.latin.uix.settings.userSettingDecorationOnly
import org.futo.inputmethod.latin.uix.settings.userSettingNavigationItem
import org.futo.inputmethod.latin.uix.settings.userSettingToggleSharedPrefs
Expand Down Expand Up @@ -97,6 +98,14 @@ val SwipeMenu = UserSettingsMenu(
default = {true},
),

userSettingToggleSharedPrefs(
title = R.string.swipe_settings_delete_word_swipe,
subtitle = R.string.swipe_settings_delete_word_swipe_subtitle,
key = Settings.PREF_DELETE_WORD_SWIPE,
default = {true},
disabled = { useSharedPrefsBool(Settings.PREF_GESTURE_INPUT, true).value },
),

userSettingToggleSharedPrefs(
title = R.string.swipe_settings_sensitive_swipe,
subtitle = R.string.swipe_settings_sensitive_swipe_subtitle,
Expand Down