Simple Directmedia Layer

Added support for inset handling on Android 15

Changed files
+48 -22
android-project
app
src
main
java
org
libsdl
docs
src
+2 -2
android-project/app/build.gradle
··· 6 6 7 7 android { 8 8 namespace "org.libsdl.app" 9 - compileSdkVersion 34 9 + compileSdkVersion 35 10 10 defaultConfig { 11 11 minSdkVersion 19 12 - targetSdkVersion 34 12 + targetSdkVersion 35 13 13 versionCode 1 14 14 versionName "1.0" 15 15 externalNativeBuild {
+4
android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
··· 928 928 if (Build.VERSION.SDK_INT >= 28 /* Android 9 (Pie) */) { 929 929 window.getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; 930 930 } 931 + if (Build.VERSION.SDK_INT >= 30 /* Android 11 (R) */ && 932 + Build.VERSION.SDK_INT < 35 /* Android 15 */) { 933 + SDLActivity.onNativeInsetsChanged(0, 0, 0, 0); 934 + } 931 935 } 932 936 } else { 933 937 Log.e(TAG, "error handling message, getContext() returned no Activity");
+18 -17
docs/README-android.md
··· 10 10 Requirements 11 11 ================================================================================ 12 12 13 - Android SDK (version 34 or later) 13 + Android SDK (version 35 or later) 14 14 https://developer.android.com/sdk/index.html 15 15 16 16 Android NDK r15c or later ··· 316 316 to choose whether to keep or re-initialize java and native static datas, see 317 317 SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY in SDL_hints.h. 318 318 319 + 320 + Insets and Safe Areas 321 + ================================================================================ 322 + 323 + As of Android 15, SDL windows cover the entire screen, extending under notches 324 + and system bars. The OS expects you to take those into account when displaying 325 + content and SDL provides the function SDL_GetWindowSafeArea() so you know what 326 + area is available for interaction. Outside of the safe area can be potentially 327 + covered by system bars or used by OS gestures. 328 + 329 + 319 330 Mouse / Touch events 320 331 ================================================================================ 321 332 ··· 324 335 To enable/disable this behavior, see SDL_hints.h: 325 336 - SDL_HINT_TOUCH_MOUSE_EVENTS 326 337 - SDL_HINT_MOUSE_TOUCH_EVENTS 338 + 327 339 328 340 Misc 329 341 ================================================================================ ··· 333 345 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); 334 346 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6); 335 347 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); 348 + 336 349 337 350 Threads and the Java VM 338 351 ================================================================================ ··· 358 371 359 372 see: 360 373 https://developer.android.com/training/articles/perf-jni#faq:-why-didnt-findclass-find-my-class 374 + 361 375 362 376 Using STL 363 377 ================================================================================ ··· 526 540 https://developer.nvidia.com/tegra-graphics-debugger 527 541 528 542 529 - Why is API level 19 the minimum required? 530 - ================================================================================ 531 - 532 - The latest NDK toolchain doesn't support targeting earlier than API level 19. 533 - As of this writing, according to https://www.composables.com/tools/distribution-chart 534 - about 99.7% of the Android devices accessing Google Play support API level 19 or 535 - higher (August 2023). 536 - 537 - 538 543 A note regarding the use of the "dirty rectangles" rendering technique 539 544 ================================================================================ 540 545 ··· 545 550 contexts, in particular the use of the eglSwapBuffers function. As stated in the 546 551 documentation for the function "The contents of ancillary buffers are always 547 552 undefined after calling eglSwapBuffers". 548 - Setting the EGL_SWAP_BEHAVIOR attribute of the surface to EGL_BUFFER_PRESERVED 549 - is not possible for SDL as it requires EGL 1.4, available only on the API level 550 - 17+, so the only workaround available on this platform is to redraw the entire 551 - screen each frame. 552 - 553 - Reference: http://www.khronos.org/registry/egl/specs/EGLTechNote0001.html 554 553 555 554 556 555 Ending your application ··· 570 569 NB: "Back button" can be handled as a SDL_EVENT_KEY_DOWN/UP events, with Keycode 571 570 SDLK_AC_BACK, for any purpose. 572 571 572 + 573 573 Known issues 574 574 ================================================================================ 575 575 576 576 - The number of buttons reported for each joystick is hardcoded to be 36, which 577 577 is the current maximum number of buttons Android can report. 578 + 578 579 579 580 Building the SDL tests 580 581 ================================================================================ ··· 651 652 cmake --build . --target build-install-start-testsprite 652 653 ``` 653 654 654 - Not all tests provide a GUI. For those, you can use `adb logcat` to read the output of stdout. 655 + Not all tests provide a GUI. For those, you can use `adb logcat` to read the output.
+1 -3
src/core/android/SDL_android.c
··· 1077 1077 { 1078 1078 SDL_LockMutex(Android_ActivityMutex); 1079 1079 1080 - if (Android_Window) { 1081 - SDL_SetWindowSafeAreaInsets(Android_Window, left, right, top, bottom); 1082 - } 1080 + Android_SetWindowSafeAreaInsets(left, right, top, bottom); 1083 1081 1084 1082 SDL_UnlockMutex(Android_ActivityMutex); 1085 1083 }
+16
src/video/android/SDL_androidvideo.c
··· 63 63 static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_RGB565; // Default SurfaceView format, in case this is queried before being filled 64 64 float Android_ScreenDensity = 1.0f; 65 65 static float Android_ScreenRate = 0.0f; 66 + int Android_SafeInsetLeft = 0; 67 + int Android_SafeInsetRight = 0; 68 + int Android_SafeInsetTop = 0; 69 + int Android_SafeInsetBottom = 0; 66 70 static SDL_SystemTheme Android_SystemTheme; 67 71 68 72 static bool Android_SuspendScreenSaver(SDL_VideoDevice *_this) ··· 268 272 269 273 if (window) { 270 274 SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, Android_SurfaceWidth, Android_SurfaceHeight); 275 + } 276 + } 277 + 278 + void Android_SetWindowSafeAreaInsets(int left, int right, int top, int bottom) 279 + { 280 + Android_SafeInsetLeft = left; 281 + Android_SafeInsetRight = right; 282 + Android_SafeInsetTop = top; 283 + Android_SafeInsetBottom = bottom; 284 + 285 + if (Android_Window) { 286 + SDL_SetWindowSafeAreaInsets(Android_Window, left, right, top, bottom); 271 287 } 272 288 } 273 289
+5
src/video/android/SDL_androidvideo.h
··· 29 29 extern void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float density, float rate); 30 30 extern void Android_SetFormat(int format_wanted, int format_got); 31 31 extern void Android_SendResize(SDL_Window *window); 32 + extern void Android_SetWindowSafeAreaInsets(int left, int right, int top, int bottom); 32 33 extern void Android_SetDarkMode(bool enabled); 33 34 34 35 // Private display data ··· 42 43 extern int Android_SurfaceWidth; 43 44 extern int Android_SurfaceHeight; 44 45 extern float Android_ScreenDensity; 46 + extern int Android_SafeInsetLeft; 47 + extern int Android_SafeInsetRight; 48 + extern int Android_SafeInsetTop; 49 + extern int Android_SafeInsetBottom; 45 50 46 51 #endif // SDL_androidvideo_h_
+2
src/video/android/SDL_androidwindow.c
··· 93 93 SDL_SetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_ANDROID_SURFACE_POINTER, data->egl_surface); 94 94 #endif 95 95 96 + SDL_SetWindowSafeAreaInsets(window, Android_SafeInsetLeft, Android_SafeInsetRight, Android_SafeInsetTop, Android_SafeInsetBottom); 97 + 96 98 window->internal = data; 97 99 Android_Window = window; 98 100