Use the modern OnBackInvokedCallback method to trap the back button on newer Android devices (#16052)

This commit is contained in:
Rachel Blackman
2026-07-27 15:43:23 -07:00
committed by GitHub
parent f4337eded2
commit 412a7c5db6
5 changed files with 74 additions and 2 deletions

View File

@@ -101,6 +101,7 @@ static jmethodID midManualBackButton;
static jmethodID midShowFileDialog;
#endif // !SDL_DIALOG_DISABLED
static jmethodID midGetPreferredLocales;
static jmethodID midSetBackButtonTrapEnabled;
#ifndef SDL_VIDEO_DISABLED
// Video/surface method signatures
@@ -681,6 +682,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
midShowFileDialog = (*env)->GetStaticMethodID(env, mActivityClass, "showFileDialog", "([Ljava/lang/String;ZILjava/lang/String;I)Z");
#endif // !SDL_DIALOG_DISABLED
midGetPreferredLocales = (*env)->GetStaticMethodID(env, mActivityClass, "getPreferredLocales", "()Ljava/lang/String;");
midSetBackButtonTrapEnabled = (*env)->GetStaticMethodID(env, mActivityClass, "setBackButtonTrapEnabled", "(Z)V");
if (!midGetContext ||
!midGetDeviceFormFactor ||
@@ -698,7 +700,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
#ifndef SDL_DIALOG_DISABLED
!midShowFileDialog ||
#endif
!midGetPreferredLocales) {
!midGetPreferredLocales ||
!midSetBackButtonTrapEnabled) {
__android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some core Java callbacks, do you have the latest version of SDLActivity.java?");
}
@@ -3714,4 +3717,14 @@ bool Android_JNI_ShowFileDialog(
}
#endif // !SDL_DIALOG_DISABLED
void Android_JNI_SetBackButtonTrapActive(bool enabled)
{
if (!midSetBackButtonTrapEnabled) {
return;
}
JNIEnv *env = Android_JNI_GetEnv();
(*env)->CallStaticVoidMethod(env, mActivityClass, midSetBackButtonTrapEnabled, enabled);
}
#endif // SDL_PLATFORM_ANDROID

View File

@@ -60,6 +60,7 @@ void Android_LockActivityMutex(void);
void Android_UnlockActivityMutex(void);
void Android_SetAllowRecreateActivity(bool enabled);
void Android_JNI_SetBackButtonTrapActive(bool enabled);
#ifndef SDL_VIDEO_DISABLED
#include <EGL/eglplatform.h>

View File

@@ -28,6 +28,7 @@
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_windowevents_c.h"
#include "../../SDL_hints_c.h"
#include "SDL_androidvideo.h"
#include "SDL_androidgl.h"
@@ -81,6 +82,16 @@ static void Android_DeleteDevice(SDL_VideoDevice *device)
SDL_free(device);
}
// Input is part of video for Android, so this goes here.
static void SDLCALL Android_Video_InternalHintCallback(
void *userdata,
const char *name,
const char *oldvalue,
const char *newvalue)
{
Android_JNI_SetBackButtonTrapActive(SDL_GetStringBoolean(newvalue, false));
}
static SDL_VideoDevice *Android_CreateDevice(void)
{
SDL_VideoDevice *device;
@@ -185,6 +196,8 @@ bool Android_VideoInit(SDL_VideoDevice *_this)
display->current_orientation = Android_JNI_GetDisplayCurrentOrientation();
display->content_scale = Android_ScreenDensity;
SDL_AddHintCallback(SDL_HINT_ANDROID_TRAP_BACK_BUTTON, Android_Video_InternalHintCallback, 0);
Android_InitTouch();
Android_InitMouse();
@@ -195,6 +208,7 @@ bool Android_VideoInit(SDL_VideoDevice *_this)
void Android_VideoQuit(SDL_VideoDevice *_this)
{
SDL_RemoveHintCallback(SDL_HINT_ANDROID_TRAP_BACK_BUTTON, Android_Video_InternalHintCallback, 0);
Android_QuitMouse();
Android_QuitTouch();
}