Allow trapping the back button so right mouse click can work on some Android systems (thanks Rachel!)
authorSam Lantinga <slouken@libsdl.org>
Thu, 12 Jul 2018 13:28:13 -0700
changeset 12059320b43d5e5a7
parent 12058 1a1133e9c7d4
child 12060 c5ea08c1b9b6
Allow trapping the back button so right mouse click can work on some Android systems (thanks Rachel!)
Also, added a function SDL_AndroidBackButton() so applications can respond to the back button directly
Android.mk
android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
include/SDL_hints.h
include/SDL_system.h
src/core/android/SDL_android.c
src/dynapi/SDL_dynapi_overrides.h
src/dynapi/SDL_dynapi_procs.h
     1.1 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java	Thu Jul 05 23:01:10 2018 +0300
     1.2 +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java	Thu Jul 12 13:28:13 2018 -0700
     1.3 @@ -363,6 +363,43 @@
     1.4      }
     1.5  
     1.6      @Override
     1.7 +    public void onBackPressed() {
     1.8 +        // Check if we want to block the back button in case of mouse right click.
     1.9 +        //
    1.10 +        // If we do, the normal hardware back button will no longer work and people have to use home,
    1.11 +        // but the mouse right click will work.
    1.12 +        //
    1.13 +        String trapBack = SDLActivity.nativeGetHint("SDL_ANDROID_TRAP_BACK_BUTTON");
    1.14 +        if ((trapBack != null) && trapBack.equals("1")) {
    1.15 +            // Exit and let the mouse handler handle this button (if appropriate)
    1.16 +            return;
    1.17 +        }
    1.18 +
    1.19 +        // Default system back button behavior.
    1.20 +        super.onBackPressed();
    1.21 +    }
    1.22 +
    1.23 +    // Called by JNI from SDL.
    1.24 +    public static void manualBackButton() {
    1.25 +        mSingleton.pressBackButton();
    1.26 +    }
    1.27 +
    1.28 +    // Used to get us onto the activity's main thread
    1.29 +    public void pressBackButton() {
    1.30 +        runOnUiThread(new Runnable() {
    1.31 +            @Override
    1.32 +            public void run() {
    1.33 +                SDLActivity.this.superOnBackPressed();
    1.34 +            }
    1.35 +        });
    1.36 +    }
    1.37 +
    1.38 +    // Used to access the system back behavior.
    1.39 +    public void superOnBackPressed() {
    1.40 +        super.onBackPressed();
    1.41 +    }
    1.42 +
    1.43 +    @Override
    1.44      public boolean dispatchKeyEvent(KeyEvent event) {
    1.45  
    1.46          if (SDLActivity.mBrokenLibraries) {
     2.1 --- a/include/SDL_hints.h	Thu Jul 05 23:01:10 2018 +0300
     2.2 +++ b/include/SDL_hints.h	Thu Jul 12 13:28:13 2018 -0700
     2.3 @@ -753,6 +753,23 @@
     2.4  #define SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH "SDL_ANDROID_SEPARATE_MOUSE_AND_TOUCH"
     2.5  
     2.6   /**
     2.7 + * \brief A variable to control whether we trap the Android back button to handle it manually.
     2.8 + *        This is necessary for the right mouse button to work on some Android devices, or
     2.9 + *        to be able to trap the back button for use in your code reliably.  If set to true,
    2.10 + *        the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of 
    2.11 + *        SDL_SCANCODE_AC_BACK.
    2.12 + *
    2.13 + * The variable can be set to the following values:
    2.14 + *   "0"       - Back button will be handled as usual for system. (default)
    2.15 + *   "1"       - Back button will be trapped, allowing you to handle the key press
    2.16 + *               manually.  (This will also let right mouse click work on systems 
    2.17 + *               where the right mouse button functions as back.)
    2.18 + *
    2.19 + * The value of this hint is used at runtime, so it can be changed at any time.
    2.20 + */
    2.21 +#define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON"
    2.22 +
    2.23 + /**
    2.24   * \brief A variable to control whether the return key on the soft keyboard
    2.25   *        should hide the soft keyboard on Android and iOS.
    2.26   *
     3.1 --- a/include/SDL_system.h	Thu Jul 05 23:01:10 2018 +0300
     3.2 +++ b/include/SDL_system.h	Thu Jul 12 13:28:13 2018 -0700
     3.3 @@ -136,6 +136,11 @@
     3.4  extern DECLSPEC SDL_bool SDLCALL SDL_IsDeXMode(void);
     3.5  
     3.6  /**
     3.7 + \brief Trigger the Android system back button behavior.
     3.8 + */
     3.9 +extern DECLSPEC void SDLCALL SDL_AndroidBackButton(void);
    3.10 +
    3.11 +/**
    3.12     See the official Android developer guide for more information:
    3.13     http://developer.android.com/guide/topics/data/data-storage.html
    3.14  */
     4.1 --- a/src/core/android/SDL_android.c	Thu Jul 05 23:01:10 2018 +0300
     4.2 +++ b/src/core/android/SDL_android.c	Thu Jul 12 13:28:13 2018 -0700
     4.3 @@ -216,6 +216,7 @@
     4.4  static jmethodID midIsAndroidTV;
     4.5  static jmethodID midIsChromebook;
     4.6  static jmethodID midIsDeXMode;
     4.7 +static jmethodID midManualBackButton;
     4.8  static jmethodID midInputGetInputDeviceIds;
     4.9  static jmethodID midSendMessage;
    4.10  static jmethodID midShowTextInput;
    4.11 @@ -323,6 +324,8 @@
    4.12                                  "isChromebook", "()Z");
    4.13      midIsDeXMode = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    4.14                                  "isDeXMode", "()Z");
    4.15 +    midManualBackButton = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    4.16 +                                "manualBackButton", "()V");
    4.17      midInputGetInputDeviceIds = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    4.18                                  "inputGetInputDeviceIds", "(I)[I");
    4.19      midSendMessage = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    4.20 @@ -357,7 +360,7 @@
    4.21         !midClipboardSetText || !midClipboardGetText || !midClipboardHasText ||
    4.22         !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables || !midGetDisplayDPI ||
    4.23         !midCreateCustomCursor || !midSetCustomCursor || !midSetSystemCursor || !midSupportsRelativeMouse || !midSetRelativeMouseEnabled ||
    4.24 -       !midIsChromebook || !midIsDeXMode) {
    4.25 +       !midIsChromebook || !midIsDeXMode || !midManualBackButton) {
    4.26          __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?");
    4.27      }
    4.28  
    4.29 @@ -2045,6 +2048,12 @@
    4.30      return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsDeXMode);
    4.31  }
    4.32  
    4.33 +void SDL_AndroidBackButton(void)
    4.34 +{
    4.35 +    JNIEnv *env = Android_JNI_GetEnv();
    4.36 +    return (*env)->CallStaticVoidMethod(env, mActivityClass, midManualBackButton);
    4.37 +}
    4.38 +
    4.39  const char * SDL_AndroidGetInternalStoragePath(void)
    4.40  {
    4.41      static char *s_AndroidInternalFilesPath = NULL;
     5.1 --- a/src/dynapi/SDL_dynapi_overrides.h	Thu Jul 05 23:01:10 2018 +0300
     5.2 +++ b/src/dynapi/SDL_dynapi_overrides.h	Thu Jul 12 13:28:13 2018 -0700
     5.3 @@ -674,3 +674,4 @@
     5.4  #define SDL_HasAVX512F SDL_HasAVX512F_REAL
     5.5  #define SDL_IsChromebook SDL_IsChromebook_REAL
     5.6  #define SDL_IsDeXMode SDL_IsDeXMode_REAL
     5.7 +#define SDL_AndroidBackButton SDL_AndroidBackButton_REAL
     6.1 --- a/src/dynapi/SDL_dynapi_procs.h	Thu Jul 05 23:01:10 2018 +0300
     6.2 +++ b/src/dynapi/SDL_dynapi_procs.h	Thu Jul 12 13:28:13 2018 -0700
     6.3 @@ -716,3 +716,6 @@
     6.4  SDL_DYNAPI_PROC(SDL_bool,SDL_IsChromebook,(void),(),return)
     6.5  SDL_DYNAPI_PROC(SDL_bool,SDL_IsDeXMode,(void),(),return)
     6.6  #endif
     6.7 +#ifdef __ANDROID__
     6.8 +SDL_DYNAPI_PROC(void,SDL_AndroidBackButton,(void),(),return)
     6.9 +#endif