mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-06-18 15:15:21 +00:00
move some key press logic from LatinIme into KeyboardActionListener
This commit is contained in:
parent
a37de668c0
commit
9c97a6b9bf
7 changed files with 98 additions and 96 deletions
|
@ -139,6 +139,16 @@ class Event private constructor(
|
|||
null, if (isKeyRepeat) FLAG_REPEAT else FLAG_NONE, null)
|
||||
}
|
||||
|
||||
// A helper method to split the code point and the key code.
|
||||
// todo: Ultimately, they should not be squashed into the same variable, and this method should be removed.
|
||||
@JvmStatic
|
||||
fun createSoftwareKeypressEvent(keyCodeOrCodePoint: Int, metaState: Int, keyX: Int, keyY: Int, isKeyRepeat: Boolean) =
|
||||
if (keyCodeOrCodePoint <= 0) {
|
||||
createSoftwareKeypressEvent(NOT_A_CODE_POINT, keyCodeOrCodePoint, metaState, keyX, keyY, isKeyRepeat)
|
||||
} else {
|
||||
createSoftwareKeypressEvent(keyCodeOrCodePoint, NOT_A_KEY_CODE, metaState, keyX, keyY, isKeyRepeat)
|
||||
}
|
||||
|
||||
fun createHardwareKeypressEvent(codePoint: Int, keyCode: Int, metaState: Int, next: Event?, isKeyRepeat: Boolean): Event {
|
||||
return Event(EVENT_TYPE_INPUT_KEYPRESS, null, codePoint, keyCode, metaState,
|
||||
Constants.EXTERNAL_KEYBOARD_COORDINATE, Constants.EXTERNAL_KEYBOARD_COORDINATE,
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
package helium314.keyboard.keyboard;
|
||||
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import helium314.keyboard.latin.common.Constants;
|
||||
import helium314.keyboard.latin.common.InputPointers;
|
||||
|
||||
|
@ -31,6 +33,12 @@ public interface KeyboardActionListener {
|
|||
*/
|
||||
void onReleaseKey(int primaryCode, boolean withSliding);
|
||||
|
||||
/** For handling hardware key presses. Returns whether the event was handled. */
|
||||
boolean onKeyDown(int keyCode, KeyEvent keyEvent);
|
||||
|
||||
/** For handling hardware key presses. Returns whether the event was handled. */
|
||||
boolean onKeyUp(int keyCode, KeyEvent keyEvent);
|
||||
|
||||
/**
|
||||
* Send a key code to the listener.
|
||||
*
|
||||
|
@ -117,6 +125,10 @@ public interface KeyboardActionListener {
|
|||
@Override
|
||||
public void onReleaseKey(int primaryCode, boolean withSliding) {}
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent keyEvent) { return false; }
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent keyEvent) { return false; }
|
||||
@Override
|
||||
public void onCodeInput(int primaryCode, int x, int y, boolean isKeyRepeat) {}
|
||||
@Override
|
||||
public void onTextInput(String text) {}
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
package helium314.keyboard.keyboard
|
||||
|
||||
import android.text.InputType
|
||||
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.HardwareEventDecoder
|
||||
import helium314.keyboard.event.HardwareKeyboardEventDecoder
|
||||
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
|
||||
import helium314.keyboard.latin.EmojiAltPhysicalKeyDetector
|
||||
import helium314.keyboard.latin.LatinIME
|
||||
import helium314.keyboard.latin.RichInputMethodManager
|
||||
import helium314.keyboard.latin.common.Constants
|
||||
import helium314.keyboard.latin.common.InputPointers
|
||||
import helium314.keyboard.latin.common.StringUtils
|
||||
import helium314.keyboard.latin.common.combiningRange
|
||||
import helium314.keyboard.latin.common.loopOverCodePoints
|
||||
import helium314.keyboard.latin.common.loopOverCodePointsBackwards
|
||||
import helium314.keyboard.latin.define.ProductionFlags
|
||||
import helium314.keyboard.latin.inputlogic.InputLogic
|
||||
import helium314.keyboard.latin.settings.Settings
|
||||
import kotlin.math.abs
|
||||
|
@ -19,6 +27,11 @@ import kotlin.math.min
|
|||
class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inputLogic: InputLogic) : KeyboardActionListener {
|
||||
|
||||
private val connection = inputLogic.mConnection
|
||||
private val emojiAltPhysicalKeyDetector by lazy { EmojiAltPhysicalKeyDetector(latinIME.resources) }
|
||||
|
||||
// We expect to have only one decoder in almost all cases, hence the default capacity of 1.
|
||||
// If it turns out we need several, it will get grown seamlessly.
|
||||
private val hardwareEventDecoders: SparseArray<HardwareEventDecoder> = SparseArray(1)
|
||||
|
||||
private val keyboardSwitcher = KeyboardSwitcher.getInstance()
|
||||
private val settings = Settings.getInstance()
|
||||
|
@ -58,9 +71,56 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp
|
|||
keyboardSwitcher.onReleaseKey(primaryCode, withSliding, latinIME.currentAutoCapsState, latinIME.currentRecapitalizeState)
|
||||
}
|
||||
|
||||
override fun onKeyUp(keyCode: Int, keyEvent: KeyEvent): Boolean {
|
||||
emojiAltPhysicalKeyDetector.onKeyUp(keyEvent)
|
||||
if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED)
|
||||
return false
|
||||
|
||||
val keyIdentifier = keyEvent.deviceId.toLong() shl 32 + keyEvent.keyCode
|
||||
return inputLogic.mCurrentlyPressedHardwareKeys.remove(keyIdentifier)
|
||||
}
|
||||
|
||||
override fun onKeyDown(keyCode: Int, keyEvent: KeyEvent): Boolean {
|
||||
emojiAltPhysicalKeyDetector.onKeyDown(keyEvent)
|
||||
if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED)
|
||||
return false
|
||||
|
||||
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) {
|
||||
getHardwareKeyEventDecoder(keyEvent.deviceId).decodeHardwareKey(keyEvent)
|
||||
}
|
||||
} else {
|
||||
event = getHardwareKeyEventDecoder(keyEvent.deviceId).decodeHardwareKey(keyEvent)
|
||||
}
|
||||
|
||||
if (event.isHandled) {
|
||||
inputLogic.onCodeInput(
|
||||
settings.current, event,
|
||||
keyboardSwitcher.getKeyboardShiftMode(), // TODO: this is not necessarily correct for a hardware keyboard right now
|
||||
keyboardSwitcher.getCurrentKeyboardScript(),
|
||||
latinIME.mHandler
|
||||
)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onCodeInput(primaryCode: Int, x: Int, y: Int, isKeyRepeat: Boolean) {
|
||||
when (primaryCode) {
|
||||
KeyCode.TOGGLE_AUTOCORRECT -> return Settings.getInstance().toggleAutoCorrect()
|
||||
KeyCode.TOGGLE_INCOGNITO_MODE -> return Settings.getInstance().toggleAlwaysIncognitoMode()
|
||||
}
|
||||
val mkv = keyboardSwitcher.mainKeyboardView
|
||||
latinIME.onCodeInput(primaryCode, metaState, mkv.getKeyX(x), mkv.getKeyY(y), isKeyRepeat)
|
||||
|
||||
// checking if the character is a combining accent
|
||||
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 {
|
||||
Event.createSoftwareKeypressEvent(primaryCode, metaState, mkv.getKeyX(x), mkv.getKeyY(y), isKeyRepeat)
|
||||
}
|
||||
latinIME.onEvent(event)
|
||||
}
|
||||
|
||||
override fun onTextInput(text: String?) = latinIME.onTextInput(text)
|
||||
|
@ -257,4 +317,13 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp
|
|||
}
|
||||
return -min(-actualSteps, text.length)
|
||||
}
|
||||
|
||||
private fun getHardwareKeyEventDecoder(deviceId: Int): HardwareEventDecoder {
|
||||
hardwareEventDecoders.get(deviceId)?.let { return it }
|
||||
|
||||
// TODO: create the decoder according to the specification
|
||||
val newDecoder = HardwareKeyboardEventDecoder(deviceId)
|
||||
hardwareEventDecoders.put(deviceId, newDecoder)
|
||||
return newDecoder
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.util.List;
|
|||
/**
|
||||
* A class for detecting Emoji-Alt physical key.
|
||||
*/
|
||||
final class EmojiAltPhysicalKeyDetector {
|
||||
public final class EmojiAltPhysicalKeyDetector {
|
||||
private static final String TAG = "EmojiAltPhysKeyDetector";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ import android.os.Process;
|
|||
import android.text.InputType;
|
||||
import android.util.PrintWriterPrinter;
|
||||
import android.util.Printer;
|
||||
import android.util.SparseArray;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
@ -51,9 +50,6 @@ import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
|
|||
import helium314.keyboard.latin.common.InsetsOutlineProvider;
|
||||
import helium314.keyboard.dictionarypack.DictionaryPackConstants;
|
||||
import helium314.keyboard.event.Event;
|
||||
import helium314.keyboard.event.HangulEventDecoder;
|
||||
import helium314.keyboard.event.HardwareEventDecoder;
|
||||
import helium314.keyboard.event.HardwareKeyboardEventDecoder;
|
||||
import helium314.keyboard.event.InputTransaction;
|
||||
import helium314.keyboard.keyboard.Keyboard;
|
||||
import helium314.keyboard.keyboard.KeyboardId;
|
||||
|
@ -68,7 +64,6 @@ import helium314.keyboard.latin.common.InputPointers;
|
|||
import helium314.keyboard.latin.common.LocaleUtils;
|
||||
import helium314.keyboard.latin.common.ViewOutlineProviderUtilsKt;
|
||||
import helium314.keyboard.latin.define.DebugFlags;
|
||||
import helium314.keyboard.latin.define.ProductionFlags;
|
||||
import helium314.keyboard.latin.inputlogic.InputLogic;
|
||||
import helium314.keyboard.latin.personalization.PersonalizationHelper;
|
||||
import helium314.keyboard.latin.settings.Settings;
|
||||
|
@ -134,9 +129,6 @@ public class LatinIME extends InputMethodService implements
|
|||
private final DictionaryFacilitator mDictionaryFacilitator =
|
||||
DictionaryFacilitatorProvider.getDictionaryFacilitator(false);
|
||||
final InputLogic mInputLogic = new InputLogic(this, this, mDictionaryFacilitator);
|
||||
// We expect to have only one decoder in almost all cases, hence the default capacity of 1.
|
||||
// If it turns out we need several, it will get grown seamlessly.
|
||||
final SparseArray<HardwareEventDecoder> mHardwareEventDecoders = new SparseArray<>(1);
|
||||
|
||||
// TODO: Move these {@link View}s to {@link KeyboardSwitcher}.
|
||||
private View mInputView;
|
||||
|
@ -146,7 +138,6 @@ public class LatinIME extends InputMethodService implements
|
|||
private RichInputMethodManager mRichImm;
|
||||
final KeyboardSwitcher mKeyboardSwitcher;
|
||||
private final SubtypeState mSubtypeState = new SubtypeState();
|
||||
private EmojiAltPhysicalKeyDetector mEmojiAltPhysicalKeyDetector;
|
||||
private final StatsUtilsManager mStatsUtilsManager;
|
||||
// Working variable for {@link #startShowingInputView()} and
|
||||
// {@link #onEvaluateInputViewShown()}.
|
||||
|
@ -1540,25 +1531,6 @@ public class LatinIME extends InputMethodService implements
|
|||
mKeyboardActionListener.onCodeInput(codePoint, x, y, isKeyRepeat);
|
||||
}
|
||||
|
||||
// called by KeyboardActionListener
|
||||
public void onCodeInput(final int codePoint, final int metaState, final int x, final int y, final boolean isKeyRepeat) {
|
||||
if (codePoint < 0) {
|
||||
switch (codePoint) {
|
||||
case KeyCode.TOGGLE_AUTOCORRECT -> {mSettings.toggleAutoCorrect(); return; }
|
||||
case KeyCode.TOGGLE_INCOGNITO_MODE -> {mSettings.toggleAlwaysIncognitoMode(); return; }
|
||||
}
|
||||
}
|
||||
final Event event;
|
||||
// checking if the character is a combining accent
|
||||
if (0x300 <= codePoint && codePoint <= 0x35b) {
|
||||
event = Event.createSoftwareDeadEvent(codePoint, 0, metaState, x, y, null);
|
||||
} else {
|
||||
event = createSoftwareKeypressEvent(codePoint, metaState, x, y, isKeyRepeat);
|
||||
}
|
||||
|
||||
onEvent(event);
|
||||
}
|
||||
|
||||
// This method is public for testability of LatinIME, but also in the future it should
|
||||
// completely replace #onCodeInput.
|
||||
public void onEvent(@NonNull final Event event) {
|
||||
|
@ -1573,24 +1545,6 @@ public class LatinIME extends InputMethodService implements
|
|||
mKeyboardSwitcher.onEvent(event, getCurrentAutoCapsState(), getCurrentRecapitalizeState());
|
||||
}
|
||||
|
||||
// A helper method to split the code point and the key code. Ultimately, they should not be
|
||||
// squashed into the same variable, and this method should be removed.
|
||||
// public for testing, as we don't want to copy the same logic into test code
|
||||
@NonNull
|
||||
public static Event createSoftwareKeypressEvent(final int keyCodeOrCodePoint, final int metaState,
|
||||
final int keyX, final int keyY, final boolean isKeyRepeat) {
|
||||
final int keyCode;
|
||||
final int codePoint;
|
||||
if (keyCodeOrCodePoint <= 0) {
|
||||
keyCode = keyCodeOrCodePoint;
|
||||
codePoint = Event.NOT_A_CODE_POINT;
|
||||
} else {
|
||||
keyCode = Event.NOT_A_KEY_CODE;
|
||||
codePoint = keyCodeOrCodePoint;
|
||||
}
|
||||
return Event.createSoftwareKeypressEvent(codePoint, keyCode, metaState, keyX, keyY, isKeyRepeat);
|
||||
}
|
||||
|
||||
public void onTextInput(final String rawText) {
|
||||
// TODO: have the keyboard pass the correct key code when we need it.
|
||||
final Event event = Event.createSoftwareTextEvent(rawText, KeyCode.MULTIPLE_CODE_POINTS);
|
||||
|
@ -1830,63 +1784,18 @@ public class LatinIME extends InputMethodService implements
|
|||
feedbackManager.performAudioFeedback(code);
|
||||
}
|
||||
|
||||
private HardwareEventDecoder getHardwareKeyEventDecoder(final int deviceId) {
|
||||
final HardwareEventDecoder decoder = mHardwareEventDecoders.get(deviceId);
|
||||
if (null != decoder) return decoder;
|
||||
// TODO: create the decoder according to the specification
|
||||
final HardwareEventDecoder newDecoder = new HardwareKeyboardEventDecoder(deviceId);
|
||||
mHardwareEventDecoders.put(deviceId, newDecoder);
|
||||
return newDecoder;
|
||||
}
|
||||
|
||||
// Hooks for hardware keyboard
|
||||
@Override
|
||||
public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) {
|
||||
if (mEmojiAltPhysicalKeyDetector == null) {
|
||||
mEmojiAltPhysicalKeyDetector = new EmojiAltPhysicalKeyDetector(
|
||||
getApplicationContext().getResources());
|
||||
}
|
||||
mEmojiAltPhysicalKeyDetector.onKeyDown(keyEvent);
|
||||
if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) {
|
||||
return super.onKeyDown(keyCode, keyEvent);
|
||||
}
|
||||
final Event event;
|
||||
if (mRichImm.getCurrentSubtypeLocale().getLanguage().equals("ko")) {
|
||||
final RichInputMethodSubtype subtype = mKeyboardSwitcher.getKeyboard() == null
|
||||
? mRichImm.getCurrentSubtype()
|
||||
: mKeyboardSwitcher.getKeyboard().mId.mSubtype;
|
||||
event = HangulEventDecoder.decodeHardwareKeyEvent(subtype, keyEvent,
|
||||
() -> getHardwareKeyEventDecoder(keyEvent.getDeviceId()).decodeHardwareKey(keyEvent));
|
||||
} else {
|
||||
event = getHardwareKeyEventDecoder(keyEvent.getDeviceId()).decodeHardwareKey(keyEvent);
|
||||
}
|
||||
// If the event is not handled by LatinIME, we just pass it to the parent implementation.
|
||||
// If it's handled, we return true because we did handle it.
|
||||
if (event.isHandled()) {
|
||||
mInputLogic.onCodeInput(mSettings.getCurrent(), event,
|
||||
mKeyboardSwitcher.getKeyboardShiftMode(),
|
||||
// TODO: this is not necessarily correct for a hardware keyboard right now
|
||||
mKeyboardSwitcher.getCurrentKeyboardScript(),
|
||||
mHandler);
|
||||
if (mKeyboardActionListener.onKeyDown(keyCode, keyEvent))
|
||||
return true;
|
||||
}
|
||||
return super.onKeyDown(keyCode, keyEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(final int keyCode, final KeyEvent keyEvent) {
|
||||
if (mEmojiAltPhysicalKeyDetector == null) {
|
||||
mEmojiAltPhysicalKeyDetector = new EmojiAltPhysicalKeyDetector(
|
||||
getApplicationContext().getResources());
|
||||
}
|
||||
mEmojiAltPhysicalKeyDetector.onKeyUp(keyEvent);
|
||||
if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) {
|
||||
return super.onKeyUp(keyCode, keyEvent);
|
||||
}
|
||||
final long keyIdentifier = (long) keyEvent.getDeviceId() << 32 + keyEvent.getKeyCode();
|
||||
if (mInputLogic.mCurrentlyPressedHardwareKeys.remove(keyIdentifier)) {
|
||||
if (mKeyboardActionListener.onKeyUp(keyCode, keyEvent))
|
||||
return true;
|
||||
}
|
||||
return super.onKeyUp(keyCode, keyEvent);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,3 +12,5 @@ object Links {
|
|||
const val CUSTOM_LAYOUTS = "$GITHUB/discussions/categories/custom-layout"
|
||||
const val CUSTOM_COLORS = "$GITHUB/discussions/categories/custom-colors"
|
||||
}
|
||||
|
||||
val combiningRange = 0x300..0x35b
|
||||
|
|
|
@ -718,7 +718,7 @@ public final class InputLogic {
|
|||
if (mConnection.hasSelection()) {
|
||||
mConnection.copyText(true);
|
||||
// fake delete keypress to remove the text
|
||||
final Event backspaceEvent = LatinIME.createSoftwareKeypressEvent(KeyCode.DELETE, 0,
|
||||
final Event backspaceEvent = Event.createSoftwareKeypressEvent(KeyCode.DELETE, 0,
|
||||
event.getMX(), event.getMY(), event.isKeyRepeat());
|
||||
handleBackspaceEvent(backspaceEvent, inputTransaction, currentKeyboardScript);
|
||||
inputTransaction.setDidAffectContents();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue