Browse Source

Merge branch 'master' into fixes/Some_Null_Annotation_And_Warning

pull/6754/head
Giuseppe Lippolis 5 years ago
parent
commit
269610b6e5
  1. 2
      build/SourceLink.props
  2. 6
      src/Avalonia.Animation/Animation.cs
  3. 12
      src/Avalonia.Animation/Animators/Animator`1.cs
  4. 3
      src/Avalonia.Animation/ApiCompatBaseline.txt
  5. 15
      src/Avalonia.Base/Data/Converters/MethodToCommandConverter.cs
  6. 2
      src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs
  7. 3
      src/Avalonia.Controls/Remote/RemoteServer.cs
  8. 2
      src/Avalonia.Controls/TextBoxTextInputMethodClient.cs
  9. 2
      src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs
  10. 25
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs
  11. 2
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs
  12. 6
      src/Avalonia.FreeDesktop/DBusMenuExporter.cs
  13. 2
      src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
  14. 23
      src/Avalonia.Themes.Default/Expander.xaml
  15. 22
      src/Avalonia.Visuals/Matrix.cs
  16. 10
      src/Avalonia.Visuals/Media/Transformation/InterpolationUtilities.cs
  17. 5
      src/Avalonia.Visuals/Media/Transformation/TransformOperation.cs
  18. 4
      src/Avalonia.X11/X11Window.Xim.cs
  19. 1
      src/Avalonia.X11/X11Window.cs
  20. 67
      tests/Avalonia.Animation.UnitTests/AnimatableTests.cs
  21. 2
      tests/Avalonia.Controls.UnitTests/ItemsSourceViewTests.cs
  22. 72
      tests/Avalonia.Visuals.UnitTests/Media/TransformOperationsTests.cs

2
build/SourceLink.props

@ -3,7 +3,7 @@
<PublishRepositoryUrl>true</PublishRepositoryUrl> <PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>false</IncludeSymbols> <IncludeSymbols>false</IncludeSymbols>
<EmbedUntrackedSources>true</EmbedUntrackedSources> <EmbedUntrackedSources>true</EmbedUntrackedSources>
<DebugType>embedded</DebugType> <DebugType>full</DebugType>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder> <AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
</PropertyGroup> </PropertyGroup>

6
src/Avalonia.Animation/Animation.cs

@ -353,6 +353,12 @@ namespace Avalonia.Animation
return new CompositeDisposable(subscriptions); return new CompositeDisposable(subscriptions);
} }
/// <inheritdoc/>
public Task RunAsync(Animatable control, IClock clock = null)
{
return RunAsync(control, clock, default);
}
/// <inheritdoc/> /// <inheritdoc/>
public Task RunAsync(Animatable control, IClock clock = null, CancellationToken cancellationToken = default) public Task RunAsync(Animatable control, IClock clock = null, CancellationToken cancellationToken = default)
{ {

12
src/Avalonia.Animation/Animators/Animator`1.cs

@ -79,15 +79,15 @@ namespace Avalonia.Animation.Animators
T oldValue, newValue; T oldValue, newValue;
if (firstKeyframe.isNeutral) if (!firstKeyframe.isNeutral && firstKeyframe.Value is T firstKeyframeValue)
oldValue = neutralValue; oldValue = firstKeyframeValue;
else else
oldValue = (T)firstKeyframe.Value; oldValue = neutralValue;
if (lastKeyframe.isNeutral) if (!lastKeyframe.isNeutral && lastKeyframe.Value is T lastKeyframeValue)
newValue = neutralValue; newValue = lastKeyframeValue;
else else
newValue = (T)lastKeyframe.Value; newValue = neutralValue;
if (lastKeyframe.KeySpline != null) if (lastKeyframe.KeySpline != null)
progress = lastKeyframe.KeySpline.GetSplineProgress(progress); progress = lastKeyframe.KeySpline.GetSplineProgress(progress);

3
src/Avalonia.Animation/ApiCompatBaseline.txt

@ -1,6 +1,5 @@
Compat issues with assembly Avalonia.Animation: Compat issues with assembly Avalonia.Animation:
MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.Animation.RunAsync(Avalonia.Animation.Animatable, Avalonia.Animation.IClock)' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Tasks.Task Avalonia.Animation.IAnimation.RunAsync(Avalonia.Animation.Animatable, Avalonia.Animation.IClock)' is present in the contract but not in the implementation. InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Tasks.Task Avalonia.Animation.IAnimation.RunAsync(Avalonia.Animation.Animatable, Avalonia.Animation.IClock)' is present in the contract but not in the implementation.
MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.IAnimation.RunAsync(Avalonia.Animation.Animatable, Avalonia.Animation.IClock)' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.IAnimation.RunAsync(Avalonia.Animation.Animatable, Avalonia.Animation.IClock)' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Tasks.Task Avalonia.Animation.IAnimation.RunAsync(Avalonia.Animation.Animatable, Avalonia.Animation.IClock, System.Threading.CancellationToken)' is present in the implementation but not in the contract. InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Tasks.Task Avalonia.Animation.IAnimation.RunAsync(Avalonia.Animation.Animatable, Avalonia.Animation.IClock, System.Threading.CancellationToken)' is present in the implementation but not in the contract.
Total Issues: 4 Total Issues: 3

15
src/Avalonia.Base/Data/Converters/MethodToCommandConverter.cs

@ -140,18 +140,9 @@ namespace Avalonia.Data.Converters
); );
} }
Action<object> action = null; return Expression
try .Lambda<Action<object>>(body, parameter)
{ .Compile();
action = Expression
.Lambda<Action<object>>(body, parameter)
.Compile();
}
catch (Exception ex)
{
throw ex;
}
return action;
} }
static Func<object, bool> CreateCanExecute(object target static Func<object, bool> CreateCanExecute(object target

2
src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs

@ -85,7 +85,9 @@ namespace Avalonia.Controls.Platform
public bool CurrentThreadIsLoopThread => TlsCurrentThreadIsLoopThread; public bool CurrentThreadIsLoopThread => TlsCurrentThreadIsLoopThread;
public event Action<DispatcherPriority?> Signaled; public event Action<DispatcherPriority?> Signaled;
#pragma warning disable CS0067
public event Action<TimeSpan> Tick; public event Action<TimeSpan> Tick;
#pragma warning restore CS0067
} }
} }

3
src/Avalonia.Controls/Remote/RemoteServer.cs

@ -15,9 +15,6 @@ namespace Avalonia.Controls.Remote
public EmbeddableRemoteServerTopLevelImpl(IAvaloniaRemoteTransportConnection transport) : base(transport) public EmbeddableRemoteServerTopLevelImpl(IAvaloniaRemoteTransportConnection transport) : base(transport)
{ {
} }
#pragma warning disable 67
public Action LostFocus { get; set; }
} }
public RemoteServer(IAvaloniaRemoteTransportConnection transport) public RemoteServer(IAvaloniaRemoteTransportConnection transport)

2
src/Avalonia.Controls/TextBoxTextInputMethodClient.cs

@ -18,7 +18,7 @@ namespace Avalonia.Controls
public bool SupportsSurroundingText => false; public bool SupportsSurroundingText => false;
public TextInputMethodSurroundingText SurroundingText => throw new NotSupportedException(); public TextInputMethodSurroundingText SurroundingText => throw new NotSupportedException();
public event EventHandler SurroundingTextChanged; public event EventHandler SurroundingTextChanged { add { } remove { } }
public string TextBeforeCursor => null; public string TextBeforeCursor => null;
public string TextAfterCursor => null; public string TextAfterCursor => null;

2
src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs

@ -59,7 +59,7 @@ namespace Avalonia.DesignerSupport.Remote
remove { _onMessage -= value; } remove { _onMessage -= value; }
} }
public event Action<IAvaloniaRemoteTransportConnection, Exception> OnException; public event Action<IAvaloniaRemoteTransportConnection, Exception> OnException { add { } remove { } }
public void Start() public void Start()
{ {
UpdaterThread(); UpdaterThread();

25
src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs

@ -17,16 +17,16 @@ namespace Avalonia.Diagnostics.ViewModels
internal class ControlDetailsViewModel : ViewModelBase, IDisposable internal class ControlDetailsViewModel : ViewModelBase, IDisposable
{ {
private readonly IVisual _control; private readonly IVisual _control;
private IDictionary<object, List<PropertyViewModel>> _propertyIndex; private IDictionary<object, List<PropertyViewModel>>? _propertyIndex;
private PropertyViewModel? _selectedProperty; private PropertyViewModel? _selectedProperty;
private DataGridCollectionView _propertiesView; private DataGridCollectionView? _propertiesView;
private bool _snapshotStyles; private bool _snapshotStyles;
private bool _showInactiveStyles; private bool _showInactiveStyles;
private string? _styleStatus; private string? _styleStatus;
private object _selectedEntity; private object? _selectedEntity;
private readonly Stack<(string Name,object Entry)> _selectedEntitiesStack = new(); private readonly Stack<(string Name,object Entry)> _selectedEntitiesStack = new();
private string _selectedEntityName; private string? _selectedEntityName;
private string _selectedEntityType; private string? _selectedEntityType;
public ControlDetailsViewModel(TreePageViewModel treePage, IVisual control) public ControlDetailsViewModel(TreePageViewModel treePage, IVisual control)
{ {
@ -117,7 +117,7 @@ namespace Avalonia.Diagnostics.ViewModels
public TreePageViewModel TreePage { get; } public TreePageViewModel TreePage { get; }
public DataGridCollectionView PropertiesView public DataGridCollectionView? PropertiesView
{ {
get => _propertiesView; get => _propertiesView;
private set => RaiseAndSetIfChanged(ref _propertiesView, value); private set => RaiseAndSetIfChanged(ref _propertiesView, value);
@ -127,7 +127,7 @@ namespace Avalonia.Diagnostics.ViewModels
public ObservableCollection<PseudoClassViewModel> PseudoClasses { get; } public ObservableCollection<PseudoClassViewModel> PseudoClasses { get; }
public object SelectedEntity public object? SelectedEntity
{ {
get => _selectedEntity; get => _selectedEntity;
set set
@ -137,7 +137,7 @@ namespace Avalonia.Diagnostics.ViewModels
} }
} }
public string SelectedEntityName public string? SelectedEntityName
{ {
get => _selectedEntityName; get => _selectedEntityName;
set set
@ -147,7 +147,7 @@ namespace Avalonia.Diagnostics.ViewModels
} }
} }
public string SelectedEntityType public string? SelectedEntityType
{ {
get => _selectedEntityType; get => _selectedEntityType;
set set
@ -270,7 +270,7 @@ namespace Avalonia.Diagnostics.ViewModels
private void ControlPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) private void ControlPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{ {
if (_propertyIndex.TryGetValue(e.Property, out var properties)) if (_propertyIndex is { } && _propertyIndex.TryGetValue(e.Property, out var properties))
{ {
foreach (var property in properties) foreach (var property in properties)
{ {
@ -284,6 +284,7 @@ namespace Avalonia.Diagnostics.ViewModels
private void ControlPropertyChanged(object? sender, PropertyChangedEventArgs e) private void ControlPropertyChanged(object? sender, PropertyChangedEventArgs e)
{ {
if (e.PropertyName != null if (e.PropertyName != null
&& _propertyIndex is { }
&& _propertyIndex.TryGetValue(e.PropertyName, out var properties)) && _propertyIndex.TryGetValue(e.PropertyName, out var properties))
{ {
foreach (var property in properties) foreach (var property in properties)
@ -402,7 +403,7 @@ namespace Avalonia.Diagnostics.ViewModels
var selectedProperty = SelectedProperty; var selectedProperty = SelectedProperty;
var selectedEntity = SelectedEntity; var selectedEntity = SelectedEntity;
var selectedEntityName = SelectedEntityName; var selectedEntityName = SelectedEntityName;
if (selectedProperty == null) if (selectedEntity == null || selectedProperty == null)
return; return;
object? property; object? property;
@ -419,7 +420,7 @@ namespace Avalonia.Diagnostics.ViewModels
?.GetValue(selectedEntity); ?.GetValue(selectedEntity);
} }
if (property == null) return; if (property == null) return;
_selectedEntitiesStack.Push((Name:selectedEntityName,Entry:selectedEntity)); _selectedEntitiesStack.Push((Name:selectedEntityName!,Entry:selectedEntity));
NavigateToProperty(property, selectedProperty.Name); NavigateToProperty(property, selectedProperty.Name);
} }

2
src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs

@ -15,7 +15,7 @@ namespace Avalonia.Diagnostics.ViewModels
Nodes = nodes; Nodes = nodes;
PropertiesFilter = new FilterViewModel(); PropertiesFilter = new FilterViewModel();
PropertiesFilter.RefreshFilter += (s, e) => Details?.PropertiesView.Refresh(); PropertiesFilter.RefreshFilter += (s, e) => Details?.PropertiesView?.Refresh();
SettersFilter = new FilterViewModel(); SettersFilter = new FilterViewModel();
SettersFilter.RefreshFilter += (s, e) => Details?.UpdateStyleFilters(); SettersFilter.RefreshFilter += (s, e) => Details?.UpdateStyleFilters();

6
src/Avalonia.FreeDesktop/DBusMenuExporter.cs

@ -413,10 +413,10 @@ namespace Avalonia.FreeDesktop
#region Events #region Events
private event Action<((int, IDictionary<string, object>)[] updatedProps, (int, string[])[] removedProps)> private event Action<((int, IDictionary<string, object>)[] updatedProps, (int, string[])[] removedProps)>
ItemsPropertiesUpdated; ItemsPropertiesUpdated { add { } remove { } }
private event Action<(uint revision, int parent)> LayoutUpdated; private event Action<(uint revision, int parent)> LayoutUpdated;
private event Action<(int id, uint timestamp)> ItemActivationRequested; private event Action<(int id, uint timestamp)> ItemActivationRequested { add { } remove { } }
private event Action<PropertyChanges> PropertiesChanged; private event Action<PropertyChanges> PropertiesChanged { add { } remove { } }
async Task<IDisposable> IDBusMenu.WatchItemsPropertiesUpdatedAsync(Action<((int, IDictionary<string, object>)[] updatedProps, (int, string[])[] removedProps)> handler, Action<Exception> onError) async Task<IDisposable> IDBusMenu.WatchItemsPropertiesUpdatedAsync(Action<((int, IDictionary<string, object>)[] updatedProps, (int, string[])[] removedProps)> handler, Action<Exception> onError)
{ {

2
src/Avalonia.Native/AvaloniaNativeMenuExporter.cs

@ -44,7 +44,7 @@ namespace Avalonia.Native
public bool IsNativeMenuExported => _exported; public bool IsNativeMenuExported => _exported;
public event EventHandler OnIsNativeMenuExportedChanged; public event EventHandler OnIsNativeMenuExportedChanged { add { } remove { } }
public void SetNativeMenu(NativeMenu menu) public void SetNativeMenu(NativeMenu menu)
{ {

23
src/Avalonia.Themes.Default/Expander.xaml

@ -15,7 +15,7 @@
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"> CornerRadius="{TemplateBinding CornerRadius}">
<Grid RowDefinitions="Auto,*"> <Grid RowDefinitions="Auto,*">
<ToggleButton Name="PART_toggle" Grid.Row="0" Content="{TemplateBinding Header}" IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" /> <ToggleButton Name="PART_toggle" Grid.Row="0" Content="{TemplateBinding Header}" IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" />
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"
Grid.Row="1" Grid.Row="1"
IsVisible="{TemplateBinding IsExpanded}" IsVisible="{TemplateBinding IsExpanded}"
@ -32,9 +32,12 @@
<Style Selector="Expander[ExpandDirection=Up]"> <Style Selector="Expander[ExpandDirection=Up]">
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border Background="{TemplateBinding Background}"> <Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid RowDefinitions="*,Auto"> <Grid RowDefinitions="*,Auto">
<ToggleButton Name="PART_toggle" Grid.Row="1" Content="{TemplateBinding Header}" IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" /> <ToggleButton Name="PART_toggle" Grid.Row="1" Content="{TemplateBinding Header}" IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" />
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"
Grid.Row="0" Grid.Row="0"
IsVisible="{TemplateBinding IsExpanded}" IsVisible="{TemplateBinding IsExpanded}"
@ -51,9 +54,12 @@
<Style Selector="Expander[ExpandDirection=Right]"> <Style Selector="Expander[ExpandDirection=Right]">
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border Background="{TemplateBinding Background}"> <Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid ColumnDefinitions="Auto,*"> <Grid ColumnDefinitions="Auto,*">
<ToggleButton Name="PART_toggle" Grid.Column="0" Content="{TemplateBinding Header}" IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" /> <ToggleButton Name="PART_toggle" Grid.Column="0" Content="{TemplateBinding Header}" IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" />
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"
Grid.Column="1" Grid.Column="1"
IsVisible="{TemplateBinding IsExpanded}" IsVisible="{TemplateBinding IsExpanded}"
@ -70,9 +76,12 @@
<Style Selector="Expander[ExpandDirection=Left]"> <Style Selector="Expander[ExpandDirection=Left]">
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border Background="{TemplateBinding Background}"> <Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid ColumnDefinitions="*,Auto"> <Grid ColumnDefinitions="*,Auto">
<ToggleButton Name="PART_toggle" Grid.Column="1" Content="{TemplateBinding Header}" IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" /> <ToggleButton Name="PART_toggle" Grid.Column="1" Content="{TemplateBinding Header}" IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" />
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"
Grid.Column="0" Grid.Column="0"
IsVisible="{TemplateBinding IsExpanded}" IsVisible="{TemplateBinding IsExpanded}"

22
src/Avalonia.Visuals/Matrix.cs

@ -215,6 +215,28 @@ namespace Avalonia
return angle * 0.0174532925; return angle * 0.0174532925;
} }
/// <summary>
/// Appends another matrix as post-multiplication operation.
/// Equivalent to this * value;
/// </summary>
/// <param name="value">A matrix.</param>
/// <returns>Post-multiplied matrix.</returns>
public Matrix Append(Matrix value)
{
return this * value;
}
/// <summary>
/// Prpends another matrix as pre-multiplication operation.
/// Equivalent to value * this;
/// </summary>
/// <param name="value">A matrix.</param>
/// <returns>Pre-multiplied matrix.</returns>
public Matrix Prepend(Matrix value)
{
return value * this;
}
/// <summary> /// <summary>
/// Calculates the determinant for this matrix. /// Calculates the determinant for this matrix.
/// </summary> /// </summary>

10
src/Avalonia.Visuals/Media/Transformation/InterpolationUtilities.cs

@ -18,11 +18,11 @@ namespace Avalonia.Media.Transformation
public static Matrix ComposeTransform(Matrix.Decomposed decomposed) public static Matrix ComposeTransform(Matrix.Decomposed decomposed)
{ {
// According to https://www.w3.org/TR/css-transforms-1/#recomposing-to-a-2d-matrix // According to https://www.w3.org/TR/css-transforms-1/#recomposing-to-a-2d-matrix
return Matrix.Identity
return Matrix.CreateTranslation(decomposed.Translate) * .Prepend(Matrix.CreateTranslation(decomposed.Translate))
Matrix.CreateRotation(decomposed.Angle) * .Prepend(Matrix.CreateRotation(decomposed.Angle))
Matrix.CreateSkew(decomposed.Skew.X, decomposed.Skew.Y) * .Prepend(Matrix.CreateSkew(decomposed.Skew.X, decomposed.Skew.Y))
Matrix.CreateScale(decomposed.Scale); .Prepend(Matrix.CreateScale(decomposed.Scale));
} }
public static Matrix.Decomposed InterpolateDecomposedTransforms(ref Matrix.Decomposed from, ref Matrix.Decomposed to, double progress) public static Matrix.Decomposed InterpolateDecomposedTransforms(ref Matrix.Decomposed from, ref Matrix.Decomposed to, double progress)

5
src/Avalonia.Visuals/Media/Transformation/TransformOperation.cs

@ -86,6 +86,8 @@ namespace Avalonia.Media.Transformation
if (fromIdentity && toIdentity) if (fromIdentity && toIdentity)
{ {
result.Matrix = Matrix.Identity;
return true; return true;
} }
@ -179,7 +181,8 @@ namespace Avalonia.Media.Transformation
} }
case OperationType.Identity: case OperationType.Identity:
{ {
// Do nothing. result.Matrix = Matrix.Identity;
break; break;
} }
} }

4
src/Avalonia.X11/X11Window.Xim.cs

@ -112,8 +112,8 @@ namespace Avalonia.X11
public ValueTask<bool> HandleEventAsync(RawKeyEventArgs args, int keyVal, int keyCode) => public ValueTask<bool> HandleEventAsync(RawKeyEventArgs args, int keyVal, int keyCode) =>
new ValueTask<bool>(false); new ValueTask<bool>(false);
public event Action<string> Commit; public event Action<string> Commit { add { } remove { } }
public event Action<X11InputMethodForwardedKey> ForwardKey; public event Action<X11InputMethodForwardedKey> ForwardKey { add { } remove { } }
} }

1
src/Avalonia.X11/X11Window.cs

@ -1026,6 +1026,7 @@ namespace Avalonia.X11
if (string.IsNullOrEmpty(title)) if (string.IsNullOrEmpty(title))
{ {
XDeleteProperty(_x11.Display, _handle, _x11.Atoms._NET_WM_NAME); XDeleteProperty(_x11.Display, _handle, _x11.Atoms._NET_WM_NAME);
XDeleteProperty(_x11.Display, _handle, _x11.Atoms.XA_WM_NAME);
} }
else else
{ {

67
tests/Avalonia.Animation.UnitTests/AnimatableTests.cs

@ -1,5 +1,7 @@
using System; using System;
using Avalonia.Animation.Animators;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Layout; using Avalonia.Layout;
using Avalonia.Media; using Avalonia.Media;
@ -100,6 +102,71 @@ namespace Avalonia.Animation.UnitTests
Times.Never); Times.Never);
} }
[Theory]
[InlineData(null)] //null value
[InlineData("stringValue")] //string value
public void Invalid_Values_In_Animation_Should_Not_Crash_Animations(object invalidValue)
{
var keyframe1 = new KeyFrame()
{
Setters =
{
new Setter(Layoutable.WidthProperty, 1d),
},
KeyTime = TimeSpan.FromSeconds(0)
};
var keyframe2 = new KeyFrame()
{
Setters =
{
new Setter(Layoutable.WidthProperty, 2d),
},
KeyTime = TimeSpan.FromSeconds(2),
};
var keyframe3 = new KeyFrame()
{
Setters =
{
new Setter(Layoutable.WidthProperty, invalidValue),
},
KeyTime = TimeSpan.FromSeconds(3),
};
var animation = new Animation()
{
Duration = TimeSpan.FromSeconds(3),
Children =
{
keyframe1,
keyframe2,
keyframe3
},
IterationCount = new IterationCount(5),
PlaybackDirection = PlaybackDirection.Alternate,
};
var rect = new Rectangle()
{
Width = 11,
};
var originalValue = rect.Width;
var clock = new TestClock();
var animationRun = animation.RunAsync(rect, clock);
clock.Step(TimeSpan.Zero);
Assert.Equal(rect.Width, 1);
clock.Step(TimeSpan.FromSeconds(2));
Assert.Equal(rect.Width, 2);
clock.Step(TimeSpan.FromSeconds(3));
//here we have invalid value so value should be expected and set to initial original value
Assert.Equal(rect.Width, originalValue);
}
[Fact] [Fact]
public void Transition_Is_Not_Applied_When_StyleTrigger_Changes_With_LocalValue_Present() public void Transition_Is_Not_Applied_When_StyleTrigger_Changes_With_LocalValue_Present()
{ {

2
tests/Avalonia.Controls.UnitTests/ItemsSourceViewTests.cs

@ -47,7 +47,7 @@ namespace Avalonia.Controls.UnitTests
private class InvalidCollection : INotifyCollectionChanged, IEnumerable<string> private class InvalidCollection : INotifyCollectionChanged, IEnumerable<string>
{ {
public event NotifyCollectionChangedEventHandler CollectionChanged; public event NotifyCollectionChangedEventHandler CollectionChanged { add { } remove { } }
public IEnumerator<string> GetEnumerator() public IEnumerator<string> GetEnumerator()
{ {

72
tests/Avalonia.Visuals.UnitTests/Media/TransformOperationsTests.cs

@ -129,7 +129,7 @@ namespace Avalonia.Visuals.UnitTests.Media
Assert.Single(operations); Assert.Single(operations);
Assert.Equal(TransformOperation.OperationType.Matrix, operations[0].Type); Assert.Equal(TransformOperation.OperationType.Matrix, operations[0].Type);
var expectedMatrix = new Matrix(1, 2, 3, 4, 5, 6); var expectedMatrix = new Matrix(1, 2, 3, 4, 5, 6);
Assert.Equal(expectedMatrix, operations[0].Matrix); Assert.Equal(expectedMatrix, operations[0].Matrix);
@ -195,7 +195,7 @@ namespace Avalonia.Visuals.UnitTests.Media
[Theory] [Theory]
[InlineData(0d, 10d)] [InlineData(0d, 10d)]
[InlineData(0.5d, 15d)] [InlineData(0.5d, 15d)]
[InlineData(1d,20d)] [InlineData(1d, 20d)]
public void Can_Interpolate_Rotation(double progress, double angle) public void Can_Interpolate_Rotation(double progress, double angle)
{ {
var from = TransformOperations.Parse("rotate(10deg)"); var from = TransformOperations.Parse("rotate(10deg)");
@ -225,5 +225,73 @@ namespace Avalonia.Visuals.UnitTests.Media
Assert.Single(operations); Assert.Single(operations);
Assert.Equal(TransformOperation.OperationType.Matrix, operations[0].Type); Assert.Equal(TransformOperation.OperationType.Matrix, operations[0].Type);
} }
[Fact]
public void Order_Of_Operations_Is_Preserved_No_Prefix()
{
var from = TransformOperations.Parse("scale(1)");
var to = TransformOperations.Parse("translate(50px,50px) scale(0.5,0.5)");
var interpolated_0 = TransformOperations.Interpolate(from, to, 0);
Assert.True(interpolated_0.IsIdentity);
var interpolated_50 = TransformOperations.Interpolate(from, to, 0.5);
AssertMatrix(interpolated_50.Value, scaleX: 0.75, scaleY: 0.75, translateX: 12.5, translateY: 12.5);
var interpolated_100 = TransformOperations.Interpolate(from, to, 1);
AssertMatrix(interpolated_100.Value, scaleX: 0.5, scaleY: 0.5, translateX: 25, translateY: 25);
}
[Fact]
public void Order_Of_Operations_Is_Preserved_One_Prefix()
{
var from = TransformOperations.Parse("scale(1)");
var to = TransformOperations.Parse("scale(0.5,0.5) translate(50px,50px)");
var interpolated_0 = TransformOperations.Interpolate(from, to, 0);
Assert.True(interpolated_0.IsIdentity);
var interpolated_50 = TransformOperations.Interpolate(from, to, 0.5);
AssertMatrix(interpolated_50.Value, scaleX: 0.75, scaleY: 0.75, translateX: 25.0, translateY: 25);
var interpolated_100 = TransformOperations.Interpolate(from, to, 1);
AssertMatrix(interpolated_100.Value, scaleX: 0.5, scaleY: 0.5, translateX: 50, translateY: 50);
}
private static void AssertMatrix(Matrix matrix, double? angle = null, double? scaleX = null, double? scaleY = null, double? translateX = null, double? translateY = null)
{
Assert.True(Matrix.TryDecomposeTransform(matrix, out var composed));
if (angle.HasValue)
{
Assert.Equal(angle.Value, composed.Angle);
}
if (scaleX.HasValue)
{
Assert.Equal(scaleX.Value, composed.Scale.X);
}
if (scaleY.HasValue)
{
Assert.Equal(scaleY.Value, composed.Scale.Y);
}
if (translateX.HasValue)
{
Assert.Equal(translateX.Value, composed.Translate.X);
}
if (translateY.HasValue)
{
Assert.Equal(translateY.Value, composed.Translate.Y);
}
}
} }
} }

Loading…
Cancel
Save