Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement OS.get_window_safe_area() for Android #43140

Merged
merged 1 commit into from
Oct 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions platform/android/java/app/res/values/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,16 @@
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;
Expand Down Expand Up @@ -494,6 +498,28 @@ public int getScreenDPI() {
return (int)(metrics.density * 160f);
}

public int[] getWindowSafeArea() {
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);
Expand Down
14 changes: 14 additions & 0 deletions platform/android/java_godot_io_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
_get_window_safe_area = p_env->GetMethodID(cls, "getWindowSafeArea", "()[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");
Expand Down Expand Up @@ -121,6 +122,19 @@ int GodotIOJavaWrapper::get_screen_dpi() {
}
}

void GodotIOJavaWrapper::get_window_safe_area(int (&p_rect_xywh)[4]) {
if (_get_window_safe_area) {
JNIEnv *env = ThreadAndroid::get_env();
jintArray returnArray = (jintArray)env->CallObjectMethod(godot_io_instance, _get_window_safe_area);
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();
Expand Down
2 changes: 2 additions & 0 deletions platform/android/java_godot_io_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class GodotIOJavaWrapper {
jmethodID _get_locale = 0;
jmethodID _get_model = 0;
jmethodID _get_screen_DPI = 0;
jmethodID _get_window_safe_area = 0;
jmethodID _get_unique_id = 0;
jmethodID _show_keyboard = 0;
jmethodID _hide_keyboard = 0;
Expand All @@ -71,6 +72,7 @@ class GodotIOJavaWrapper {
String get_locale();
String get_model();
int get_screen_dpi();
void get_window_safe_area(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);
Expand Down
6 changes: 6 additions & 0 deletions platform/android/os_android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,12 @@ Size2 OS_Android::get_window_size() const {
return Vector2(default_videomode.width, default_videomode.height);
}

Rect2 OS_Android::get_window_safe_area() const {
int xywh[4];
godot_io_java->get_window_safe_area(xywh);
return Rect2(xywh[0], xywh[1], xywh[2], xywh[3]);
}

String OS_Android::get_name() const {

return "Android";
Expand Down
1 change: 1 addition & 0 deletions platform/android/os_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ class OS_Android : public OS_Unix {
virtual void set_keep_screen_on(bool p_enabled);

virtual Size2 get_window_size() const;
virtual Rect2 get_window_safe_area() const;

virtual String get_name() const;
virtual MainLoop *get_main_loop() const;
Expand Down