From 8704ab84228aca126c906ea42c2dbf4a240909bc Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 30 Dec 2024 15:49:10 -0800
Subject: [PATCH] Wait for a display resize event before sending orientation
changes
Fixes https://github.com/libsdl-org/SDL/issues/9585
---
src/core/android/SDL_android.c | 5 +----
src/video/android/SDL_androidvideo.c | 25 +++++++++++++++++++++++++
src/video/android/SDL_androidvideo.h | 1 +
3 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index 419d4c29f146d..c2f94dbd804b0 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -1063,10 +1063,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeRotationChanged)(
break;
}
- if (Android_Window) {
- SDL_VideoDisplay *display = SDL_GetVideoDisplay(SDL_GetPrimaryDisplay());
- SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_ORIENTATION, displayCurrentOrientation, 0);
- }
+ Android_SetOrientation(displayCurrentOrientation);
SDL_UnlockMutex(Android_ActivityMutex);
}
diff --git a/src/video/android/SDL_androidvideo.c b/src/video/android/SDL_androidvideo.c
index ab360a11c44aa..e2e5f3e9255c4 100644
--- a/src/video/android/SDL_androidvideo.c
+++ b/src/video/android/SDL_androidvideo.c
@@ -63,6 +63,7 @@ static int Android_DeviceHeight = 0;
static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_RGB565; // Default SurfaceView format, in case this is queried before being filled
float Android_ScreenDensity = 1.0f;
static float Android_ScreenRate = 0.0f;
+static SDL_DisplayOrientation Android_ScreenOrientation = SDL_ORIENTATION_UNKNOWN;
int Android_SafeInsetLeft = 0;
int Android_SafeInsetRight = 0;
int Android_SafeInsetTop = 0;
@@ -249,6 +250,29 @@ void Android_SetFormat(int format_wanted, int format_got)
SDL_GetPixelFormatName(pf_got), format_got);
}
+static void Android_SendOrientationUpdate(void)
+{
+ /* If we've received a compatible resize event, update the
+ * orientation immediately, otherwise wait for the display
+ * resize event.
+ */
+ SDL_VideoDevice *device = SDL_GetVideoDevice();
+ if (device && device->num_displays > 0) {
+ SDL_VideoDisplay *display = device->displays[0];
+ bool mode_landscape = (display->desktop_mode.w > display->desktop_mode.h);
+ bool sensor_landscape = (Android_ScreenOrientation == SDL_ORIENTATION_LANDSCAPE || Android_ScreenOrientation == SDL_ORIENTATION_LANDSCAPE_FLIPPED);
+ if (sensor_landscape == mode_landscape) {
+ SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_ORIENTATION, Android_ScreenOrientation, 0);
+ }
+ }
+}
+
+void Android_SetOrientation(SDL_DisplayOrientation orientation)
+{
+ Android_ScreenOrientation = orientation;
+ Android_SendOrientationUpdate();
+}
+
void Android_SendResize(SDL_Window *window)
{
/*
@@ -268,6 +292,7 @@ void Android_SendResize(SDL_Window *window)
desktop_mode.h = Android_DeviceHeight;
desktop_mode.refresh_rate = Android_ScreenRate;
SDL_SetDesktopDisplayMode(display, &desktop_mode);
+ Android_SendOrientationUpdate();
}
if (window) {
diff --git a/src/video/android/SDL_androidvideo.h b/src/video/android/SDL_androidvideo.h
index bcc234f5d0af8..cd67890c92e22 100644
--- a/src/video/android/SDL_androidvideo.h
+++ b/src/video/android/SDL_androidvideo.h
@@ -28,6 +28,7 @@
// Called by the JNI layer when the screen changes size or format
extern void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float density, float rate);
extern void Android_SetFormat(int format_wanted, int format_got);
+extern void Android_SetOrientation(SDL_DisplayOrientation orientation);
extern void Android_SendResize(SDL_Window *window);
extern void Android_SetWindowSafeAreaInsets(int left, int right, int top, int bottom);
extern void Android_SetDarkMode(bool enabled);