+2
-2
android-project/app/build.gradle
+2
-2
android-project/app/build.gradle
+4
android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
+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
+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
+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
+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
+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
+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