From f67b4bfa910f0d23970a8d6a7d0a9afa262e4706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 18 Jan 2024 12:03:49 +0100 Subject: [PATCH 1/3] Include rounded corner radius in android safe area implementation Android apparently has a separate API for "window cutouts", i.e. for cameras and the like, and a separate API for "rounded corners", i.e. devices where the rounded corners of the display will cause some areas of the theoretically-rectangular display to be obscured. Because there is no engineering like overengineering, right? Bonus points for them being usable at different API levels, too. Disclaimer that this does absolutely nothing on my one test device that has a rounded display and a high enough API level, but honestly it may be a device issue since it's not even returning `true` for `WindowInsets.IsRound`. Maybe it'll help someone, no idea. --- osu.Framework.Android/AndroidGameView.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/osu.Framework.Android/AndroidGameView.cs b/osu.Framework.Android/AndroidGameView.cs index 952cc4e4f2..0b48d5db5a 100644 --- a/osu.Framework.Android/AndroidGameView.cs +++ b/osu.Framework.Android/AndroidGameView.cs @@ -245,6 +245,22 @@ private void updateSafeArea() usableScreenArea = usableScreenArea.Shrink(cutout.SafeInsetLeft, cutout.SafeInsetRight, cutout.SafeInsetTop, cutout.SafeInsetBottom); } + if (OperatingSystem.IsAndroidVersionAtLeast(31) && RootWindowInsets != null) + { + var topLeftCorner = RootWindowInsets.GetRoundedCorner((int)RoundedCornerPosition.TopLeft); + var topRightCorner = RootWindowInsets.GetRoundedCorner((int)RoundedCornerPosition.TopRight); + var bottomLeftCorner = RootWindowInsets.GetRoundedCorner((int)RoundedCornerPosition.BottomLeft); + var bottomRightCorner = RootWindowInsets.GetRoundedCorner((int)RoundedCornerPosition.BottomRight); + + int cornerInsetLeft = Math.Max(topLeftCorner?.Radius ?? 0, bottomLeftCorner?.Radius ?? 0); + int cornerInsetRight = Math.Max(topRightCorner?.Radius ?? 0, bottomRightCorner?.Radius ?? 0); + int cornerInsetTop = Math.Max(topLeftCorner?.Radius ?? 0, topRightCorner?.Radius ?? 0); + int cornerInsetBottom = Math.Max(bottomLeftCorner?.Radius ?? 0, bottomRightCorner?.Radius ?? 0); + + var radiusInsetArea = screenArea.Shrink(cornerInsetLeft, cornerInsetRight, cornerInsetTop, cornerInsetBottom); + usableScreenArea = usableScreenArea.Intersect(radiusInsetArea); + } + if (OperatingSystem.IsAndroidVersionAtLeast(24) && Activity.IsInMultiWindowMode) { // if we are in multi-window mode, the status bar is always visible (even if we request to hide it) and could be obstructing our view. From 15c1444a7291ea232d2f4a39ad8d45c895f6a2b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 18 Jan 2024 13:02:02 +0100 Subject: [PATCH 2/3] remove todo --- osu.Framework.Android/AndroidGameView.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Framework.Android/AndroidGameView.cs b/osu.Framework.Android/AndroidGameView.cs index 0b48d5db5a..37d3119979 100644 --- a/osu.Framework.Android/AndroidGameView.cs +++ b/osu.Framework.Android/AndroidGameView.cs @@ -273,8 +273,6 @@ private void updateSafeArea() usableScreenArea = usableScreenArea.Intersect(screenArea.Shrink(0, 0, statusBarHeight, 0)); } - // TODO: add rounded corners support (Android 12): https://developer.android.com/guide/topics/ui/look-and-feel/rounded-corners - // compute the location/area of this view on the screen. int[] location = new int[2]; From 471d5e9a0fdf73927f66aa649d92b6f981563eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 18 Jan 2024 13:42:18 +0100 Subject: [PATCH 3/3] use even better bounds (hopefully) --- osu.Framework.Android/AndroidGameView.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Framework.Android/AndroidGameView.cs b/osu.Framework.Android/AndroidGameView.cs index 37d3119979..2f4582bc83 100644 --- a/osu.Framework.Android/AndroidGameView.cs +++ b/osu.Framework.Android/AndroidGameView.cs @@ -257,7 +257,10 @@ private void updateSafeArea() int cornerInsetTop = Math.Max(topLeftCorner?.Radius ?? 0, topRightCorner?.Radius ?? 0); int cornerInsetBottom = Math.Max(bottomLeftCorner?.Radius ?? 0, bottomRightCorner?.Radius ?? 0); - var radiusInsetArea = screenArea.Shrink(cornerInsetLeft, cornerInsetRight, cornerInsetTop, cornerInsetBottom); + var radiusInsetArea = screenArea.Width >= screenArea.Height + ? screenArea.Shrink(cornerInsetLeft, cornerInsetRight, 0, 0) + : screenArea.Shrink(0, 0, cornerInsetTop, cornerInsetBottom); + usableScreenArea = usableScreenArea.Intersect(radiusInsetArea); }