diff --git a/app/src/main/java/helium314/keyboard/event/HardwareKeyboardEventDecoder.kt b/app/src/main/java/helium314/keyboard/event/HardwareKeyboardEventDecoder.kt index 0578a6ffb..a8d2d7f32 100644 --- a/app/src/main/java/helium314/keyboard/event/HardwareKeyboardEventDecoder.kt +++ b/app/src/main/java/helium314/keyboard/event/HardwareKeyboardEventDecoder.kt @@ -10,8 +10,6 @@ import android.view.KeyCharacterMap import android.view.KeyEvent import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode import helium314.keyboard.latin.common.Constants -import helium314.keyboard.latin.utils.Log -import helium314.keyboard.latin.utils.getCustomKeyCode /** * A hardware event decoder for a hardware qwerty-ish keyboard. diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt b/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt index a86eaeee6..f75e2825e 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt @@ -5,7 +5,7 @@ import android.util.SparseArray import android.view.KeyEvent import android.view.inputmethod.InputMethodSubtype import helium314.keyboard.event.Event -import helium314.keyboard.event.HangulEventDecoder.decodeHardwareKeyEvent +import helium314.keyboard.event.HangulEventDecoder import helium314.keyboard.event.HardwareEventDecoder import helium314.keyboard.event.HardwareKeyboardEventDecoder import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode @@ -88,7 +88,7 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp val event: Event if (settings.current.mLocale.language == "ko") { // todo: this does not appear to be the right place val subtype = keyboardSwitcher.keyboard?.mId?.mSubtype ?: RichInputMethodManager.getInstance().currentSubtype - event = decodeHardwareKeyEvent(subtype, keyEvent) { + event = HangulEventDecoder.decodeHardwareKeyEvent(subtype, keyEvent) { getHardwareKeyEventDecoder(keyEvent.deviceId).decodeHardwareKey(keyEvent) } } else { @@ -118,6 +118,12 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp val event = if (primaryCode in combiningRange) { // todo: should this be done later, maybe in inputLogic? Event.createSoftwareDeadEvent(primaryCode, 0, metaState, mkv.getKeyX(x), mkv.getKeyY(y), null) } else { + // todo: + // setting meta shift should only be done for arrow and similar cursor movement keys + // should only be enabled once it works more reliably (currently depends on app for some reason) +// if (mkv.keyboard?.mId?.isAlphabetShiftedManually == true) +// Event.createSoftwareKeypressEvent(primaryCode, metaState or KeyEvent.META_SHIFT_ON, mkv.getKeyX(x), mkv.getKeyY(y), isKeyRepeat) +// else Event.createSoftwareKeypressEvent(primaryCode, metaState, mkv.getKeyX(x), mkv.getKeyY(y), isKeyRepeat) Event.createSoftwareKeypressEvent(primaryCode, metaState, mkv.getKeyX(x), mkv.getKeyY(y), isKeyRepeat) } latinIME.onEvent(event) diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardId.java b/app/src/main/java/helium314/keyboard/keyboard/KeyboardId.java index ac39680a8..62523f488 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardId.java +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardId.java @@ -184,6 +184,11 @@ public final class KeyboardId { || mElementId == ELEMENT_ALPHABET_AUTOMATIC_SHIFTED || mElementId == ELEMENT_ALPHABET_MANUAL_SHIFTED; } + public boolean isAlphabetShiftedManually() { + return mElementId == ELEMENT_ALPHABET_SHIFT_LOCKED || mElementId == ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED + || mElementId == ELEMENT_ALPHABET_MANUAL_SHIFTED; + } + public boolean isNumberLayout() { return mElementId == ELEMENT_NUMBER || mElementId == ELEMENT_NUMPAD || mElementId == ELEMENT_PHONE || mElementId == ELEMENT_PHONE_SYMBOLS; diff --git a/app/src/main/java/helium314/keyboard/latin/LatinIME.java b/app/src/main/java/helium314/keyboard/latin/LatinIME.java index 1ebcba6b8..917aff58d 100644 --- a/app/src/main/java/helium314/keyboard/latin/LatinIME.java +++ b/app/src/main/java/helium314/keyboard/latin/LatinIME.java @@ -1164,8 +1164,12 @@ public class LatinIME extends InputMethodService implements if (isInputViewShown() && mInputLogic.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, composingSpanStart, composingSpanEnd, settingsValues)) { - mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(), - getCurrentRecapitalizeState()); + // we don't want to update a manually set shift state if selection changed towards one side + // because this may end the manual shift, which is unwanted in case of shift + arrow keys for changing selection + // todo: this is not fully implemented yet, and maybe should be behind a setting + if (mKeyboardSwitcher.getKeyboard() != null && mKeyboardSwitcher.getKeyboard().mId.isAlphabetShiftedManually() + && !((oldSelEnd == newSelEnd && oldSelStart != newSelStart) || (oldSelEnd != newSelEnd && oldSelStart == newSelStart))) + mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(), getCurrentRecapitalizeState()); } } diff --git a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java index 63004024a..6fcd24a68 100644 --- a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java +++ b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java @@ -89,6 +89,7 @@ public final class InputLogic { private int mDeleteCount; private long mLastKeyTime; + // todo: this is not used, so either remove it or do something with it public final TreeSet mCurrentlyPressedHardwareKeys = new TreeSet<>(); // Keeps track of most recently inserted text (multi-character key) for reverting @@ -399,7 +400,11 @@ public final class InputLogic { // Stop the last recapitalization, if started. mRecapitalizeStatus.stop(); mWordBeingCorrectedByCursor = null; - return true; + + // we do not return true if + final boolean oneSidedSelectionMove = hasOrHadSelection + && ((oldSelEnd == newSelEnd && oldSelStart != newSelStart) || (oldSelEnd != newSelEnd && oldSelStart == newSelStart)); + return !oneSidedSelectionMove; } public boolean moveCursorByAndReturnIfInsideComposingWord(int distance) { @@ -725,30 +730,36 @@ public final class InputLogic { } break; case KeyCode.WORD_LEFT: - sendDownUpKeyEventWithMetaState(ScriptUtils.isScriptRtl(currentKeyboardScript)? - KeyEvent.KEYCODE_DPAD_RIGHT : KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.META_CTRL_ON); + sendDownUpKeyEventWithMetaState( + ScriptUtils.isScriptRtl(currentKeyboardScript) ? KeyEvent.KEYCODE_DPAD_RIGHT : KeyEvent.KEYCODE_DPAD_LEFT, + KeyEvent.META_CTRL_ON | event.getMMetaState()); break; case KeyCode.WORD_RIGHT: - sendDownUpKeyEventWithMetaState(ScriptUtils.isScriptRtl(currentKeyboardScript)? - KeyEvent.KEYCODE_DPAD_LEFT : KeyEvent.KEYCODE_DPAD_RIGHT, KeyEvent.META_CTRL_ON); + sendDownUpKeyEventWithMetaState( + ScriptUtils.isScriptRtl(currentKeyboardScript) ? KeyEvent.KEYCODE_DPAD_LEFT : KeyEvent.KEYCODE_DPAD_RIGHT, + KeyEvent.META_CTRL_ON | event.getMMetaState()); break; case KeyCode.MOVE_START_OF_PAGE: - final int selectionEnd = mConnection.getExpectedSelectionEnd(); - sendDownUpKeyEventWithMetaState(KeyEvent.KEYCODE_MOVE_HOME, KeyEvent.META_CTRL_ON); - if (mConnection.getExpectedSelectionStart() > 0 && mConnection.getExpectedSelectionEnd() == selectionEnd) { - // unchanged, and we're not at the top -> try a different method (necessary for compose fields) - mConnection.setSelection(0, 0); + final int selectionEnd1 = mConnection.getExpectedSelectionEnd(); + final int selectionStart1 = mConnection.getExpectedSelectionStart(); + sendDownUpKeyEventWithMetaState(KeyEvent.KEYCODE_MOVE_HOME, KeyEvent.META_CTRL_ON | event.getMMetaState()); + if (mConnection.getExpectedSelectionStart() == selectionStart1 && mConnection.getExpectedSelectionEnd() == selectionEnd1) { + // unchanged -> try a different method (necessary for compose fields) + final int newEnd = (event.getMMetaState() & KeyEvent.META_SHIFT_MASK) != 0 ? selectionEnd1 : 0; + mConnection.setSelection(0, newEnd); } break; case KeyCode.MOVE_END_OF_PAGE: - final int selectionStart = mConnection.getExpectedSelectionEnd(); - sendDownUpKeyEventWithMetaState(KeyEvent.KEYCODE_MOVE_END, KeyEvent.META_CTRL_ON); - if (mConnection.getExpectedSelectionStart() == selectionStart) { + final int selectionStart2 = mConnection.getExpectedSelectionStart(); + final int selectionEnd2 = mConnection.getExpectedSelectionEnd(); + sendDownUpKeyEventWithMetaState(KeyEvent.KEYCODE_MOVE_END, KeyEvent.META_CTRL_ON | event.getMMetaState()); + if (mConnection.getExpectedSelectionStart() == selectionStart2 && mConnection.getExpectedSelectionEnd() == selectionEnd2) { // unchanged, try fallback e.g. for compose fields that don't care about ctrl + end // we just move to a very large index, and hope the field is prepared to deal with this // getting the actual length of the text for setting the correct position can be tricky for some apps... try { - mConnection.setSelection(Integer.MAX_VALUE, Integer.MAX_VALUE); + final int newStart = (event.getMMetaState() & KeyEvent.META_SHIFT_MASK) != 0 ? selectionStart2 : Integer.MAX_VALUE; + mConnection.setSelection(newStart, Integer.MAX_VALUE); } catch (Exception e) { // better catch potential errors and just do nothing in this case Log.i(TAG, "error when trying to move cursor to last position: " + e);