Fix insets on android 15 (#18844)
* fix insets on android 15 * add api diff * fix nit
This commit is contained in:
@@ -109,6 +109,18 @@
|
||||
<Left>baseline/netstandard2.0/Avalonia.Controls.dll</Left>
|
||||
<Right>target/netstandard2.0/Avalonia.Controls.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0006</DiagnosticId>
|
||||
<Target>P:Avalonia.Controls.Platform.IInsetsManager.DisplayEdgeToEdgePreference</Target>
|
||||
<Left>baseline/netstandard2.0/Avalonia.Controls.dll</Left>
|
||||
<Right>target/netstandard2.0/Avalonia.Controls.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0006</DiagnosticId>
|
||||
<Target>P:Avalonia.Controls.Platform.IInsetsManager.DisplaysEdgeToEdge</Target>
|
||||
<Left>baseline/netstandard2.0/Avalonia.Controls.dll</Left>
|
||||
<Right>target/netstandard2.0/Avalonia.Controls.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0009</DiagnosticId>
|
||||
<Target>T:Avalonia.Diagnostics.StyleDiagnostics</Target>
|
||||
|
||||
@@ -108,14 +108,14 @@ namespace ControlCatalog
|
||||
ViewModel.SafeAreaPadding = insets.SafeAreaPadding;
|
||||
};
|
||||
|
||||
ViewModel.DisplayEdgeToEdge = insets.DisplayEdgeToEdge;
|
||||
ViewModel.DisplayEdgeToEdge = insets.DisplayEdgeToEdgePreference;
|
||||
ViewModel.IsSystemBarVisible = insets.IsSystemBarVisible ?? true;
|
||||
|
||||
ViewModel.PropertyChanged += async (sender, args) =>
|
||||
{
|
||||
if (args.PropertyName == nameof(ViewModel.DisplayEdgeToEdge))
|
||||
{
|
||||
insets.DisplayEdgeToEdge = ViewModel.DisplayEdgeToEdge;
|
||||
insets.DisplayEdgeToEdgePreference = ViewModel.DisplayEdgeToEdge;
|
||||
}
|
||||
else if (args.PropertyName == nameof(ViewModel.IsSystemBarVisible))
|
||||
{
|
||||
@@ -124,7 +124,7 @@ namespace ControlCatalog
|
||||
|
||||
// Give the OS some time to apply new values and refresh the view model.
|
||||
await Task.Delay(100);
|
||||
ViewModel.DisplayEdgeToEdge = insets.DisplayEdgeToEdge;
|
||||
ViewModel.DisplayEdgeToEdge = insets.DisplayEdgeToEdgePreference;
|
||||
ViewModel.IsSystemBarVisible = insets.IsSystemBarVisible ?? true;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace SafeAreaDemo.ViewModels
|
||||
|
||||
if (_insetsManager != null)
|
||||
{
|
||||
_insetsManager.DisplayEdgeToEdge = value;
|
||||
_insetsManager.DisplayEdgeToEdgePreference = value;
|
||||
}
|
||||
|
||||
this.RaisePropertyChanged();
|
||||
@@ -129,7 +129,7 @@ namespace SafeAreaDemo.ViewModels
|
||||
{
|
||||
_insetsManager.SafeAreaChanged += InsetsManager_SafeAreaChanged;
|
||||
|
||||
_displayEdgeToEdge = _insetsManager.DisplayEdgeToEdge;
|
||||
_displayEdgeToEdge = _insetsManager.DisplayEdgeToEdgePreference;
|
||||
_hideSystemBars = !(_insetsManager.IsSystemBarVisible ?? false);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,12 @@ namespace Avalonia.Android.Platform
|
||||
{
|
||||
internal sealed class AndroidInsetsManager : WindowInsetsAnimationCompat.Callback, IInsetsManager, IOnApplyWindowInsetsListener, ViewTreeObserver.IOnGlobalLayoutListener, IInputPane
|
||||
{
|
||||
// For now, we check if running under net 9. TODO: remove runtime check when we target net 10
|
||||
private static bool IsDisplayEdgeToEdgeForced = System.Environment.Version.Major >=9 && Build.VERSION.SdkInt >= (BuildVersionCodes)35;
|
||||
|
||||
private readonly Activity _activity;
|
||||
private readonly TopLevelImpl _topLevel;
|
||||
private bool _displayEdgeToEdge;
|
||||
private bool _displaysEdgeToEdge;
|
||||
private bool? _systemUiVisibility;
|
||||
private SystemBarTheme? _statusBarTheme;
|
||||
private bool? _isDefaultSystemBarLightTheme;
|
||||
@@ -27,6 +30,7 @@ namespace Avalonia.Android.Platform
|
||||
private InputPaneState _state;
|
||||
private Rect _previousRect;
|
||||
private Insets? _previousImeInset;
|
||||
private bool _displayEdgeToEdgePreference;
|
||||
private readonly bool _usesLegacyLayouts;
|
||||
|
||||
private AndroidWindow Window => _activity.Window ?? throw new InvalidOperationException("Activity.Window must be set.");
|
||||
@@ -50,29 +54,42 @@ namespace Avalonia.Android.Platform
|
||||
}
|
||||
}
|
||||
|
||||
public bool DisplayEdgeToEdge
|
||||
public bool DisplayEdgeToEdgePreference
|
||||
{
|
||||
get => _displayEdgeToEdge;
|
||||
get => _displayEdgeToEdgePreference;
|
||||
set
|
||||
{
|
||||
_displayEdgeToEdge = value;
|
||||
_displayEdgeToEdgePreference = value;
|
||||
|
||||
if (OperatingSystem.IsAndroidVersionAtLeast(28) && Window.Attributes is { } attributes)
|
||||
{
|
||||
attributes.LayoutInDisplayCutoutMode = value ? LayoutInDisplayCutoutMode.ShortEdges : LayoutInDisplayCutoutMode.Default;
|
||||
}
|
||||
UpdateDisplayEdgeToEgdeState();
|
||||
}
|
||||
}
|
||||
|
||||
WindowCompat.SetDecorFitsSystemWindows(Window, !value);
|
||||
private void UpdateDisplayEdgeToEgdeState()
|
||||
{
|
||||
if (IsDisplayEdgeToEdgeForced)
|
||||
{
|
||||
_displaysEdgeToEdge = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value)
|
||||
{
|
||||
Window.AddFlags(WindowManagerFlags.TranslucentStatus);
|
||||
Window.AddFlags(WindowManagerFlags.TranslucentNavigation);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemBarColor = _systemBarColor;
|
||||
}
|
||||
_displaysEdgeToEdge = _displayEdgeToEdgePreference;
|
||||
|
||||
if (OperatingSystem.IsAndroidVersionAtLeast(28) && Window.Attributes is { } attributes)
|
||||
{
|
||||
attributes.LayoutInDisplayCutoutMode = _displayEdgeToEdgePreference ? LayoutInDisplayCutoutMode.ShortEdges : LayoutInDisplayCutoutMode.Default;
|
||||
}
|
||||
|
||||
WindowCompat.SetDecorFitsSystemWindows(Window, !_displayEdgeToEdgePreference);
|
||||
|
||||
if (_displayEdgeToEdgePreference)
|
||||
{
|
||||
Window.AddFlags(WindowManagerFlags.TranslucentStatus);
|
||||
Window.AddFlags(WindowManagerFlags.TranslucentNavigation);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemBarColor = _systemBarColor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +106,7 @@ namespace Avalonia.Android.Platform
|
||||
_activity.Window?.DecorView.ViewTreeObserver?.AddOnGlobalLayoutListener(this);
|
||||
}
|
||||
|
||||
DisplayEdgeToEdge = false;
|
||||
DisplayEdgeToEdgePreference = false;
|
||||
|
||||
ViewCompat.SetWindowInsetsAnimationCallback(Window.DecorView, this);
|
||||
}
|
||||
@@ -105,11 +122,11 @@ namespace Avalonia.Android.Platform
|
||||
var renderScaling = _topLevel.RenderScaling;
|
||||
|
||||
var inset = insets.GetInsets(
|
||||
_displayEdgeToEdge ?
|
||||
DisplaysEdgeToEdge ?
|
||||
WindowInsetsCompat.Type.StatusBars() | WindowInsetsCompat.Type.NavigationBars() |
|
||||
WindowInsetsCompat.Type.DisplayCutout() : 0);
|
||||
|
||||
return new Thickness(inset.Left / renderScaling,
|
||||
return new Thickness(inset.Left / renderScaling,
|
||||
inset.Top / renderScaling,
|
||||
inset.Right / renderScaling,
|
||||
inset.Bottom / renderScaling);
|
||||
@@ -264,7 +281,10 @@ namespace Avalonia.Android.Platform
|
||||
{
|
||||
_systemBarColor = value;
|
||||
|
||||
if (_systemBarColor is { } color && !_displayEdgeToEdge && _activity.Window != null)
|
||||
if (IsDisplayEdgeToEdgeForced)
|
||||
return;
|
||||
|
||||
if (_systemBarColor is { } color && !_displaysEdgeToEdge && _activity.Window != null)
|
||||
{
|
||||
_activity.Window.ClearFlags(WindowManagerFlags.TranslucentStatus);
|
||||
_activity.Window.ClearFlags(WindowManagerFlags.TranslucentNavigation);
|
||||
@@ -282,6 +302,10 @@ namespace Avalonia.Android.Platform
|
||||
}
|
||||
}
|
||||
|
||||
public bool DisplayEdgeToEdge { get => DisplaysEdgeToEdge; set => DisplayEdgeToEdgePreference = value; }
|
||||
|
||||
public bool DisplaysEdgeToEdge => _displaysEdgeToEdge;
|
||||
|
||||
internal void ApplyStatusBarState()
|
||||
{
|
||||
IsSystemBarVisible = _systemUiVisibility;
|
||||
|
||||
@@ -17,8 +17,20 @@ namespace Avalonia.Controls.Platform
|
||||
/// <summary>
|
||||
/// Gets or sets whether the window draws edge to edge. behind any visible system bars.
|
||||
/// </summary>
|
||||
bool DisplayEdgeToEdgePreference { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the window draws edge to edge. behind any visible system bars.
|
||||
/// </summary>
|
||||
[Obsolete("Use DisplayEdgeToEdgePreference")]
|
||||
bool DisplayEdgeToEdge { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the window is currently displaying edge to edge.
|
||||
/// </summary>
|
||||
bool DisplaysEdgeToEdge { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current safe area padding.
|
||||
/// </summary>
|
||||
@@ -39,9 +51,12 @@ namespace Avalonia.Controls.Platform
|
||||
public abstract class InsetsManagerBase : IInsetsManager
|
||||
{
|
||||
public virtual bool? IsSystemBarVisible { get; set; }
|
||||
public virtual bool DisplayEdgeToEdge { get; set; }
|
||||
public virtual bool DisplayEdgeToEdgePreference { get; set; }
|
||||
public virtual bool DisplayEdgeToEdge { get => DisplaysEdgeToEdge; set => DisplayEdgeToEdgePreference = value; }
|
||||
public virtual Thickness SafeAreaPadding { get; protected set; }
|
||||
public virtual Color? SystemBarColor { get; set; }
|
||||
public virtual bool DisplaysEdgeToEdge => DisplayEdgeToEdgePreference;
|
||||
|
||||
public event EventHandler<SafeAreaChangedArgs>? SafeAreaChanged;
|
||||
|
||||
protected void OnSafeAreaChanged(SafeAreaChangedArgs eventArgs)
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Avalonia.Browser
|
||||
}
|
||||
}
|
||||
|
||||
public override bool DisplayEdgeToEdge { get; set; }
|
||||
public override bool DisplayEdgeToEdgePreference { get; set; }
|
||||
|
||||
public override Thickness SafeAreaPadding
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ internal class InsetsManager : InsetsManagerBase
|
||||
}
|
||||
public event EventHandler<bool>? DisplayEdgeToEdgeChanged;
|
||||
|
||||
public override bool DisplayEdgeToEdge
|
||||
public override bool DisplayEdgeToEdgePreference
|
||||
{
|
||||
get => _displayEdgeToEdge;
|
||||
set
|
||||
|
||||
Reference in New Issue
Block a user