Pārlūkot izejas kodu

Implement OS.get_window_safe_area() for Android

Mark Riedesel 4 gadi atpakaļ
vecāks
revīzija
96e22bd9fb

+ 5 - 2
platform/android/display_server_android.cpp

@@ -137,8 +137,11 @@ Size2i DisplayServerAndroid::screen_get_size(int p_screen) const {
 }
 
 Rect2i DisplayServerAndroid::screen_get_usable_rect(int p_screen) const {
-	Size2i display_size = OS_Android::get_singleton()->get_display_size();
-	return Rect2i(0, 0, display_size.width, display_size.height);
+	GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
+	ERR_FAIL_COND_V(!godot_io_java, Rect2i());
+	int xywh[4];
+	godot_io_java->screen_get_usable_rect(xywh);
+	return Rect2i(xywh[0], xywh[1], xywh[2], xywh[3]);
 }
 
 int DisplayServerAndroid::screen_get_dpi(int p_screen) const {

+ 1 - 0
platform/android/java/app/res/values/themes.xml

@@ -5,5 +5,6 @@
 
 	<style name="GodotAppSplashTheme" parent="@style/GodotAppMainTheme">
 		<item name="android:windowBackground">@drawable/splash_drawable</item>
+		<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
 	</style>
 </resources>

+ 26 - 0
platform/android/java/lib/src/org/godotengine/godot/GodotIO.java

@@ -37,12 +37,16 @@ import android.content.*;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.res.AssetManager;
+import android.graphics.Point;
 import android.media.*;
 import android.net.Uri;
 import android.os.*;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.SparseArray;
+import android.view.Display;
+import android.view.DisplayCutout;
+import android.view.WindowInsets;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -461,6 +465,28 @@ public class GodotIO {
 		return (int)(metrics.density * 160f);
 	}
 
+	public int[] screenGetUsableRect() {
+		DisplayMetrics metrics = activity.getResources().getDisplayMetrics();
+		Display display = activity.getWindowManager().getDefaultDisplay();
+		Point size = new Point();
+		display.getRealSize(size);
+
+		int result[] = { 0, 0, size.x, size.y };
+		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+			WindowInsets insets = activity.getWindow().getDecorView().getRootWindowInsets();
+			DisplayCutout cutout = insets.getDisplayCutout();
+			if (cutout != null) {
+				int insetLeft = cutout.getSafeInsetLeft();
+				int insetTop = cutout.getSafeInsetTop();
+				result[0] = insetLeft;
+				result[1] = insetTop;
+				result[2] -= insetLeft + cutout.getSafeInsetRight();
+				result[3] -= insetTop + cutout.getSafeInsetBottom();
+			}
+		}
+		return result;
+	}
+
 	public void showKeyboard(String p_existing_text, boolean p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
 		if (edit != null)
 			edit.showKeyboard(p_existing_text, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end);

+ 14 - 0
platform/android/java_godot_io_wrapper.cpp

@@ -52,6 +52,7 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc
 		_get_locale = p_env->GetMethodID(cls, "getLocale", "()Ljava/lang/String;");
 		_get_model = p_env->GetMethodID(cls, "getModel", "()Ljava/lang/String;");
 		_get_screen_DPI = p_env->GetMethodID(cls, "getScreenDPI", "()I");
+		_screen_get_usable_rect = p_env->GetMethodID(cls, "screenGetUsableRect", "()[I"),
 		_get_unique_id = p_env->GetMethodID(cls, "getUniqueID", "()Ljava/lang/String;");
 		_show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;ZIII)V");
 		_hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V");
@@ -118,6 +119,19 @@ int GodotIOJavaWrapper::get_screen_dpi() {
 	}
 }
 
+void GodotIOJavaWrapper::screen_get_usable_rect(int (&p_rect_xywh)[4]) {
+	if (_screen_get_usable_rect) {
+		JNIEnv *env = ThreadAndroid::get_env();
+		jintArray returnArray = (jintArray)env->CallObjectMethod(godot_io_instance, _screen_get_usable_rect);
+		ERR_FAIL_COND(env->GetArrayLength(returnArray) != 4);
+		jint *arrayBody = env->GetIntArrayElements(returnArray, JNI_FALSE);
+		for (int i = 0; i < 4; i++) {
+			p_rect_xywh[i] = arrayBody[i];
+		}
+		env->ReleaseIntArrayElements(returnArray, arrayBody, 0);
+	}
+}
+
 String GodotIOJavaWrapper::get_unique_id() {
 	if (_get_unique_id) {
 		JNIEnv *env = ThreadAndroid::get_env();

+ 2 - 0
platform/android/java_godot_io_wrapper.h

@@ -50,6 +50,7 @@ private:
 	jmethodID _get_locale = 0;
 	jmethodID _get_model = 0;
 	jmethodID _get_screen_DPI = 0;
+	jmethodID _screen_get_usable_rect = 0;
 	jmethodID _get_unique_id = 0;
 	jmethodID _show_keyboard = 0;
 	jmethodID _hide_keyboard = 0;
@@ -68,6 +69,7 @@ public:
 	String get_locale();
 	String get_model();
 	int get_screen_dpi();
+	void screen_get_usable_rect(int (&p_rect_xywh)[4]);
 	String get_unique_id();
 	bool has_vk();
 	void show_vk(const String &p_existing, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end);