add new key codes for a bunch of hw keyboard keys (no labels except for escape)

also make sure they are handled together with meta-state (e.g. ctrl+arrow keys)
fixes #237
This commit is contained in:
Helium314 2024-06-30 11:27:45 +02:00
parent beb52d322f
commit 2f6bef478e
4 changed files with 137 additions and 87 deletions

View file

@ -137,8 +137,32 @@ object KeyCode {
const val PAGE_UP = -10010
const val PAGE_DOWN = -10011
const val META = -10012
const val META_LOCK = -10013 // to be consistent with the CTRL/ALT(/FN LOCK codes, not sure whether this will be used
const val META_LOCK = -10013 // to be consistent with the CTRL/ALT/FN LOCK codes, not sure whether this will be used
const val TAB = -10014
const val ESCAPE = -10017
const val INSERT = -10018
const val SLEEP = -10019
const val MEDIA_PLAY = -10020
const val MEDIA_PAUSE = -10021
const val MEDIA_PLAY_PAUSE = -10022
const val MEDIA_NEXT = -10023
const val MEDIA_PREVIOUS = -10024
const val VOL_UP = -10025
const val VOL_DOWN = -10026
const val MUTE = -10027
const val F1 = -10028
const val F2 = -10029
const val F3 = -10030
const val F4 = -10031
const val F5 = -10032
const val F6 = -10033
const val F7 = -10034
const val F8 = -10035
const val F9 = -10036
const val F10 = -10037
const val F11 = -10038
const val F12 = -10039
const val BACK = -10040
/** to make sure a FlorisBoard code works when reading a JSON layout */
fun Int.checkAndConvertCode(): Int = if (this > 0) this else when (this) {
@ -151,7 +175,9 @@ object KeyCode {
// heliboard only
SYMBOL_ALPHA, START_ONE_HANDED_MODE, STOP_ONE_HANDED_MODE, SWITCH_ONE_HANDED_MODE, SHIFT_ENTER,
ACTION_NEXT, ACTION_PREVIOUS, NOT_SPECIFIED, CLIPBOARD_COPY_ALL, PAGE_UP, PAGE_DOWN, META, TAB
ACTION_NEXT, ACTION_PREVIOUS, NOT_SPECIFIED, CLIPBOARD_COPY_ALL, PAGE_UP, PAGE_DOWN, META, TAB,
ESCAPE, INSERT, SLEEP, MEDIA_PLAY, MEDIA_PAUSE, MEDIA_PLAY_PAUSE, MEDIA_NEXT, MEDIA_PREVIOUS,
VOL_UP, VOL_DOWN, MUTE, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, BACK
-> this
// conversion
@ -162,10 +188,25 @@ object KeyCode {
else -> throw IllegalStateException("key code $this not yet supported")
}
// todo: add more keys, see near https://developer.android.com/reference/android/view/KeyEvent#KEYCODE_0
// maybe not toChar for conversion of some special keys?
/** convert a codePoint to a KeyEvent.KEYCODE_<xxx>, fallback to KeyEvent.KEYCODE_UNKNOWN */
fun Int.toKeyEventCode(): Int = when (this.toChar().uppercaseChar()) {
// todo: three 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 */
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
@ -204,4 +245,40 @@ object KeyCode {
'Z' -> KeyEvent.KEYCODE_Z
else -> KeyEvent.KEYCODE_UNKNOWN
}
else when (this) {
ARROW_UP -> KeyEvent.KEYCODE_DPAD_UP
ARROW_RIGHT -> KeyEvent.KEYCODE_DPAD_RIGHT
ARROW_DOWN -> KeyEvent.KEYCODE_DPAD_DOWN
ARROW_LEFT -> KeyEvent.KEYCODE_DPAD_LEFT
MOVE_START_OF_LINE -> KeyEvent.KEYCODE_MOVE_HOME
MOVE_END_OF_LINE -> KeyEvent.KEYCODE_MOVE_END
TAB -> KeyEvent.KEYCODE_TAB
PAGE_UP -> KeyEvent.KEYCODE_PAGE_UP
PAGE_DOWN -> KeyEvent.KEYCODE_PAGE_DOWN
ESCAPE -> KeyEvent.KEYCODE_ESCAPE
INSERT -> KeyEvent.KEYCODE_INSERT
SLEEP -> KeyEvent.KEYCODE_SLEEP
MEDIA_PLAY -> KeyEvent.KEYCODE_MEDIA_PLAY
MEDIA_PAUSE -> KeyEvent.KEYCODE_MEDIA_PAUSE
MEDIA_PLAY_PAUSE -> KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
MEDIA_NEXT -> KeyEvent.KEYCODE_MEDIA_NEXT
MEDIA_PREVIOUS -> KeyEvent.KEYCODE_MEDIA_PREVIOUS
VOL_UP -> KeyEvent.KEYCODE_VOLUME_UP
VOL_DOWN -> KeyEvent.KEYCODE_VOLUME_DOWN
MUTE -> KeyEvent.KEYCODE_VOLUME_MUTE
BACK -> KeyEvent.KEYCODE_BACK
F1 -> KeyEvent.KEYCODE_F1
F2 -> KeyEvent.KEYCODE_F2
F3 -> KeyEvent.KEYCODE_F3
F4 -> KeyEvent.KEYCODE_F4
F5 -> KeyEvent.KEYCODE_F5
F6 -> KeyEvent.KEYCODE_F6
F7 -> KeyEvent.KEYCODE_F7
F8 -> KeyEvent.KEYCODE_F8
F9 -> KeyEvent.KEYCODE_F9
F10 -> KeyEvent.KEYCODE_F10
F11 -> KeyEvent.KEYCODE_F11
F12 -> KeyEvent.KEYCODE_F12
else -> KeyEvent.KEYCODE_UNKNOWN
}
}

View file

@ -30,6 +30,7 @@ object KeyLabel {
const val FN = "fn"
const val META = "meta"
const val TAB = "tab"
const val ESCAPE = "esc"
/** to make sure a FlorisBoard label works when reading a JSON layout */
// resulting special labels should be names of FunctionalKey enum, case insensitive

View file

@ -488,7 +488,7 @@ sealed interface KeyData : AbstractKeyData {
KeyLabel.CURRENCY3 -> params.mLocaleKeyboardInfos.currencyKey.second[2]
KeyLabel.CURRENCY4 -> params.mLocaleKeyboardInfos.currencyKey.second[3]
KeyLabel.CURRENCY5 -> params.mLocaleKeyboardInfos.currencyKey.second[4]
KeyLabel.CTRL, KeyLabel.ALT, KeyLabel.FN, KeyLabel.META -> label.uppercase(Locale.US)
KeyLabel.CTRL, KeyLabel.ALT, KeyLabel.FN, KeyLabel.META , KeyLabel.ESCAPE -> label.uppercase(Locale.US)
KeyLabel.TAB -> "!icon/tab_key|"
else -> {
if (label in toolbarKeyStrings.values) {

View file

@ -749,64 +749,36 @@ public final class InputLogic {
inputTransaction.setDidAffectContents();
}
break;
case KeyCode.ARROW_LEFT:
sendDownUpKeyEvent(KeyEvent.KEYCODE_DPAD_LEFT);
break;
case KeyCode.ARROW_RIGHT:
sendDownUpKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT);
break;
case KeyCode.ARROW_UP:
sendDownUpKeyEvent(KeyEvent.KEYCODE_DPAD_UP);
break;
case KeyCode.ARROW_DOWN:
sendDownUpKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN);
break;
case KeyCode.UNDO:
sendDownUpKeyEventWithMetaState(KeyEvent.KEYCODE_Z, KeyEvent.META_CTRL_ON);
break;
case KeyCode.REDO:
sendDownUpKeyEventWithMetaState(KeyEvent.KEYCODE_Z, KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON);
break;
case KeyCode.MOVE_START_OF_LINE:
sendDownUpKeyEvent(KeyEvent.KEYCODE_MOVE_HOME);
break;
case KeyCode.MOVE_END_OF_LINE:
sendDownUpKeyEvent(KeyEvent.KEYCODE_MOVE_END);
break;
case KeyCode.PAGE_UP:
sendDownUpKeyEvent(KeyEvent.KEYCODE_PAGE_UP);
break;
case KeyCode.PAGE_DOWN:
sendDownUpKeyEvent(KeyEvent.KEYCODE_PAGE_DOWN);
break;
case KeyCode.TAB:
sendDownUpKeyEvent(KeyEvent.KEYCODE_TAB);
break;
case KeyCode.VOICE_INPUT:
// 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 KeyCode.CAPS_LOCK:
case KeyCode.SYMBOL_ALPHA:
case KeyCode.ALPHA:
case KeyCode.SYMBOL:
case KeyCode.NUMPAD:
case KeyCode.EMOJI:
case KeyCode.START_ONE_HANDED_MODE:
case KeyCode.STOP_ONE_HANDED_MODE:
case KeyCode.SWITCH_ONE_HANDED_MODE:
case KeyCode.CTRL:
case KeyCode.ALT:
case KeyCode.FN:
case KeyCode.META:
case KeyCode.CAPS_LOCK, KeyCode.SYMBOL_ALPHA, KeyCode.ALPHA, KeyCode.SYMBOL, KeyCode.NUMPAD, KeyCode.EMOJI,
KeyCode.START_ONE_HANDED_MODE, KeyCode.STOP_ONE_HANDED_MODE, KeyCode.SWITCH_ONE_HANDED_MODE,
KeyCode.CTRL, KeyCode.ALT, KeyCode.FN, KeyCode.META:
break;
default:
if (event.getMMetaState() != 0) {
// need to convert codepoint to KeyEvent.KEYCODE_<xxx>
int keyEventCode = KeyCode.INSTANCE.toKeyEventCode(event.getMCodePoint());
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());
} else
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;
}
}
throw new RuntimeException("Unknown key code : " + event.getMKeyCode());
}
}