android: Fix softkeyboard issue in SDL on Android.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
index 5d2ef4a..241e4b9 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
@@ -1248,6 +1248,9 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
if ((event.getSource() & InputDevice.SOURCE_KEYBOARD) != 0) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
//Log.v("SDL", "key down: " + keyCode);
+ if (SDLActivity.isTextInputEvent(event)) {
+ SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
+ }
SDLActivity.onNativeKeyDown(keyCode);
return true;
}
@@ -1435,6 +1438,7 @@ class DummyEdit extends View implements View.OnKeyListener {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (SDLActivity.isTextInputEvent(event)) {
ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
+ return true;
}
SDLActivity.onNativeKeyDown(keyCode);
return true;
@@ -1484,26 +1488,23 @@ class SDLInputConnection extends BaseInputConnection {
@Override
public boolean sendKeyEvent(KeyEvent event) {
/*
- * This handles the keycodes from soft keyboard (and IME-translated input from hardkeyboard)
+ * This used to handle the keycodes from soft keyboard (and IME-translated input from hardkeyboard)
+ * However, as of Ice Cream Sandwich and later, almost all soft keyboard doesn't generate key presses
+ * and so we need to generate them ourselves in commitText. To avoid duplicates on the handful of keys
+ * that still do, we empty this out.
*/
- int keyCode = event.getKeyCode();
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- if (SDLActivity.isTextInputEvent(event)) {
- commitText(String.valueOf((char) event.getUnicodeChar()), 1);
- }
- SDLActivity.onNativeKeyDown(keyCode);
- return true;
- } else if (event.getAction() == KeyEvent.ACTION_UP) {
- SDLActivity.onNativeKeyUp(keyCode);
- return true;
- }
return super.sendKeyEvent(event);
}
@Override
public boolean commitText(CharSequence text, int newCursorPosition) {
- nativeCommitText(text.toString(), newCursorPosition);
+ for (int i = 0; i < text.length(); i++) {
+ char c = text.charAt(i);
+ nativeGenerateScancodeForUnichar(c);
+ }
+
+ SDLInputConnection.nativeCommitText(text.toString(), newCursorPosition);
return super.commitText(text, newCursorPosition);
}
@@ -1516,7 +1517,9 @@ class SDLInputConnection extends BaseInputConnection {
return super.setComposingText(text, newCursorPosition);
}
- public native void nativeCommitText(String text, int newCursorPosition);
+ public static native void nativeCommitText(String text, int newCursorPosition);
+
+ public native void nativeGenerateScancodeForUnichar(char c);
public native void nativeSetComposingText(String text, int newCursorPosition);
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index c3a9ba5..4fe6e8c 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -31,6 +31,8 @@
#include "SDL_android.h"
#include <EGL/egl.h>
+#include "keyinfotable.h"
+
#include "../../events/SDL_events_c.h"
#include "../../video/android/SDL_androidkeyboard.h"
#include "../../video/android/SDL_androidmouse.h"
@@ -749,6 +751,36 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(
(*env)->ReleaseStringUTFChars(env, text, utftext);
}
+JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)(
+ JNIEnv* env, jclass cls,
+ jchar chUnicode)
+{
+ SDL_Scancode code = SDL_SCANCODE_UNKNOWN;
+ uint16_t mod = 0;
+
+ // We do not care about bigger than 127.
+ if (chUnicode < 127) {
+ AndroidKeyInfo info = unicharToAndroidKeyInfoTable[chUnicode];
+ code = info.code;
+ mod = info.mod;
+ }
+
+ if (mod & KMOD_SHIFT) {
+ /* If character uses shift, press shift down */
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);
+ }
+
+ /* send a keydown and keyup even for the character */
+ SDL_SendKeyboardKey(SDL_PRESSED, code);
+ SDL_SendKeyboardKey(SDL_RELEASED, code);
+
+ if (mod & KMOD_SHIFT) {
+ /* If character uses shift, press shift back up */
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
+ }
+}
+
+
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)(
JNIEnv* env, jclass cls,
jstring text, jint newCursorPosition)