diff --git a/src/Uno.UI/Extensions/InsetsExtensions.Android.cs b/src/Uno.UI/Extensions/InsetsExtensions.Android.cs new file mode 100644 index 000000000000..ee79c8a16e5c --- /dev/null +++ b/src/Uno.UI/Extensions/InsetsExtensions.Android.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Windows.UI.Xaml; + +namespace Uno.UI.Extensions +{ + internal static class InsetsExtensions + { + public static Thickness ToThickness(this Android.Graphics.Insets insets) + => new Thickness(insets.Left, insets.Top, insets.Right, insets.Bottom); + } +} diff --git a/src/Uno.UI/Extensions/ThicknessExtensions.cs b/src/Uno.UI/Extensions/ThicknessExtensions.cs index 51e0078ea7f9..2e2cbf731cb5 100644 --- a/src/Uno.UI/Extensions/ThicknessExtensions.cs +++ b/src/Uno.UI/Extensions/ThicknessExtensions.cs @@ -12,6 +12,10 @@ internal static class ThicknessExtensions /// /// Is this uniform (all sides are equal)? /// - public static bool IsUniform(this Thickness thickness) => thickness.Left == thickness.Top && thickness.Left == thickness.Right && thickness.Left == thickness.Bottom; + public static bool IsUniform(this Thickness thickness) + => thickness.Left == thickness.Top && thickness.Left == thickness.Right && thickness.Left == thickness.Bottom; + + public static Thickness Minus(this Thickness x, Thickness y) // Minus ==> There is a (not implemented) Substract on struct in mono! + => new Thickness(x.Left - y.Left, x.Top - y.Top, x.Right - y.Right, x.Bottom - y.Bottom); } } diff --git a/src/Uno.UI/UI/Xaml/Window.Android.cs b/src/Uno.UI/UI/Xaml/Window.Android.cs index 3025dbeb3fe0..d58ef6dd9aeb 100644 --- a/src/Uno.UI/UI/Xaml/Window.Android.cs +++ b/src/Uno.UI/UI/Xaml/Window.Android.cs @@ -15,6 +15,8 @@ using Windows.UI.ViewManagement; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; +using Uno.Extensions.ValueType; +using Uno.UI.Extensions; namespace Windows.UI.Xaml { @@ -76,6 +78,34 @@ private static Window InternalGetCurrentWindow() internal void RaiseNativeSizeChanged() { +#if __ANDROID_30__ + var metrics = (ContextHelper.Current as Activity)?.WindowManager?.CurrentWindowMetrics; + + var insetsTypes = WindowInsets.Type.SystemBars(); // == WindowInsets.Type.StatusBars() | WindowInsets.Type.NavigationBars() | WindowInsets.Type.CaptionBar(); + var solidInsetsTypes = insetsTypes; + if (IsStatusBarTranslucent()) + { + solidInsetsTypes &= ~WindowInsets.Type.StatusBars(); + } + if (IsNavigationBarTranslucent()) + { + solidInsetsTypes &= ~WindowInsets.Type.NavigationBars(); + } + + var insets = metrics.WindowInsets.GetInsets(insetsTypes).ToThickness(); + var solidInsets = metrics.WindowInsets.GetInsets(solidInsetsTypes).ToThickness(); + + // The 'metric.Bounds' does not include any insets, so we remove the "solid" insets under which we cannot draw anything + var windowBounds = new Rect(default, ((Rect)metrics.Bounds).DeflateBy(solidInsets).Size).PhysicalToLogicalPixels(); + var newBounds = windowBounds; + + // The visible bounds is the windows bounds on which we remove also + // [translucent only inset](all_insets - solid_insets_that_has_already_been_removed_from_all_insets) + var visibleBounds = windowBounds.DeflateBy(insets.Minus(solidInsets)).PhysicalToLogicalPixels(); + + // The true visible bounds ... is unknown for now! + var trueVisibleBounds = visibleBounds; +#else using var display = (ContextHelper.Current as Activity)?.WindowManager?.DefaultDisplay; using var fullScreenMetrics = new DisplayMetrics(); @@ -140,6 +170,8 @@ Rect CalculateVisibleBounds(double excludedStatusBarHeight) var visibleBounds = CalculateVisibleBounds(statusBarSizeExcluded); var trueVisibleBounds = CalculateVisibleBounds(statusBarSize); +#endif + ApplicationView.GetForCurrentView()?.SetVisibleBounds(visibleBounds); ApplicationView.GetForCurrentView()?.SetTrueVisibleBounds(trueVisibleBounds); @@ -198,6 +230,7 @@ internal void UpdateInsetsWithVisibilities() Insets = newInsets; } +#if !__ANDROID_30__ private double GetLogicalStatusBarSize() { var logicalStatusBarHeight = 0d; @@ -228,6 +261,7 @@ private double GetLogicalNavigationBarSizeExcluded() ? ViewHelper.PhysicalToLogicalPixels(navigationBarSize) : 0; } +#endif internal void DisplayFullscreen(UIElement element) { @@ -268,7 +302,7 @@ public bool IsStatusBarTranslucent() } return activity.Window.Attributes.Flags.HasFlag(WindowManagerFlags.TranslucentStatus) - || activity.Window.Attributes.Flags.HasFlag(WindowManagerFlags.LayoutNoLimits); ; + || activity.Window.Attributes.Flags.HasFlag(WindowManagerFlags.LayoutNoLimits); } #endregion