android: Fix softkeyboard issue in SDL on Android.
authorSam Lantinga <slouken@libsdl.org>
Thu, 26 Oct 2017 10:41:38 -0700
changeset 11655ccf47d584003
parent 11654 64ae77236054
child 11656 c351a823c2af
android: Fix softkeyboard issue in SDL on Android.
android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
src/core/android/SDL_android.c
     1.1 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java	Wed Oct 25 18:02:11 2017 -0400
     1.2 +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java	Thu Oct 26 10:41:38 2017 -0700
     1.3 @@ -1248,6 +1248,9 @@
     1.4          if ((event.getSource() & InputDevice.SOURCE_KEYBOARD) != 0) {
     1.5              if (event.getAction() == KeyEvent.ACTION_DOWN) {
     1.6                  //Log.v("SDL", "key down: " + keyCode);
     1.7 +                if (SDLActivity.isTextInputEvent(event)) {
     1.8 +                    SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
     1.9 +                }
    1.10                  SDLActivity.onNativeKeyDown(keyCode);
    1.11                  return true;
    1.12              }
    1.13 @@ -1435,6 +1438,7 @@
    1.14          if (event.getAction() == KeyEvent.ACTION_DOWN) {
    1.15              if (SDLActivity.isTextInputEvent(event)) {
    1.16                  ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
    1.17 +                return true;
    1.18              }
    1.19              SDLActivity.onNativeKeyDown(keyCode);
    1.20              return true;
    1.21 @@ -1484,26 +1488,23 @@
    1.22      @Override
    1.23      public boolean sendKeyEvent(KeyEvent event) {
    1.24          /*
    1.25 -         * This handles the keycodes from soft keyboard (and IME-translated input from hardkeyboard)
    1.26 +         * This used to handle the keycodes from soft keyboard (and IME-translated input from hardkeyboard)
    1.27 +         * However, as of Ice Cream Sandwich and later, almost all soft keyboard doesn't generate key presses
    1.28 +         * and so we need to generate them ourselves in commitText.  To avoid duplicates on the handful of keys
    1.29 +         * that still do, we empty this out.
    1.30           */
    1.31 -        int keyCode = event.getKeyCode();
    1.32 -        if (event.getAction() == KeyEvent.ACTION_DOWN) {
    1.33 -            if (SDLActivity.isTextInputEvent(event)) {
    1.34 -                commitText(String.valueOf((char) event.getUnicodeChar()), 1);
    1.35 -            }
    1.36 -            SDLActivity.onNativeKeyDown(keyCode);
    1.37 -            return true;
    1.38 -        } else if (event.getAction() == KeyEvent.ACTION_UP) {
    1.39 -            SDLActivity.onNativeKeyUp(keyCode);
    1.40 -            return true;
    1.41 -        }
    1.42          return super.sendKeyEvent(event);
    1.43      }
    1.44  
    1.45      @Override
    1.46      public boolean commitText(CharSequence text, int newCursorPosition) {
    1.47  
    1.48 -        nativeCommitText(text.toString(), newCursorPosition);
    1.49 +        for (int i = 0; i < text.length(); i++) {
    1.50 +            char c = text.charAt(i);
    1.51 +            nativeGenerateScancodeForUnichar(c);
    1.52 +        }
    1.53 +
    1.54 +        SDLInputConnection.nativeCommitText(text.toString(), newCursorPosition);
    1.55  
    1.56          return super.commitText(text, newCursorPosition);
    1.57      }
    1.58 @@ -1516,7 +1517,9 @@
    1.59          return super.setComposingText(text, newCursorPosition);
    1.60      }
    1.61  
    1.62 -    public native void nativeCommitText(String text, int newCursorPosition);
    1.63 +    public static native void nativeCommitText(String text, int newCursorPosition);
    1.64 +
    1.65 +    public native void nativeGenerateScancodeForUnichar(char c);
    1.66  
    1.67      public native void nativeSetComposingText(String text, int newCursorPosition);
    1.68  
     2.1 --- a/src/core/android/SDL_android.c	Wed Oct 25 18:02:11 2017 -0400
     2.2 +++ b/src/core/android/SDL_android.c	Thu Oct 26 10:41:38 2017 -0700
     2.3 @@ -31,6 +31,8 @@
     2.4  #include "SDL_android.h"
     2.5  #include <EGL/egl.h>
     2.6  
     2.7 +#include "keyinfotable.h"
     2.8 +
     2.9  #include "../../events/SDL_events_c.h"
    2.10  #include "../../video/android/SDL_androidkeyboard.h"
    2.11  #include "../../video/android/SDL_androidmouse.h"
    2.12 @@ -749,6 +751,36 @@
    2.13      (*env)->ReleaseStringUTFChars(env, text, utftext);
    2.14  }
    2.15  
    2.16 +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)(
    2.17 +                                    JNIEnv* env, jclass cls,
    2.18 +                                    jchar chUnicode)
    2.19 +{
    2.20 +    SDL_Scancode code = SDL_SCANCODE_UNKNOWN;
    2.21 +    uint16_t mod = 0;
    2.22 +
    2.23 +    // We do not care about bigger than 127.
    2.24 +    if (chUnicode < 127) {
    2.25 +        AndroidKeyInfo info = unicharToAndroidKeyInfoTable[chUnicode];
    2.26 +        code = info.code;
    2.27 +        mod = info.mod;
    2.28 +    }
    2.29 +
    2.30 +    if (mod & KMOD_SHIFT) {
    2.31 +        /* If character uses shift, press shift down */
    2.32 +        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);
    2.33 +    }
    2.34 +
    2.35 +    /* send a keydown and keyup even for the character */
    2.36 +    SDL_SendKeyboardKey(SDL_PRESSED, code);
    2.37 +    SDL_SendKeyboardKey(SDL_RELEASED, code);
    2.38 +
    2.39 +    if (mod & KMOD_SHIFT) {
    2.40 +        /* If character uses shift, press shift back up */
    2.41 +        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
    2.42 +    }
    2.43 +}
    2.44 +
    2.45 +
    2.46  JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)(
    2.47                                      JNIEnv* env, jclass cls,
    2.48                                      jstring text, jint newCursorPosition)