From 8e37bed3b67e36669b35cfc8eb796d5103a60ffa Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 26 Oct 2017 10:41:38 -0700 Subject: [PATCH] android: Fix softkeyboard issue in SDL on Android. --- .../main/java/org/libsdl/app/SDLActivity.java | 31 ++++++++++-------- src/core/android/SDL_android.c | 32 +++++++++++++++++++ 2 files changed, 49 insertions(+), 14 deletions(-) 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 5d2ef4adc..241e4b92f 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 c3a9ba5f3..4fe6e8c92 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -31,6 +31,8 @@ #include "SDL_android.h" #include +#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)