Browse Source

Implement `love.window.getSafeArea` for Android

--HG--
branch : android-safearea
Miku AuahDark 6 years ago
parent
commit
4a08c0f7c1
3 changed files with 44 additions and 1 deletions
  1. 22 0
      src/common/android.cpp
  2. 6 0
      src/common/android.h
  3. 16 1
      src/modules/window/sdl/Window.cpp

+ 22 - 0
src/common/android.cpp

@@ -90,6 +90,28 @@ double getScreenScale()
 	return result;
 	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()
 const char *getSelectedGameFile()
 {
 {
 	static const char *path = NULL;
 	static const char *path = NULL;

+ 6 - 0
src/common/android.h

@@ -44,6 +44,12 @@ bool getImmersive();
  **/
  **/
 double getScreenScale();
 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.
  * Gets the selected love file in the device filesystem.
  **/
  **/

+ 16 - 1
src/modules/window/sdl/Window.cpp

@@ -845,9 +845,24 @@ void Window::getPosition(int &x, int &y, int &displayindex)
 
 
 Rect Window::getSafeArea() const
 Rect Window::getSafeArea() const
 {
 {
-#ifdef LOVE_IOS
+#if defined(LOVE_IOS)
 	if (window != nullptr)
 	if (window != nullptr)
 		return love::ios::getSafeArea(window);
 		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
 #endif
 
 
 	double dw, dh;
 	double dw, dh;