diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/common/Constants.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/common/Constants.java index 08a4f3f67..d39301956 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/common/Constants.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/common/Constants.java @@ -238,8 +238,10 @@ public final class Constants { public static final int CODE_RIGHT = -26; public static final int CODE_UP = -27; public static final int CODE_DOWN = -28; + public static final int CODE_UNDO = -29; + public static final int CODE_REDO = -30; // Code value representing the code is not specified. - public static final int CODE_UNSPECIFIED = -29; + public static final int CODE_UNSPECIFIED = -200; public static boolean isLetterCode(final int code) { return code >= CODE_SPACE; diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/inputlogic/InputLogic.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/inputlogic/InputLogic.java index e07e6cb3f..83bbe055c 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/inputlogic/InputLogic.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/inputlogic/InputLogic.java @@ -672,25 +672,9 @@ public final class InputLogic { && inputTransaction.getMSettingsValues().isUsuallyFollowedBySpace(mConnection.getCodePointBeforeCursor())) mSpaceState = SpaceState.NONE; break; - case Constants.CODE_CAPSLOCK: - // Note: Changing keyboard to shift lock state is handled in - // {@link KeyboardSwitcher#onEvent(Event)}. - break; - case Constants.CODE_SYMBOL_SHIFT: - // Note: Calling back to the keyboard on the symbol Shift key is handled in - // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. - break; - case Constants.CODE_SWITCH_ALPHA_SYMBOL: - // Note: Calling back to the keyboard on symbol key is handled in - // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. - break; case Constants.CODE_SETTINGS: onSettingsKeyPressed(); break; - case Constants.CODE_SHORTCUT: - // We need to switch to the shortcut IME. This is handled by LatinIME since the - // input logic has no business with IME switching. - break; case Constants.CODE_ACTION_NEXT: performEditorAction(EditorInfo.IME_ACTION_NEXT); break; @@ -700,14 +684,6 @@ public final class InputLogic { case Constants.CODE_LANGUAGE_SWITCH: handleLanguageSwitchKey(); break; - case Constants.CODE_EMOJI: - // Note: Switching emoji keyboard is being handled in - // {@link KeyboardState#onEvent(Event,int)}. - break; - case Constants.CODE_ALPHA_FROM_EMOJI: - // Note: Switching back from Emoji keyboard to the main keyboard is being - // handled in {@link KeyboardState#onEvent(Event,int)}. - break; case Constants.CODE_CLIPBOARD: // Note: If clipboard history is enabled, switching to clipboard keyboard // is being handled in {@link KeyboardState#onEvent(Event,int)}. @@ -721,22 +697,6 @@ public final class InputLogic { } } break; - case Constants.CODE_ALPHA_FROM_CLIPBOARD: - // Note: Switching back from clipboard keyboard to the main keyboard is being - // handled in {@link KeyboardState#onEvent(Event,int)}. - break; - case Constants.CODE_NUMPAD: - // Note: Switching Numpad keyboard is being handled in - // {@link KeyboardState#onEvent(Event,int)}. - break; - case Constants.CODE_ALPHA_FROM_NUMPAD: - // Note: Switching back from Numpad keyboard to the main keyboard is being - // handled in {@link KeyboardState#onEvent(Event,int)}. - break; - case Constants.CODE_SYMBOL_FROM_NUMPAD: - // Note: Switching back from Numpad keyboard to the symbol keyboard is being - // handled in {@link KeyboardState#onEvent(Event,int)}. - break; case Constants.CODE_SHIFT_ENTER: final Event tmpEvent = Event.createSoftwareKeypressEvent(Constants.CODE_ENTER, event.getMKeyCode(), event.getMX(), event.getMY(), event.isKeyRepeat()); @@ -751,15 +711,6 @@ public final class InputLogic { // a word, but the keepCursorPosition applyProcessedEvent seems to help here mWordComposer.applyProcessedEvent(event, true); break; - case Constants.CODE_START_ONE_HANDED_MODE: - case Constants.CODE_STOP_ONE_HANDED_MODE: - // Note: One-handed mode activation is being - // handled in {@link KeyboardState#onEvent(Event,int)}. - break; - case Constants.CODE_SWITCH_ONE_HANDED_MODE: - // Note: Switching one-handed side is being - // handled in {@link KeyboardState#onEvent(Event,int)}. - break; case Constants.CODE_SELECT_ALL: mConnection.selectAll(); break; @@ -778,6 +729,30 @@ public final class InputLogic { case Constants.CODE_DOWN: sendDownUpKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN); break; + case Constants.CODE_UNDO: + sendDownUpKeyEventWithMetaState(KeyEvent.KEYCODE_Z, KeyEvent.META_CTRL_ON); + break; + case Constants.CODE_REDO: + sendDownUpKeyEventWithMetaState(KeyEvent.KEYCODE_Z, KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON); + break; + case Constants.CODE_SHORTCUT: + // switching to shortcut IME, shift state, keyboard,... is handled by LatinIME, + // {@link KeyboardSwitcher#onEvent(Event)}, or {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. + // We need to switch to the shortcut IME. This is handled by LatinIME since the + // input logic has no business with IME switching. + case Constants.CODE_CAPSLOCK: + case Constants.CODE_SYMBOL_SHIFT: + case Constants.CODE_SWITCH_ALPHA_SYMBOL: + case Constants.CODE_EMOJI: + case Constants.CODE_ALPHA_FROM_EMOJI: + case Constants.CODE_ALPHA_FROM_CLIPBOARD: + case Constants.CODE_NUMPAD: + case Constants.CODE_ALPHA_FROM_NUMPAD: + case Constants.CODE_SYMBOL_FROM_NUMPAD: + case Constants.CODE_START_ONE_HANDED_MODE: + case Constants.CODE_STOP_ONE_HANDED_MODE: + case Constants.CODE_SWITCH_ONE_HANDED_MODE: + break; default: throw new RuntimeException("Unknown key code : " + event.getMKeyCode()); } @@ -2099,12 +2074,26 @@ public final class InputLogic { * @param keyCode the key code to send inside the key event. */ public void sendDownUpKeyEvent(final int keyCode) { + sendDownUpKeyEventWithMetaState(keyCode, 0); + } + + /** + * Sends a DOWN key event followed by an UP key event to the editor. + * + * If possible at all, avoid using this method. It causes all sorts of race conditions with + * the text view because it goes through a different, asynchronous binder. Also, batch edits + * are ignored for key events. Use the normal software input methods instead. + * + * @param keyCode the key code to send inside the key event. + * @param metaState the meta state to send inside the key event, e.g. KeyEvent.META_CTRL_ON + */ + public void sendDownUpKeyEventWithMetaState(final int keyCode, final int metaState) { final long eventTime = SystemClock.uptimeMillis(); mConnection.sendKeyEvent(new KeyEvent(eventTime, eventTime, - KeyEvent.ACTION_DOWN, keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, + KeyEvent.ACTION_DOWN, keyCode, 0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE)); mConnection.sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime, - KeyEvent.ACTION_UP, keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, + KeyEvent.ACTION_UP, keyCode, 0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE)); } diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/suggestions/SuggestionStripView.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/suggestions/SuggestionStripView.java index 1f8c16619..ce5a8236a 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/suggestions/SuggestionStripView.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/suggestions/SuggestionStripView.java @@ -84,6 +84,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick private static final String RIGHT_KEY_TAG = "right_key"; private static final String UP_KEY_TAG = "up_key"; private static final String DOWN_KEY_TAG = "down_key"; + private static final String UNDO_TAG = "undo"; + private static final String REDO_TAG = "redo"; private final ViewGroup mSuggestionsStrip; private final ImageButton mToolbarKey; @@ -653,6 +655,12 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick case DOWN_KEY_TAG: mListener.onCodeInput(Constants.CODE_DOWN, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false); return; + case UNDO_TAG: + mListener.onCodeInput(Constants.CODE_UNDO, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false); + return; + case REDO_TAG: + mListener.onCodeInput(Constants.CODE_REDO, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false); + return; } } if (view == mToolbarKey) {