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
This commit is contained in:
Sam Lantinga 2018-07-12 13:28:13 -07:00
parent c74837fbb9
commit ff8c9538bc
7 changed files with 73 additions and 1 deletions

0
Android.mk Normal file → Executable file
View File

View File

@ -362,6 +362,43 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
SDLActivity.initialize(); SDLActivity.initialize();
} }
@Override
public void onBackPressed() {
// Check if we want to block the back button in case of mouse right click.
//
// If we do, the normal hardware back button will no longer work and people have to use home,
// but the mouse right click will work.
//
String trapBack = SDLActivity.nativeGetHint("SDL_ANDROID_TRAP_BACK_BUTTON");
if ((trapBack != null) && trapBack.equals("1")) {
// Exit and let the mouse handler handle this button (if appropriate)
return;
}
// Default system back button behavior.
super.onBackPressed();
}
// Called by JNI from SDL.
public static void manualBackButton() {
mSingleton.pressBackButton();
}
// Used to get us onto the activity's main thread
public void pressBackButton() {
runOnUiThread(new Runnable() {
@Override
public void run() {
SDLActivity.this.superOnBackPressed();
}
});
}
// Used to access the system back behavior.
public void superOnBackPressed() {
super.onBackPressed();
}
@Override @Override
public boolean dispatchKeyEvent(KeyEvent event) { public boolean dispatchKeyEvent(KeyEvent event) {

View File

@ -752,6 +752,23 @@ extern "C" {
*/ */
#define SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH "SDL_ANDROID_SEPARATE_MOUSE_AND_TOUCH" #define SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH "SDL_ANDROID_SEPARATE_MOUSE_AND_TOUCH"
/**
* \brief A variable to control whether we trap the Android back button to handle it manually.
* This is necessary for the right mouse button to work on some Android devices, or
* to be able to trap the back button for use in your code reliably. If set to true,
* the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of
* SDL_SCANCODE_AC_BACK.
*
* The variable can be set to the following values:
* "0" - Back button will be handled as usual for system. (default)
* "1" - Back button will be trapped, allowing you to handle the key press
* manually. (This will also let right mouse click work on systems
* where the right mouse button functions as back.)
*
* The value of this hint is used at runtime, so it can be changed at any time.
*/
#define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON"
/** /**
* \brief A variable to control whether the return key on the soft keyboard * \brief A variable to control whether the return key on the soft keyboard
* should hide the soft keyboard on Android and iOS. * should hide the soft keyboard on Android and iOS.

View File

@ -135,6 +135,11 @@ extern DECLSPEC SDL_bool SDLCALL SDL_IsChromebook(void);
*/ */
extern DECLSPEC SDL_bool SDLCALL SDL_IsDeXMode(void); extern DECLSPEC SDL_bool SDLCALL SDL_IsDeXMode(void);
/**
\brief Trigger the Android system back button behavior.
*/
extern DECLSPEC void SDLCALL SDL_AndroidBackButton(void);
/** /**
See the official Android developer guide for more information: See the official Android developer guide for more information:
http://developer.android.com/guide/topics/data/data-storage.html http://developer.android.com/guide/topics/data/data-storage.html

View File

@ -216,6 +216,7 @@ static jmethodID midGetContext;
static jmethodID midIsAndroidTV; static jmethodID midIsAndroidTV;
static jmethodID midIsChromebook; static jmethodID midIsChromebook;
static jmethodID midIsDeXMode; static jmethodID midIsDeXMode;
static jmethodID midManualBackButton;
static jmethodID midInputGetInputDeviceIds; static jmethodID midInputGetInputDeviceIds;
static jmethodID midSendMessage; static jmethodID midSendMessage;
static jmethodID midShowTextInput; static jmethodID midShowTextInput;
@ -323,6 +324,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c
"isChromebook", "()Z"); "isChromebook", "()Z");
midIsDeXMode = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, midIsDeXMode = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"isDeXMode", "()Z"); "isDeXMode", "()Z");
midManualBackButton = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"manualBackButton", "()V");
midInputGetInputDeviceIds = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, midInputGetInputDeviceIds = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"inputGetInputDeviceIds", "(I)[I"); "inputGetInputDeviceIds", "(I)[I");
midSendMessage = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, midSendMessage = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
@ -357,7 +360,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c
!midClipboardSetText || !midClipboardGetText || !midClipboardHasText || !midClipboardSetText || !midClipboardGetText || !midClipboardHasText ||
!midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables || !midGetDisplayDPI || !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables || !midGetDisplayDPI ||
!midCreateCustomCursor || !midSetCustomCursor || !midSetSystemCursor || !midSupportsRelativeMouse || !midSetRelativeMouseEnabled || !midCreateCustomCursor || !midSetCustomCursor || !midSetSystemCursor || !midSupportsRelativeMouse || !midSetRelativeMouseEnabled ||
!midIsChromebook || !midIsDeXMode) { !midIsChromebook || !midIsDeXMode || !midManualBackButton) {
__android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?"); __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?");
} }
@ -2045,6 +2048,12 @@ SDL_bool SDL_IsDeXMode(void)
return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsDeXMode); return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsDeXMode);
} }
void SDL_AndroidBackButton(void)
{
JNIEnv *env = Android_JNI_GetEnv();
return (*env)->CallStaticVoidMethod(env, mActivityClass, midManualBackButton);
}
const char * SDL_AndroidGetInternalStoragePath(void) const char * SDL_AndroidGetInternalStoragePath(void)
{ {
static char *s_AndroidInternalFilesPath = NULL; static char *s_AndroidInternalFilesPath = NULL;

View File

@ -674,3 +674,4 @@
#define SDL_HasAVX512F SDL_HasAVX512F_REAL #define SDL_HasAVX512F SDL_HasAVX512F_REAL
#define SDL_IsChromebook SDL_IsChromebook_REAL #define SDL_IsChromebook SDL_IsChromebook_REAL
#define SDL_IsDeXMode SDL_IsDeXMode_REAL #define SDL_IsDeXMode SDL_IsDeXMode_REAL
#define SDL_AndroidBackButton SDL_AndroidBackButton_REAL

View File

@ -716,3 +716,6 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_HasAVX512F,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_IsChromebook,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_IsChromebook,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_IsDeXMode,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_IsDeXMode,(void),(),return)
#endif #endif
#ifdef __ANDROID__
SDL_DYNAPI_PROC(void,SDL_AndroidBackButton,(void),(),return)
#endif