diff --git a/src/common/android.cpp b/src/common/android.cpp index 140162fe6..19e8486f2 100644 --- a/src/common/android.cpp +++ b/src/common/android.cpp @@ -90,6 +90,28 @@ double getScreenScale() return result; } +bool getSafeArea(int &top, int &left, int &bottom, int &right) +{ + JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv(); + jobject activity = (jobject) SDL_AndroidGetActivity(); + jclass clazz(env->GetObjectClass(activity)); + jmethodID methodID = env->GetMethodID(clazz, "initializeSafeArea", "()Z"); + bool hasSafeArea = false; + + if ((hasSafeArea = env->CallBooleanMethod(activity, methodID))) + { + top = env->GetIntField(activity, env->GetFieldID(clazz, "safeAreaTop", "I")); + left = env->GetIntField(activity, env->GetFieldID(clazz, "safeAreaLeft", "I")); + bottom = env->GetIntField(activity, env->GetFieldID(clazz, "safeAreaBottom", "I")); + right = env->GetIntField(activity, env->GetFieldID(clazz, "safeAreaRight", "I")); + } + + env->DeleteLocalRef(clazz); + env->DeleteLocalRef(activity); + + return hasSafeArea; +} + const char *getSelectedGameFile() { static const char *path = NULL; diff --git a/src/common/android.h b/src/common/android.h index bf9c43f65..a19e923fe 100644 --- a/src/common/android.h +++ b/src/common/android.h @@ -44,6 +44,12 @@ bool getImmersive(); **/ double getScreenScale(); +/** + * Gets the window safe area, e.g. phone with notch display. + * Returns false if safe area is not set. + **/ +bool getSafeArea(int &top, int &left, int &bottom, int &right); + /** * Gets the selected love file in the device filesystem. **/ diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 182f695d5..2ccd76425 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -845,9 +845,24 @@ void Window::getPosition(int &x, int &y, int &displayindex) Rect Window::getSafeArea() const { -#ifdef LOVE_IOS +#if defined(LOVE_IOS) if (window != nullptr) return love::ios::getSafeArea(window); +#elif defined(LOVE_ANDROID) + if (window != nullptr) + { + int top, left, bottom, right; + + if (love::android::getSafeArea(top, left, bottom, right)) + { + // DisplayCutout API returns safe area in pixels + // and is affected by display orientation. + double safeLeft, safeTop, safeWidth, safeHeight; + fromPixels(left, top, safeLeft, safeTop); + fromPixels(pixelWidth - left - right, pixelHeight - top - bottom, safeWidth, safeHeight); + return {(int) safeLeft, (int) safeTop, (int) safeWidth, (int) safeHeight}; + } + } #endif double dw, dh;