Added support for inset handling on Android 15

This commit is contained in:
Sam Lantinga
2024-12-30 12:23:00 -08:00
parent f3cbd04a81
commit e91c37f4dd
7 changed files with 48 additions and 22 deletions

View File

@@ -6,10 +6,10 @@ def buildWithCMake = project.hasProperty('BUILD_WITH_CMAKE');
android {
namespace "org.libsdl.app"
compileSdkVersion 34
compileSdkVersion 35
defaultConfig {
minSdkVersion 19
targetSdkVersion 34
targetSdkVersion 35
versionCode 1
versionName "1.0"
externalNativeBuild {

View File

@@ -928,6 +928,10 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
if (Build.VERSION.SDK_INT >= 28 /* Android 9 (Pie) */) {
window.getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
}
if (Build.VERSION.SDK_INT >= 30 /* Android 11 (R) */ &&
Build.VERSION.SDK_INT < 35 /* Android 15 */) {
SDLActivity.onNativeInsetsChanged(0, 0, 0, 0);
}
}
} else {
Log.e(TAG, "error handling message, getContext() returned no Activity");

View File

@@ -10,7 +10,7 @@ The rest of this README covers the Android gradle style build process.
Requirements
================================================================================
Android SDK (version 34 or later)
Android SDK (version 35 or later)
https://developer.android.com/sdk/index.html
Android NDK r15c or later
@@ -316,6 +316,17 @@ You can control activity re-creation (eg. onCreate()) behaviour. This allows you
to choose whether to keep or re-initialize java and native static datas, see
SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY in SDL_hints.h.
Insets and Safe Areas
================================================================================
As of Android 15, SDL windows cover the entire screen, extending under notches
and system bars. The OS expects you to take those into account when displaying
content and SDL provides the function SDL_GetWindowSafeArea() so you know what
area is available for interaction. Outside of the safe area can be potentially
covered by system bars or used by OS gestures.
Mouse / Touch events
================================================================================
@@ -325,6 +336,7 @@ To enable/disable this behavior, see SDL_hints.h:
- SDL_HINT_TOUCH_MOUSE_EVENTS
- SDL_HINT_MOUSE_TOUCH_EVENTS
Misc
================================================================================
@@ -334,6 +346,7 @@ before creating a window:
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
Threads and the Java VM
================================================================================
@@ -359,6 +372,7 @@ in your native thread.
see:
https://developer.android.com/training/articles/perf-jni#faq:-why-didnt-findclass-find-my-class
Using STL
================================================================================
@@ -526,15 +540,6 @@ The Tegra Graphics Debugger is available from NVidia here:
https://developer.nvidia.com/tegra-graphics-debugger
Why is API level 19 the minimum required?
================================================================================
The latest NDK toolchain doesn't support targeting earlier than API level 19.
As of this writing, according to https://www.composables.com/tools/distribution-chart
about 99.7% of the Android devices accessing Google Play support API level 19 or
higher (August 2023).
A note regarding the use of the "dirty rectangles" rendering technique
================================================================================
@@ -545,12 +550,6 @@ This is caused by SDL's use of EGL as the support system to handle OpenGL ES/ES2
contexts, in particular the use of the eglSwapBuffers function. As stated in the
documentation for the function "The contents of ancillary buffers are always
undefined after calling eglSwapBuffers".
Setting the EGL_SWAP_BEHAVIOR attribute of the surface to EGL_BUFFER_PRESERVED
is not possible for SDL as it requires EGL 1.4, available only on the API level
17+, so the only workaround available on this platform is to redraw the entire
screen each frame.
Reference: http://www.khronos.org/registry/egl/specs/EGLTechNote0001.html
Ending your application
@@ -570,12 +569,14 @@ Don't call exit() as it stops the activity badly.
NB: "Back button" can be handled as a SDL_EVENT_KEY_DOWN/UP events, with Keycode
SDLK_AC_BACK, for any purpose.
Known issues
================================================================================
- The number of buttons reported for each joystick is hardcoded to be 36, which
is the current maximum number of buttons Android can report.
Building the SDL tests
================================================================================
@@ -651,4 +652,4 @@ There is also a convenience target which will build, install and start a test:
cmake --build . --target build-install-start-testsprite
```
Not all tests provide a GUI. For those, you can use `adb logcat` to read the output of stdout.
Not all tests provide a GUI. For those, you can use `adb logcat` to read the output.

View File

@@ -1077,9 +1077,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeInsetsChanged)(
{
SDL_LockMutex(Android_ActivityMutex);
if (Android_Window) {
SDL_SetWindowSafeAreaInsets(Android_Window, left, right, top, bottom);
}
Android_SetWindowSafeAreaInsets(left, right, top, bottom);
SDL_UnlockMutex(Android_ActivityMutex);
}

View File

@@ -63,6 +63,10 @@ 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;
int Android_SafeInsetLeft = 0;
int Android_SafeInsetRight = 0;
int Android_SafeInsetTop = 0;
int Android_SafeInsetBottom = 0;
static SDL_SystemTheme Android_SystemTheme;
static bool Android_SuspendScreenSaver(SDL_VideoDevice *_this)
@@ -271,6 +275,18 @@ void Android_SendResize(SDL_Window *window)
}
}
void Android_SetWindowSafeAreaInsets(int left, int right, int top, int bottom)
{
Android_SafeInsetLeft = left;
Android_SafeInsetRight = right;
Android_SafeInsetTop = top;
Android_SafeInsetBottom = bottom;
if (Android_Window) {
SDL_SetWindowSafeAreaInsets(Android_Window, left, right, top, bottom);
}
}
void Android_SetDarkMode(bool enabled)
{
SDL_VideoDevice *device = SDL_GetVideoDevice();

View File

@@ -29,6 +29,7 @@
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_SendResize(SDL_Window *window);
extern void Android_SetWindowSafeAreaInsets(int left, int right, int top, int bottom);
extern void Android_SetDarkMode(bool enabled);
// Private display data
@@ -42,5 +43,9 @@ struct SDL_VideoData
extern int Android_SurfaceWidth;
extern int Android_SurfaceHeight;
extern float Android_ScreenDensity;
extern int Android_SafeInsetLeft;
extern int Android_SafeInsetRight;
extern int Android_SafeInsetTop;
extern int Android_SafeInsetBottom;
#endif // SDL_androidvideo_h_

View File

@@ -93,6 +93,8 @@ bool Android_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Proper
SDL_SetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_ANDROID_SURFACE_POINTER, data->egl_surface);
#endif
SDL_SetWindowSafeAreaInsets(window, Android_SafeInsetLeft, Android_SafeInsetRight, Android_SafeInsetTop, Android_SafeInsetBottom);
window->internal = data;
Android_Window = window;