summaryrefslogtreecommitdiff
path: root/platform/android
diff options
context:
space:
mode:
authorbruvzg <7645683+bruvzg@users.noreply.github.com>2022-12-11 01:21:22 +0200
committerbruvzg <7645683+bruvzg@users.noreply.github.com>2023-01-23 15:08:12 +0200
commitdaad4aed62bfa471421f960179f0ac0fd78e8040 (patch)
tree86b7f69d180f253c51c4b567139d68850f9e365d /platform/android
parent9937915ad77059b63582ffd4e324afb26f467b76 (diff)
Cleanup and unify keyboard input.
- Unify keycode values (secondary label printed on a key), remove unused hardcoded Latin-1 codes. - Unify IME behaviour, add inline composition string display on Windows and X11. - Add key_label (localized label printed on a key) value to the key events, and allow mapping actions to the unshifted Unicode events. - Add support for physical keyboard (Bluetooth or Sidecar) handling on iOS. - Add support for media key handling on macOS. Co-authored-by: Raul Santos <raulsntos@gmail.com>
Diffstat (limited to 'platform/android')
-rw-r--r--platform/android/android_input_handler.cpp10
-rw-r--r--platform/android/android_input_handler.h2
-rw-r--r--platform/android/android_keys_utils.cpp38
-rw-r--r--platform/android/android_keys_utils.h3
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java10
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java22
-rw-r--r--platform/android/java_godot_lib_jni.cpp4
-rw-r--r--platform/android/java_godot_lib_jni.h2
9 files changed, 26 insertions, 67 deletions
diff --git a/platform/android/android_input_handler.cpp b/platform/android/android_input_handler.cpp
index e3f93086dc..277195a054 100644
--- a/platform/android/android_input_handler.cpp
+++ b/platform/android/android_input_handler.cpp
@@ -56,7 +56,7 @@ void AndroidInputHandler::_set_key_modifier_state(Ref<InputEventWithModifiers> e
ev->set_ctrl_pressed(control_mem);
}
-void AndroidInputHandler::process_key_event(int p_keycode, int p_physical_keycode, int p_unicode, bool p_pressed) {
+void AndroidInputHandler::process_key_event(int p_physical_keycode, int p_unicode, int p_key_label, bool p_pressed) {
static char32_t prev_wc = 0;
char32_t unicode = p_unicode;
if ((p_unicode & 0xfffffc00) == 0xd800) {
@@ -80,10 +80,7 @@ void AndroidInputHandler::process_key_event(int p_keycode, int p_physical_keycod
ev.instantiate();
Key physical_keycode = godot_code_from_android_code(p_physical_keycode);
- Key keycode = physical_keycode;
- if (p_keycode != 0) {
- keycode = godot_code_from_unicode(p_keycode);
- }
+ Key keycode = fix_keycode(unicode, physical_keycode);
switch (physical_keycode) {
case Key::SHIFT: {
@@ -104,7 +101,8 @@ void AndroidInputHandler::process_key_event(int p_keycode, int p_physical_keycod
ev->set_keycode(keycode);
ev->set_physical_keycode(physical_keycode);
- ev->set_unicode(unicode);
+ ev->set_key_label(fix_key_label(p_key_label, keycode));
+ ev->set_unicode(fix_unicode(unicode));
ev->set_pressed(p_pressed);
_set_key_modifier_state(ev);
diff --git a/platform/android/android_input_handler.h b/platform/android/android_input_handler.h
index 34259efd81..6e53dcfc89 100644
--- a/platform/android/android_input_handler.h
+++ b/platform/android/android_input_handler.h
@@ -97,7 +97,7 @@ public:
void process_magnify(Point2 p_pos, float p_factor);
void process_pan(Point2 p_pos, Vector2 p_delta);
void process_joy_event(JoypadEvent p_event);
- void process_key_event(int p_keycode, int p_physical_keycode, int p_unicode, bool p_pressed);
+ void process_key_event(int p_physical_keycode, int p_unicode, int p_key_label, bool p_pressed);
};
#endif // ANDROID_INPUT_HANDLER_H
diff --git a/platform/android/android_keys_utils.cpp b/platform/android/android_keys_utils.cpp
index 0dc2d19cdd..f50437e82a 100644
--- a/platform/android/android_keys_utils.cpp
+++ b/platform/android/android_keys_utils.cpp
@@ -38,41 +38,3 @@ Key godot_code_from_android_code(unsigned int p_code) {
}
return Key::UNKNOWN;
}
-
-Key godot_code_from_unicode(unsigned int p_code) {
- unsigned int code = p_code;
- if (code > 0xFF) {
- return Key::UNKNOWN;
- }
- // Known control codes.
- if (code == '\b') { // 0x08
- return Key::BACKSPACE;
- }
- if (code == '\t') { // 0x09
- return Key::TAB;
- }
- if (code == '\n') { // 0x0A
- return Key::ENTER;
- }
- if (code == 0x1B) {
- return Key::ESCAPE;
- }
- if (code == 0x1F) {
- return Key::KEY_DELETE;
- }
- // Unknown control codes.
- if (code <= 0x1F || (code >= 0x80 && code <= 0x9F)) {
- return Key::UNKNOWN;
- }
- // Convert to uppercase.
- if (code >= 'a' && code <= 'z') { // 0x61 - 0x7A
- code -= ('a' - 'A');
- }
- if (code >= u'à' && code <= u'ö') { // 0xE0 - 0xF6
- code -= (u'à' - u'À'); // 0xE0 - 0xC0
- }
- if (code >= u'ø' && code <= u'þ') { // 0xF8 - 0xFF
- code -= (u'ø' - u'Ø'); // 0xF8 - 0xD8
- }
- return Key(code);
-}
diff --git a/platform/android/android_keys_utils.h b/platform/android/android_keys_utils.h
index 33e7929278..3a587dd680 100644
--- a/platform/android/android_keys_utils.h
+++ b/platform/android/android_keys_utils.h
@@ -165,13 +165,14 @@ static AndroidGodotCodePair android_godot_code_pairs[] = {
{ AKEYCODE_NUMPAD_DOT, Key::KP_PERIOD }, // (158) Numeric keypad '.' key (for decimals or digit grouping).
{ AKEYCODE_NUMPAD_ENTER, Key::KP_ENTER }, // (160) Numeric keypad Enter key.
{ AKEYCODE_VOLUME_MUTE, Key::VOLUMEMUTE }, // (164) Volume Mute key.
+ { AKEYCODE_EISU, Key::JIS_EISU }, // (212) JIS EISU key.
{ AKEYCODE_YEN, Key::YEN }, // (216) Japanese Yen key.
+ { AKEYCODE_KANA, Key::JIS_KANA }, // (218) JIS KANA key.
{ AKEYCODE_HELP, Key::HELP }, // (259) Help key.
{ AKEYCODE_REFRESH, Key::REFRESH }, // (285) Refresh key.
{ AKEYCODE_MAX, Key::UNKNOWN }
};
Key godot_code_from_android_code(unsigned int p_code);
-Key godot_code_from_unicode(unsigned int p_code);
#endif // ANDROID_KEYS_UTILS_H
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
index 31b512d2dd..75a01dc787 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -148,7 +148,7 @@ public class GodotLib {
/**
* Forward regular key events.
*/
- public static native void key(int p_keycode, int p_physical_keycode, int p_unicode, boolean p_pressed);
+ public static native void key(int p_physical_keycode, int p_unicode, int p_key_label, boolean p_pressed);
/**
* Forward game device's key events.
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
index f2bd3e28e6..cedbbfb7c3 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
@@ -129,12 +129,10 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
}
} else {
// getKeyCode(): The physical key that was pressed.
- // Godot's keycodes match the ASCII codes, so for single byte unicode characters,
- // we can use the unmodified unicode character to determine Godot's keycode.
- final int keycode = event.getUnicodeChar(0);
final int physical_keycode = event.getKeyCode();
final int unicode = event.getUnicodeChar();
- GodotLib.key(keycode, physical_keycode, unicode, false);
+ final int key_label = event.getDisplayLabel();
+ GodotLib.key(physical_keycode, unicode, key_label, false);
};
return true;
@@ -166,10 +164,10 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
GodotLib.joybutton(godotJoyId, button, true);
}
} else {
- final int keycode = event.getUnicodeChar(0);
final int physical_keycode = event.getKeyCode();
final int unicode = event.getUnicodeChar();
- GodotLib.key(keycode, physical_keycode, unicode, true);
+ final int key_label = event.getDisplayLabel();
+ GodotLib.key(physical_keycode, unicode, key_label, true);
}
return true;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
index fdfe20f32b..7b628e25ed 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
@@ -93,8 +93,8 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
@Override
public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) {
for (int i = 0; i < count; ++i) {
- GodotLib.key(0, KeyEvent.KEYCODE_DEL, 0, true);
- GodotLib.key(0, KeyEvent.KEYCODE_DEL, 0, false);
+ GodotLib.key(KeyEvent.KEYCODE_DEL, 0, 0, true);
+ GodotLib.key(KeyEvent.KEYCODE_DEL, 0, 0, false);
if (mHasSelection) {
mHasSelection = false;
@@ -110,13 +110,13 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
newChars[i - start] = pCharSequence.charAt(i);
}
for (int i = 0; i < count; ++i) {
- int key = newChars[i];
- if ((key == '\n') && !(mEdit.getKeyboardType() == GodotEditText.VirtualKeyboardType.KEYBOARD_TYPE_MULTILINE)) {
+ final int character = newChars[i];
+ if ((character == '\n') && !(mEdit.getKeyboardType() == GodotEditText.VirtualKeyboardType.KEYBOARD_TYPE_MULTILINE)) {
// Return keys are handled through action events
continue;
}
- GodotLib.key(key, 0, key, true);
- GodotLib.key(key, 0, key, false);
+ GodotLib.key(0, character, 0, true);
+ GodotLib.key(0, character, 0, false);
}
}
@@ -126,17 +126,17 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
final String characters = pKeyEvent.getCharacters();
for (int i = 0; i < characters.length(); i++) {
- final int ch = characters.codePointAt(i);
- GodotLib.key(ch, 0, ch, true);
- GodotLib.key(ch, 0, ch, false);
+ final int character = characters.codePointAt(i);
+ GodotLib.key(0, character, 0, true);
+ GodotLib.key(0, character, 0, false);
}
}
if (pActionID == EditorInfo.IME_ACTION_DONE) {
// Enter key has been pressed
mRenderView.queueOnRenderThread(() -> {
- GodotLib.key(0, KeyEvent.KEYCODE_ENTER, 0, true);
- GodotLib.key(0, KeyEvent.KEYCODE_ENTER, 0, false);
+ GodotLib.key(KeyEvent.KEYCODE_ENTER, 0, 0, true);
+ GodotLib.key(KeyEvent.KEYCODE_ENTER, 0, 0, false);
});
mRenderView.getView().requestFocus();
return true;
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index e6cdd7932a..1ee1cccb82 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -382,11 +382,11 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(
}
// Called on the UI thread
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_physical_keycode, jint p_unicode, jboolean p_pressed) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_physical_keycode, jint p_unicode, jint p_key_label, jboolean p_pressed) {
if (step.get() <= 0) {
return;
}
- input_handler->process_key_event(p_keycode, p_physical_keycode, p_unicode, p_pressed);
+ input_handler->process_key_event(p_physical_keycode, p_unicode, p_key_label, p_pressed);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv *env, jclass clazz, jfloat x, jfloat y, jfloat z) {
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index 3f07a8cfe1..0020ddffd2 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -49,7 +49,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_dispatchMouseEvent(JN
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_dispatchTouchEvent(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jboolean p_double_tap);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_magnify(JNIEnv *env, jclass clazz, jfloat p_x, jfloat p_y, jfloat p_factor);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_pan(JNIEnv *env, jclass clazz, jfloat p_x, jfloat p_y, jfloat p_delta_x, jfloat p_delta_y);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_physical_keycode, jint p_unicode, jboolean p_pressed);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_physical_keycode, jint p_unicode, jint p_key_label, jboolean p_pressed);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jclass clazz, jint p_device, jint p_axis, jfloat p_value);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jclass clazz, jint p_device, jint p_hat_x, jint p_hat_y);