From bac4a1f22d60687caf15deeae66e5534e1888953 Mon Sep 17 00:00:00 2001 From: Ghabry Date: Sun, 23 Feb 2025 18:24:36 +0100 Subject: [PATCH] Android: Properly handle rotations ConfigurationChanged is not sent on all Android versions because of various bugs in the operating system. Instead SurfaceChanged is used which is consistent with what SDL does. Also Window events are not filtered anymore when in the background. This is required on Android, otherwise rotations are lost. --- .../player/player/EasyRpgPlayerActivity.java | 8 +++++- .../easyrpg/player/player/EasyRpgSurface.java | 26 +++++++++++++++++++ src/platform/sdl/sdl2_ui.cpp | 5 ++++ src/platform/sdl/sdl3_ui.cpp | 7 ++++- 4 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 builds/android/app/src/main/java/org/easyrpg/player/player/EasyRpgSurface.java diff --git a/builds/android/app/src/main/java/org/easyrpg/player/player/EasyRpgPlayerActivity.java b/builds/android/app/src/main/java/org/easyrpg/player/player/EasyRpgPlayerActivity.java index 8c32ed2e2c..b0e57ef796 100644 --- a/builds/android/app/src/main/java/org/easyrpg/player/player/EasyRpgPlayerActivity.java +++ b/builds/android/app/src/main/java/org/easyrpg/player/player/EasyRpgPlayerActivity.java @@ -26,6 +26,7 @@ import android.app.AlertDialog; import android.content.ClipDescription; +import android.content.Context; import android.content.Intent; import android.content.res.AssetManager; import android.content.res.Configuration; @@ -62,6 +63,7 @@ import org.easyrpg.player.game_browser.GameBrowserActivity; import org.easyrpg.player.settings.SettingsManager; import org.libsdl.app.SDLActivity; +import org.libsdl.app.SDLSurface; import java.io.File; import java.lang.reflect.Method; @@ -94,6 +96,11 @@ protected String[] getLibraries() { }; } + @Override + protected SDLSurface createSDLSurface(Context context) { + return new EasyRpgSurface(context, this); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -438,7 +445,6 @@ public void showInputLayout() { public void updateScreenPosition() { RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); - int topMargin, leftMargin; // Determine the multiplier int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); diff --git a/builds/android/app/src/main/java/org/easyrpg/player/player/EasyRpgSurface.java b/builds/android/app/src/main/java/org/easyrpg/player/player/EasyRpgSurface.java new file mode 100644 index 0000000000..f8c158a20d --- /dev/null +++ b/builds/android/app/src/main/java/org/easyrpg/player/player/EasyRpgSurface.java @@ -0,0 +1,26 @@ +package org.easyrpg.player.player; + +import android.content.Context; +import android.view.SurfaceHolder; + +import org.libsdl.app.SDLSurface; + +public class EasyRpgSurface extends SDLSurface { + private EasyRpgPlayerActivity activity = null; + + public EasyRpgSurface(Context context, EasyRpgPlayerActivity activity) { + super(context); + + this.activity = activity; + } + + @Override + public void surfaceChanged(SurfaceHolder holder, + int format, int width, int height) { + // configurationChanged is not always sent because of Android bugs in various versions + // SDL uses the surfaceChanged event to detect rotations instead + super.surfaceChanged(holder, format, width, height); + + activity.updateScreenPosition(); + } +} diff --git a/src/platform/sdl/sdl2_ui.cpp b/src/platform/sdl/sdl2_ui.cpp index 3b86cfc3b7..6af0764835 100644 --- a/src/platform/sdl/sdl2_ui.cpp +++ b/src/platform/sdl/sdl2_ui.cpp @@ -807,6 +807,11 @@ void Sdl2Ui::ProcessWindowEvent(SDL_Event &evnt) { SDL_Event wait_event; while (SDL_WaitEvent(&wait_event)) { + if (wait_event.type == SDL_WINDOWEVENT && wait_event.window.event != SDL_WINDOWEVENT_FOCUS_LOST) { + // Process size change etc. events + ProcessWindowEvent(wait_event); + } + if (FilterUntilFocus(&wait_event)) { break; } diff --git a/src/platform/sdl/sdl3_ui.cpp b/src/platform/sdl/sdl3_ui.cpp index 25f31c081c..3beb25758a 100644 --- a/src/platform/sdl/sdl3_ui.cpp +++ b/src/platform/sdl/sdl3_ui.cpp @@ -175,7 +175,7 @@ Sdl3Ui::~Sdl3Ui() { #ifdef SUPPORT_AUDIO audio_.reset(); -#endif +#endif SDL_Quit(); } @@ -732,6 +732,11 @@ void Sdl3Ui::ProcessWindowEvent(SDL_Event &evnt) { SDL_Event wait_event; while (SDL_WaitEvent(&wait_event)) { + if (wait_event.type >= SDL_EVENT_WINDOW_FIRST && wait_event.type <= SDL_EVENT_WINDOW_LAST && wait_event.type != SDL_EVENT_WINDOW_FOCUS_LOST) { + // Process size change etc. events + ProcessWindowEvent(wait_event); + } + if (FilterUntilFocus(&wait_event)) { break; }