Skip to content

Commit

Permalink
Merge pull request godotengine#60553 from madmiraal/separate-display_…
Browse files Browse the repository at this point in the history
…safe_area
  • Loading branch information
akien-mga authored May 3, 2022
2 parents f75afaa + 97e87a2 commit 3894b08
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 40 deletions.
8 changes: 7 additions & 1 deletion doc/classes/DisplayServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,16 @@
<method name="get_display_cutouts" qualifiers="const">
<return type="Array" />
<description>
Returns an [Array] of [Rect2], each of which is the bounding rectangle for a display cutout or notch. These are non-functional areas on edge-to-edge screens used by cameras and sensors. Returns an empty array if the device does not have cutouts. See also [method screen_get_usable_rect].
Returns an [Array] of [Rect2], each of which is the bounding rectangle for a display cutout or notch. These are non-functional areas on edge-to-edge screens used by cameras and sensors. Returns an empty array if the device does not have cutouts. See also [method get_display_safe_area].
[b]Note:[/b] Currently only implemented on Android. Other platforms will return an empty array even if they do have display cutouts or notches.
</description>
</method>
<method name="get_display_safe_area" qualifiers="const">
<return type="Rect2i" />
<description>
Returns the unobscured area of the display where interactive controls should be rendered. See also [method get_display_cutouts].
</description>
</method>
<method name="get_name" qualifiers="const">
<return type="String" />
<description>
Expand Down
13 changes: 8 additions & 5 deletions platform/android/display_server_android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,12 @@ Array DisplayServerAndroid::get_display_cutouts() const {
return godot_io_java->get_display_cutouts();
}

Rect2i DisplayServerAndroid::get_display_safe_area() const {
GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
ERR_FAIL_NULL_V(godot_io_java, Rect2i());
return godot_io_java->get_display_safe_area();
}

void DisplayServerAndroid::screen_set_keep_on(bool p_enable) {
GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java();
ERR_FAIL_COND(!godot_java);
Expand Down Expand Up @@ -183,11 +189,8 @@ Size2i DisplayServerAndroid::screen_get_size(int p_screen) const {
}

Rect2i DisplayServerAndroid::screen_get_usable_rect(int p_screen) const {
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]);
Size2i display_size = OS_Android::get_singleton()->get_display_size();
return Rect2i(0, 0, display_size.width, display_size.height);
}

int DisplayServerAndroid::screen_get_dpi(int p_screen) const {
Expand Down
1 change: 1 addition & 0 deletions platform/android/display_server_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class DisplayServerAndroid : public DisplayServer {
virtual bool clipboard_has() const override;

virtual Array get_display_cutouts() const override;
virtual Rect2i get_display_safe_area() const override;

virtual void screen_set_keep_on(bool p_enable) override;
virtual bool screen_is_kept_on() const override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ public double getScreenRefreshRate(double fallback) {
return fallback;
}

public int[] screenGetUsableRect() {
public int[] getDisplaySafeArea() {
DisplayMetrics metrics = activity.getResources().getDisplayMetrics();
Display display = activity.getWindowManager().getDefaultDisplay();
Point size = new Point();
Expand Down
29 changes: 14 additions & 15 deletions platform/android/java_godot_io_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc
_get_cache_dir = p_env->GetMethodID(cls, "getCacheDir", "()Ljava/lang/String;");
_get_data_dir = p_env->GetMethodID(cls, "getDataDir", "()Ljava/lang/String;");
_get_display_cutouts = p_env->GetMethodID(cls, "getDisplayCutouts", "()[I"),
_get_display_safe_area = p_env->GetMethodID(cls, "getDisplaySafeArea", "()[I"),
_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_scaled_density = p_env->GetMethodID(cls, "getScaledDensity", "()F");
_get_screen_refresh_rate = p_env->GetMethodID(cls, "getScreenRefreshRate", "(D)D");
_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");
Expand Down Expand Up @@ -165,20 +165,6 @@ float GodotIOJavaWrapper::get_screen_refresh_rate(float fallback) {
return fallback;
}

void GodotIOJavaWrapper::screen_get_usable_rect(int (&p_rect_xywh)[4]) {
if (_screen_get_usable_rect) {
JNIEnv *env = get_jni_env();
ERR_FAIL_COND(env == nullptr);
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);
}
}

Array GodotIOJavaWrapper::get_display_cutouts() {
Array result;
ERR_FAIL_NULL_V(_get_display_cutouts, result);
Expand All @@ -200,6 +186,19 @@ Array GodotIOJavaWrapper::get_display_cutouts() {
return result;
}

Rect2i GodotIOJavaWrapper::get_display_safe_area() {
Rect2i result;
ERR_FAIL_NULL_V(_get_display_safe_area, result);
JNIEnv *env = get_jni_env();
ERR_FAIL_NULL_V(env, result);
jintArray returnArray = (jintArray)env->CallObjectMethod(godot_io_instance, _get_display_safe_area);
ERR_FAIL_COND_V(env->GetArrayLength(returnArray) != 4, result);
jint *arrayBody = env->GetIntArrayElements(returnArray, JNI_FALSE);
result = Rect2i(arrayBody[0], arrayBody[1], arrayBody[2], arrayBody[3]);
env->ReleaseIntArrayElements(returnArray, arrayBody, 0);
return result;
}

String GodotIOJavaWrapper::get_unique_id() {
if (_get_unique_id) {
JNIEnv *env = get_jni_env();
Expand Down
5 changes: 3 additions & 2 deletions platform/android/java_godot_io_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <android/log.h>
#include <jni.h>

#include "core/math/rect2i.h"
#include "core/variant/array.h"
#include "string_android.h"

Expand All @@ -50,12 +51,12 @@ class GodotIOJavaWrapper {
jmethodID _get_cache_dir = 0;
jmethodID _get_data_dir = 0;
jmethodID _get_display_cutouts = 0;
jmethodID _get_display_safe_area = 0;
jmethodID _get_locale = 0;
jmethodID _get_model = 0;
jmethodID _get_screen_DPI = 0;
jmethodID _get_scaled_density = 0;
jmethodID _get_screen_refresh_rate = 0;
jmethodID _screen_get_usable_rect = 0;
jmethodID _get_unique_id = 0;
jmethodID _show_keyboard = 0;
jmethodID _hide_keyboard = 0;
Expand All @@ -77,8 +78,8 @@ class GodotIOJavaWrapper {
int get_screen_dpi();
float get_scaled_density();
float get_screen_refresh_rate(float fallback);
void screen_get_usable_rect(int (&p_rect_xywh)[4]);
Array get_display_cutouts();
Rect2i get_display_safe_area();
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
2 changes: 2 additions & 0 deletions platform/iphone/display_server_iphone.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ class DisplayServerIPhone : public DisplayServer {
virtual void tts_resume() override;
virtual void tts_stop() override;

virtual Rect2i get_display_safe_area() const override;

virtual int get_screen_count() const override;
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
Expand Down
33 changes: 17 additions & 16 deletions platform/iphone/display_server_iphone.mm
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,22 @@
[tts stopSpeaking];
}

Rect2i DisplayServerIPhone::get_display_safe_area() const {
if (@available(iOS 11, *)) {
UIEdgeInsets insets = UIEdgeInsetsZero;
UIView *view = AppDelegate.viewController.godotView;
if ([view respondsToSelector:@selector(safeAreaInsets)]) {
insets = [view safeAreaInsets];
}
float scale = screen_get_scale();
Size2i insets_position = Size2i(insets.left, insets.top) * scale;
Size2i insets_size = Size2i(insets.left + insets.right, insets.top + insets.bottom) * scale;
return Rect2i(screen_get_position() + insets_position, screen_get_size() - insets_size);
} else {
return Rect2i(screen_get_position(), screen_get_size());
}
}

int DisplayServerIPhone::get_screen_count() const {
return 1;
}
Expand All @@ -379,22 +395,7 @@
}

Rect2i DisplayServerIPhone::screen_get_usable_rect(int p_screen) const {
if (@available(iOS 11, *)) {
UIEdgeInsets insets = UIEdgeInsetsZero;
UIView *view = AppDelegate.viewController.godotView;

if ([view respondsToSelector:@selector(safeAreaInsets)]) {
insets = [view safeAreaInsets];
}

float scale = screen_get_scale(p_screen);
Size2i insets_position = Size2i(insets.left, insets.top) * scale;
Size2i insets_size = Size2i(insets.left + insets.right, insets.top + insets.bottom) * scale;

return Rect2i(screen_get_position(p_screen) + insets_position, screen_get_size(p_screen) - insets_size);
} else {
return Rect2i(screen_get_position(p_screen), screen_get_size(p_screen));
}
return Rect2i(screen_get_position(p_screen), screen_get_size(p_screen));
}

int DisplayServerIPhone::screen_get_dpi(int p_screen) const {
Expand Down
1 change: 1 addition & 0 deletions servers/display_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("clipboard_get_primary"), &DisplayServer::clipboard_get_primary);

ClassDB::bind_method(D_METHOD("get_display_cutouts"), &DisplayServer::get_display_cutouts);
ClassDB::bind_method(D_METHOD("get_display_safe_area"), &DisplayServer::get_display_safe_area);

ClassDB::bind_method(D_METHOD("get_screen_count"), &DisplayServer::get_screen_count);
ClassDB::bind_method(D_METHOD("screen_get_position", "screen"), &DisplayServer::screen_get_position, DEFVAL(SCREEN_OF_MAIN_WINDOW));
Expand Down
1 change: 1 addition & 0 deletions servers/display_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ class DisplayServer : public Object {
virtual String clipboard_get_primary() const;

virtual Array get_display_cutouts() const { return Array(); }
virtual Rect2i get_display_safe_area() const { return screen_get_usable_rect(); }

enum {
SCREEN_OF_MAIN_WINDOW = -1
Expand Down

0 comments on commit 3894b08

Please sign in to comment.