From 6bb16296b0bf7b5b004830d76f2e6f01b446a73f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 3 Apr 2025 10:35:50 -0700 Subject: [PATCH] Added special handling for SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY This hint needs to persist outside of the normal application flow, so use the environment to set the initial value, and then save the value set via SDL_SetHint() after that. Fixes https://github.com/libsdl-org/SDL/issues/12677 --- src/SDL_hints.c | 33 +++++++++++++++++++++++++++++++++ src/core/android/SDL_android.c | 18 +++++++++++++++++- src/core/android/SDL_android.h | 2 ++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/SDL_hints.c b/src/SDL_hints.c index 9c4ccd4bd9..a10598f0ff 100644 --- a/src/SDL_hints.c +++ b/src/SDL_hints.c @@ -22,6 +22,10 @@ #include "SDL_hints_c.h" +#ifdef SDL_PLATFORM_ANDROID +#include "core/android/SDL_android.h" +#endif + typedef struct SDL_HintWatch { SDL_HintCallback callback; @@ -147,6 +151,13 @@ bool SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPriori } } +#ifdef SDL_PLATFORM_ANDROID + if (SDL_strcmp(name, SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY) == 0) { + // Special handling for this hint, which needs to persist outside the normal application flow + Android_SetAllowRecreateActivity(SDL_GetStringBoolean(value, false)); + } +#endif // SDL_PLATFORM_ANDROID + SDL_UnlockProperties(hints); return result; @@ -185,6 +196,17 @@ bool SDL_ResetHint(const char *name) result = true; } +#ifdef SDL_PLATFORM_ANDROID + if (SDL_strcmp(name, SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY) == 0) { + // Special handling for this hint, which needs to persist outside the normal application flow + if (env) { + Android_SetAllowRecreateActivity(SDL_GetStringBoolean(env, false)); + } else { + Android_SetAllowRecreateActivity(false); + } + } +#endif // SDL_PLATFORM_ANDROID + SDL_UnlockProperties(hints); return result; @@ -210,6 +232,17 @@ static void SDLCALL ResetHintsCallback(void *userdata, SDL_PropertiesID hints, c SDL_free(hint->value); hint->value = NULL; hint->priority = SDL_HINT_DEFAULT; + +#ifdef SDL_PLATFORM_ANDROID + if (SDL_strcmp(name, SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY) == 0) { + // Special handling for this hint, which needs to persist outside the normal application flow + if (env) { + Android_SetAllowRecreateActivity(SDL_GetStringBoolean(env, false)); + } else { + Android_SetAllowRecreateActivity(false); + } + } +#endif // SDL_PLATFORM_ANDROID } void SDL_ResetHints(void) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 1fb6fbf65b..7b666c5f5a 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -751,6 +751,8 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv *env typedef int (*SDL_main_func)(int argc, char *argv[]); static int run_count = 0; +static bool allow_recreate_activity; +static bool allow_recreate_activity_set; JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeCheckSDLThreadCounter)( JNIEnv *env, jclass jcls) @@ -760,10 +762,16 @@ JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeCheckSDLThreadCounter)( return tmp; } +void Android_SetAllowRecreateActivity(bool enabled) +{ + allow_recreate_activity = enabled; + allow_recreate_activity_set = true; +} + JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(nativeAllowRecreateActivity)( JNIEnv *env, jclass jcls) { - return SDL_GetHintBoolean(SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY, false); + return allow_recreate_activity; } JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeInitMainThread)( @@ -1526,6 +1534,14 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)( // Note that we call setenv() directly to avoid affecting SDL environments setenv(utfname, utfvalue, 1); // This should NOT be SDL_setenv() + if (SDL_strcmp(utfname, SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY) == 0) { + // Special handling for this hint, which needs to persist outside the normal application flow + // Only set this the first time we run, in case it's been set by the application via SDL_SetHint() + if (!allow_recreate_activity_set) { + Android_SetAllowRecreateActivity(SDL_GetStringBoolean(utfvalue, false)); + } + } + (*env)->ReleaseStringUTFChars(env, name, utfname); (*env)->ReleaseStringUTFChars(env, value, utfvalue); } diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h index 3541c2a9cc..620639ca96 100644 --- a/src/core/android/SDL_android.h +++ b/src/core/android/SDL_android.h @@ -55,6 +55,8 @@ bool Android_WaitLifecycleEvent(SDL_AndroidLifecycleEvent *event, Sint64 timeout void Android_LockActivityMutex(void); void Android_UnlockActivityMutex(void); +void Android_SetAllowRecreateActivity(bool enabled); + // Interface from the SDL library into the Android Java activity extern void Android_JNI_SetActivityTitle(const char *title); extern void Android_JNI_SetWindowStyle(bool fullscreen);