From 6bb16296b0bf7b5b004830d76f2e6f01b446a73f Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
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 9c4ccd4bd94dc..a10598f0ffe69 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 1fb6fbf65b0a5..7b666c5f5a22d 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 3541c2a9ccc92..620639ca961e5 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);