enable hardware keyboard handling again, with improved handling

This commit is contained in:
Helium314 2025-06-14 11:29:26 +02:00
parent 63dad1549e
commit a37de668c0
5 changed files with 86 additions and 87 deletions

View file

@ -256,10 +256,8 @@ class Event private constructor(
source.mX, source.mY, source.mSuggestedWordInfo, source.mFlags or FLAG_COMBINING, source.mNextEvent)
}
fun createNotHandledEvent(): Event {
return Event(EVENT_TYPE_NOT_HANDLED, null, NOT_A_CODE_POINT, NOT_A_KEY_CODE, 0,
val notHandledEvent = Event(EVENT_TYPE_NOT_HANDLED, null, NOT_A_CODE_POINT, NOT_A_KEY_CODE, 0,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, null, FLAG_NONE, null)
}
}
// This method is private - to create a new event, use one of the create* utility methods.

View file

@ -48,6 +48,8 @@ class HardwareKeyboardEventDecoder(val mDeviceId: Int) : HardwareEventDecoder {
} else Event.createHardwareKeypressEvent(codePointAndFlags, keyCode, metaState, null, isKeyRepeat)
// If not Enter, then this is just a regular keypress event for a normal character
// that can be committed right away, taking into account the current state.
} else Event.createNotHandledEvent()
} else {
Event.notHandledEvent
}
}
}

View file

@ -210,66 +210,11 @@ object KeyCode {
// todo: there are many more keys, see near https://developer.android.com/reference/android/view/KeyEvent#KEYCODE_0
/**
* Convert a keyCode / codePoint to a KeyEvent.KEYCODE_<xxx>.
* Fallback to KeyEvent.KEYCODE_UNKNOWN.
* Convert an internal keyCode to a KeyEvent.KEYCODE_<xxx>.
* Positive codes are passed through, unknown negative codes result in KeyEvent.KEYCODE_UNKNOWN.
* To be uses for fake hardware key press.
* */
fun Int.toKeyEventCode(): Int = if (this > 0)
when (this.toChar().uppercaseChar()) {
'/' -> KeyEvent.KEYCODE_SLASH
'\\' -> KeyEvent.KEYCODE_BACKSLASH
';' -> KeyEvent.KEYCODE_SEMICOLON
',' -> KeyEvent.KEYCODE_COMMA
'.' -> KeyEvent.KEYCODE_PERIOD
'\'' -> KeyEvent.KEYCODE_APOSTROPHE
'`' -> KeyEvent.KEYCODE_GRAVE
'*' -> KeyEvent.KEYCODE_STAR
']' -> KeyEvent.KEYCODE_RIGHT_BRACKET
'[' -> KeyEvent.KEYCODE_LEFT_BRACKET
'+' -> KeyEvent.KEYCODE_PLUS
'-' -> KeyEvent.KEYCODE_MINUS
'=' -> KeyEvent.KEYCODE_EQUALS
'\n' -> KeyEvent.KEYCODE_ENTER
'\t' -> KeyEvent.KEYCODE_TAB
'0' -> KeyEvent.KEYCODE_0
'1' -> KeyEvent.KEYCODE_1
'2' -> KeyEvent.KEYCODE_2
'3' -> KeyEvent.KEYCODE_3
'4' -> KeyEvent.KEYCODE_4
'5' -> KeyEvent.KEYCODE_5
'6' -> KeyEvent.KEYCODE_6
'7' -> KeyEvent.KEYCODE_7
'8' -> KeyEvent.KEYCODE_8
'9' -> KeyEvent.KEYCODE_9
'A' -> KeyEvent.KEYCODE_A
'B' -> KeyEvent.KEYCODE_B
'C' -> KeyEvent.KEYCODE_C
'D' -> KeyEvent.KEYCODE_D
'E' -> KeyEvent.KEYCODE_E
'F' -> KeyEvent.KEYCODE_F
'G' -> KeyEvent.KEYCODE_G
'H' -> KeyEvent.KEYCODE_H
'I' -> KeyEvent.KEYCODE_I
'J' -> KeyEvent.KEYCODE_J
'K' -> KeyEvent.KEYCODE_K
'L' -> KeyEvent.KEYCODE_L
'M' -> KeyEvent.KEYCODE_M
'N' -> KeyEvent.KEYCODE_N
'O' -> KeyEvent.KEYCODE_O
'P' -> KeyEvent.KEYCODE_P
'Q' -> KeyEvent.KEYCODE_Q
'R' -> KeyEvent.KEYCODE_R
'S' -> KeyEvent.KEYCODE_S
'T' -> KeyEvent.KEYCODE_T
'U' -> KeyEvent.KEYCODE_U
'V' -> KeyEvent.KEYCODE_V
'W' -> KeyEvent.KEYCODE_W
'X' -> KeyEvent.KEYCODE_X
'Y' -> KeyEvent.KEYCODE_Y
'Z' -> KeyEvent.KEYCODE_Z
else -> KeyEvent.KEYCODE_UNKNOWN
}
else when (this) {
*/
@JvmStatic fun keyCodeToKeyEventCode(keyCode: Int) = when (keyCode) {
ARROW_UP -> KeyEvent.KEYCODE_DPAD_UP
ARROW_RIGHT -> KeyEvent.KEYCODE_DPAD_RIGHT
ARROW_DOWN -> KeyEvent.KEYCODE_DPAD_DOWN
@ -303,6 +248,67 @@ object KeyCode {
F10 -> KeyEvent.KEYCODE_F10
F11 -> KeyEvent.KEYCODE_F11
F12 -> KeyEvent.KEYCODE_F12
else -> if (keyCode < 0) KeyEvent.KEYCODE_UNKNOWN else keyCode
}
// todo: there are many more keys, see near https://developer.android.com/reference/android/view/KeyEvent#KEYCODE_0
/**
* Convert a codePoint to a KeyEvent.KEYCODE_<xxx>.
* Fallback to KeyEvent.KEYCODE_UNKNOWN.
* To be uses for fake hardware key press.
*/
@JvmStatic fun codePointToKeyEventCode(codePoint: Int): Int = when (codePoint.toChar().uppercaseChar()) {
'/' -> KeyEvent.KEYCODE_SLASH
'\\' -> KeyEvent.KEYCODE_BACKSLASH
';' -> KeyEvent.KEYCODE_SEMICOLON
',' -> KeyEvent.KEYCODE_COMMA
'.' -> KeyEvent.KEYCODE_PERIOD
'\'' -> KeyEvent.KEYCODE_APOSTROPHE
'`' -> KeyEvent.KEYCODE_GRAVE
'*' -> KeyEvent.KEYCODE_STAR
']' -> KeyEvent.KEYCODE_RIGHT_BRACKET
'[' -> KeyEvent.KEYCODE_LEFT_BRACKET
'+' -> KeyEvent.KEYCODE_PLUS
'-' -> KeyEvent.KEYCODE_MINUS
'=' -> KeyEvent.KEYCODE_EQUALS
'\n' -> KeyEvent.KEYCODE_ENTER
'\t' -> KeyEvent.KEYCODE_TAB
'0' -> KeyEvent.KEYCODE_0
'1' -> KeyEvent.KEYCODE_1
'2' -> KeyEvent.KEYCODE_2
'3' -> KeyEvent.KEYCODE_3
'4' -> KeyEvent.KEYCODE_4
'5' -> KeyEvent.KEYCODE_5
'6' -> KeyEvent.KEYCODE_6
'7' -> KeyEvent.KEYCODE_7
'8' -> KeyEvent.KEYCODE_8
'9' -> KeyEvent.KEYCODE_9
'A' -> KeyEvent.KEYCODE_A
'B' -> KeyEvent.KEYCODE_B
'C' -> KeyEvent.KEYCODE_C
'D' -> KeyEvent.KEYCODE_D
'E' -> KeyEvent.KEYCODE_E
'F' -> KeyEvent.KEYCODE_F
'G' -> KeyEvent.KEYCODE_G
'H' -> KeyEvent.KEYCODE_H
'I' -> KeyEvent.KEYCODE_I
'J' -> KeyEvent.KEYCODE_J
'K' -> KeyEvent.KEYCODE_K
'L' -> KeyEvent.KEYCODE_L
'M' -> KeyEvent.KEYCODE_M
'N' -> KeyEvent.KEYCODE_N
'O' -> KeyEvent.KEYCODE_O
'P' -> KeyEvent.KEYCODE_P
'Q' -> KeyEvent.KEYCODE_Q
'R' -> KeyEvent.KEYCODE_R
'S' -> KeyEvent.KEYCODE_S
'T' -> KeyEvent.KEYCODE_T
'U' -> KeyEvent.KEYCODE_U
'V' -> KeyEvent.KEYCODE_V
'W' -> KeyEvent.KEYCODE_W
'X' -> KeyEvent.KEYCODE_X
'Y' -> KeyEvent.KEYCODE_Y
'Z' -> KeyEvent.KEYCODE_Z
else -> KeyEvent.KEYCODE_UNKNOWN
}
}

View file

@ -7,15 +7,11 @@
package helium314.keyboard.latin.define
object ProductionFlags {
const val IS_HARDWARE_KEYBOARD_SUPPORTED = false
// todo: make it work
// was set to true in hangul branch (and there is the hangul hardware event decoder in latinIme)
// but disabled again because this breaks ctrl+c / ctrl+v, and most likely other things
// so it looks like the HardwareKeyboardEventDecoder needs some work before it's ready
const val IS_HARDWARE_KEYBOARD_SUPPORTED = true
/**
* Include all suggestions from all dictionaries in
* [helium314.keyboard.latin.SuggestedWords.mRawSuggestions].
*/
const val INCLUDE_RAW_SUGGESTIONS = false
}
}

View file

@ -643,7 +643,8 @@ public final class InputLogic {
*/
private void handleFunctionalEvent(final Event event, final InputTransaction inputTransaction,
final String currentKeyboardScript, final LatinIME.UIHandler handler) {
switch (event.getMKeyCode()) {
final int keyCode = event.getMKeyCode();
switch (keyCode) {
case KeyCode.DELETE:
handleBackspaceEvent(event, inputTransaction, currentKeyboardScript);
// Backspace is a functional key, but it affects the contents of the editor.
@ -686,7 +687,7 @@ public final class InputLogic {
case KeyCode.SHIFT_ENTER:
// todo: try using sendDownUpKeyEventWithMetaState() and remove the key code maybe
final Event tmpEvent = Event.createSoftwareKeypressEvent(Constants.CODE_ENTER,
event.getMKeyCode(), 0, event.getMX(), event.getMY(), event.isKeyRepeat());
keyCode, 0, event.getMX(), event.getMY(), event.isKeyRepeat());
handleNonSpecialCharacterEvent(tmpEvent, inputTransaction, handler);
// Shift + Enter is treated as a functional key but it results in adding a new
// line, so that does affect the contents of the editor.
@ -777,23 +778,19 @@ public final class InputLogic {
case KeyCode.CAPS_LOCK, KeyCode.EMOJI, KeyCode.TOGGLE_ONE_HANDED_MODE, KeyCode.SWITCH_ONE_HANDED_MODE:
break;
default:
if (KeyCode.INSTANCE.isModifier(event.getMKeyCode()))
return; // continuation of previous switch case, but modifiers are in a separate place
if (event.getMMetaState() != 0) {
// need to convert codepoint to KeyEvent.KEYCODE_<xxx>
final int codeToConvert = event.getMKeyCode() < 0 ? event.getMKeyCode() : event.getMCodePoint();
int keyEventCode = KeyCode.INSTANCE.toKeyEventCode(codeToConvert);
if (keyEventCode != KeyEvent.KEYCODE_UNKNOWN)
sendDownUpKeyEventWithMetaState(keyEventCode, event.getMMetaState());
return; // never crash if user inputs sth we don't have a KeyEvent.KEYCODE for
} else if (event.getMKeyCode() < 0) {
int keyEventCode = KeyCode.INSTANCE.toKeyEventCode(event.getMKeyCode());
if (keyEventCode != KeyEvent.KEYCODE_UNKNOWN) {
sendDownUpKeyEvent(keyEventCode);
return;
}
if (KeyCode.INSTANCE.isModifier(keyCode))
return; // continuation of previous switch case above, but modifiers are held in a separate place
final int keyEventCode = event.getMCodePoint() <= 0
? KeyCode.keyCodeToKeyEventCode(keyCode)
: KeyCode.codePointToKeyEventCode(event.getMCodePoint());
if (keyEventCode != KeyEvent.KEYCODE_UNKNOWN) {
sendDownUpKeyEventWithMetaState(keyEventCode, event.getMMetaState());
return;
}
throw new RuntimeException("Unknown key code : " + event.getMKeyCode());
// unknown event
Log.e(TAG, "unknown event, key code: "+keyCode+", functional: "+event.isFunctionalKeyEvent()+", meta: "+event.getMMetaState());
if (DebugFlags.DEBUG_ENABLED)
throw new RuntimeException("Unknown event");
}
}