Browse Source

Merge branch 'master' into fix-textbox-pointermove-crashes

Dariusz Komosiński 5 years ago
parent
commit
e83c23838e
23 changed files with 182 additions and 16 deletions
  1. 1 1
      build/SharedVersion.props
  2. 1 1
      samples/RenderDemo/App.xaml
  3. 1 1
      samples/Sandbox/App.axaml
  4. 5 1
      src/Avalonia.Layout/LayoutContext.cs
  5. 3 2
      src/Avalonia.Themes.Fluent/ApiCompatBaseline.txt
  6. 114 0
      src/Avalonia.Themes.Fluent/FluentTheme.cs
  7. 3 0
      src/Avalonia.Themes.Fluent/Properties/AssemblyInfo.cs
  8. 35 6
      src/Windows/Avalonia.Win32/ClipboardImpl.cs
  9. 1 0
      tests/Avalonia.Animation.UnitTests/Avalonia.Animation.UnitTests.csproj
  10. 2 1
      tests/Avalonia.Base.UnitTests/Avalonia.Base.UnitTests.csproj
  11. 1 0
      tests/Avalonia.Controls.DataGrid.UnitTests/Avalonia.Controls.DataGrid.UnitTests.csproj
  12. 1 0
      tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj
  13. 1 0
      tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj
  14. 2 1
      tests/Avalonia.Direct2D1.UnitTests/Avalonia.Direct2D1.UnitTests.csproj
  15. 1 0
      tests/Avalonia.Layout.UnitTests/Avalonia.Layout.UnitTests.csproj
  16. 2 1
      tests/Avalonia.LeakTests/Avalonia.LeakTests.csproj
  17. 1 0
      tests/Avalonia.Markup.UnitTests/Avalonia.Markup.UnitTests.csproj
  18. 1 0
      tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj
  19. 1 0
      tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj
  20. 2 1
      tests/Avalonia.Skia.UnitTests/Avalonia.Skia.UnitTests.csproj
  21. 1 0
      tests/Avalonia.Styling.UnitTests/Avalonia.Styling.UnitTests.csproj
  22. 1 0
      tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj
  23. 1 0
      tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj

+ 1 - 1
build/SharedVersion.props

@@ -16,7 +16,7 @@
     <PackageReleaseNotes>https://github.com/AvaloniaUI/Avalonia/releases</PackageReleaseNotes>
     <RepositoryType>git</RepositoryType>
     <AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)\avalonia.snk</AssemblyOriginatorKeyFile>
-    <SignAssembly>false</SignAssembly>
+    <SignAssembly>true</SignAssembly>
     <DefineConstants Condition="$(SignAssembly) == true">$(DefineConstants);SIGNED_BUILD</DefineConstants>
   </PropertyGroup>
 

+ 1 - 1
samples/RenderDemo/App.xaml

@@ -3,7 +3,7 @@
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     x:Class="RenderDemo.App">
     <Application.Styles>
-        <StyleInclude Source="avares://Avalonia.Themes.Fluent/FluentLight.xaml"/>
+        <FluentTheme/>
         <StyleInclude Source="avares://RenderDemo/SideBar.xaml"/>
     </Application.Styles>
 </Application>

+ 1 - 1
samples/Sandbox/App.axaml

@@ -3,6 +3,6 @@
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     x:Class="Sandbox.App">
     <Application.Styles>
-        <StyleInclude Source="avares://Avalonia.Themes.Fluent/FluentDark.xaml"/>
+        <FluentTheme Mode="Dark"/>
     </Application.Styles>
 </Application>

+ 5 - 1
src/Avalonia.Layout/LayoutContext.cs

@@ -14,7 +14,11 @@ namespace Avalonia.Layout
         /// <summary>
         /// Gets or sets an object that represents the state of a layout.
         /// </summary>
-        public object LayoutState { get; set; }
+        public object LayoutState 
+        {
+            get => LayoutStateCore;
+            set => LayoutStateCore = value;
+        }
 
         /// <summary>
         /// Implements the behavior of <see cref="LayoutState"/> in a derived or custom LayoutContext.

+ 3 - 2
src/Avalonia.Themes.Fluent/ApiCompatBaseline.txt

@@ -1,3 +1,4 @@
 Compat issues with assembly Avalonia.Themes.Fluent:
-TypesMustExist : Type 'Avalonia.Themes.Fluent.FluentTheme' does not exist in the implementation but it does exist in the contract.
-Total Issues: 1
+CannotRemoveBaseTypeOrInterface : Type 'Avalonia.Themes.Fluent.FluentTheme' does not inherit from base type 'Avalonia.Styling.Styles' in the implementation but it does in the contract.
+MembersMustExist : Member 'public void Avalonia.Themes.Fluent.FluentTheme..ctor()' does not exist in the implementation but it does exist in the contract.
+Total Issues: 2

+ 114 - 0
src/Avalonia.Themes.Fluent/FluentTheme.cs

@@ -0,0 +1,114 @@
+using System;
+using System.Collections.Generic;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using Avalonia.Styling;
+
+#nullable enable
+
+namespace Avalonia.Themes.Fluent
+{
+    public enum FluentThemeMode
+    {
+        Light,
+        Dark,
+    }
+
+    /// <summary>
+    /// Includes the fluent theme in an application.
+    /// </summary>
+    public class FluentTheme : IStyle, IResourceProvider
+    {
+        private readonly Uri _baseUri;
+        private IStyle[]? _loaded;
+        private bool _isLoading;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="FluentTheme"/> class.
+        /// </summary>
+        /// <param name="baseUri">The base URL for the XAML context.</param>
+        public FluentTheme(Uri baseUri)
+        {
+            _baseUri = baseUri;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="FluentTheme"/> class.
+        /// </summary>
+        /// <param name="serviceProvider">The XAML service provider.</param>
+        public FluentTheme(IServiceProvider serviceProvider)
+        {
+            _baseUri = ((IUriContext)serviceProvider.GetService(typeof(IUriContext))).BaseUri;
+        }
+
+        /// <summary>
+        /// Gets or sets the mode of the fluent theme (light, dark).
+        /// </summary>
+        public FluentThemeMode Mode { get; set; }
+
+        public IResourceHost? Owner => (Loaded as IResourceProvider)?.Owner;
+
+        /// <summary>
+        /// Gets the loaded style.
+        /// </summary>
+        public IStyle Loaded
+        {
+            get
+            {
+                if (_loaded == null)
+                {
+                    _isLoading = true;
+                    var loaded = (IStyle)AvaloniaXamlLoader.Load(GetUri(), _baseUri);
+                    _loaded = new[] { loaded };
+                    _isLoading = false;
+                }
+
+                return _loaded?[0]!;
+            }
+        }
+
+        bool IResourceNode.HasResources => (Loaded as IResourceProvider)?.HasResources ?? false;
+
+        IReadOnlyList<IStyle> IStyle.Children => _loaded ?? Array.Empty<IStyle>();
+
+        public event EventHandler OwnerChanged
+        {
+            add
+            {
+                if (Loaded is IResourceProvider rp)
+                {
+                    rp.OwnerChanged += value;
+                }
+            }
+            remove
+            {
+                if (Loaded is IResourceProvider rp)
+                {
+                    rp.OwnerChanged -= value;
+                }
+            }
+        }
+
+        public SelectorMatchResult TryAttach(IStyleable target, IStyleHost? host) => Loaded.TryAttach(target, host);
+
+        public bool TryGetResource(object key, out object? value)
+        {
+            if (!_isLoading && Loaded is IResourceProvider p)
+            {
+                return p.TryGetResource(key, out value);
+            }
+
+            value = null;
+            return false;
+        }
+
+        void IResourceProvider.AddOwner(IResourceHost owner) => (Loaded as IResourceProvider)?.AddOwner(owner);
+        void IResourceProvider.RemoveOwner(IResourceHost owner) => (Loaded as IResourceProvider)?.RemoveOwner(owner);
+
+        private Uri GetUri() => Mode switch
+        {
+            FluentThemeMode.Dark => new Uri("avares://Avalonia.Themes.Fluent/FluentDark.xaml", UriKind.Absolute),
+            _ => new Uri("avares://Avalonia.Themes.Fluent/FluentLight.xaml", UriKind.Absolute),
+        };
+    }
+}

+ 3 - 0
src/Avalonia.Themes.Fluent/Properties/AssemblyInfo.cs

@@ -0,0 +1,3 @@
+using Avalonia.Metadata;
+
+[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Themes.Fluent")]

+ 35 - 6
src/Windows/Avalonia.Win32/ClipboardImpl.cs

@@ -12,10 +12,17 @@ namespace Avalonia.Win32
 {
     internal class ClipboardImpl : IClipboard
     {
+        private const int OleRetryCount = 10;
+        private const int OleRetryDelay = 100;
+
         private async Task<IDisposable> OpenClipboard()
         {
+            var i = OleRetryCount;
+
             while (!UnmanagedMethods.OpenClipboard(IntPtr.Zero))
             {
+                if (--i == 0)
+                    throw new TimeoutException("Timeout opening clipboard.");
                 await Task.Delay(100);
             }
 
@@ -72,20 +79,32 @@ namespace Avalonia.Win32
         {
             Dispatcher.UIThread.VerifyAccess();
             var wrapper = new DataObject(data);
+            var i = OleRetryCount;
+
             while (true)
             {
-                if (UnmanagedMethods.OleSetClipboard(wrapper) == 0)
+                var hr = UnmanagedMethods.OleSetClipboard(wrapper);
+
+                if (hr == 0)
                     break;
-                await Task.Delay(100);
+
+                if (--i == 0)
+                    Marshal.ThrowExceptionForHR(hr);
+                
+                await Task.Delay(OleRetryDelay);
             }
         }
 
         public async Task<string[]> GetFormatsAsync()
         {
             Dispatcher.UIThread.VerifyAccess();
+            var i = OleRetryCount;
+
             while (true)
             {
-                if (UnmanagedMethods.OleGetClipboard(out var dataObject) == 0)
+                var hr = UnmanagedMethods.OleGetClipboard(out var dataObject);
+
+                if (hr == 0)
                 {
                     var wrapper = new OleDataObject(dataObject);
                     var formats = wrapper.GetDataFormats().ToArray();
@@ -93,16 +112,23 @@ namespace Avalonia.Win32
                     return formats;
                 }
 
-                await Task.Delay(100);
+                if (--i == 0)
+                    Marshal.ThrowExceptionForHR(hr);
+
+                await Task.Delay(OleRetryDelay);
             }
         }
 
         public async Task<object> GetDataAsync(string format)
         {
             Dispatcher.UIThread.VerifyAccess();
+            var i = OleRetryCount;
+
             while (true)
             {
-                if (UnmanagedMethods.OleGetClipboard(out var dataObject) == 0)
+                var hr = UnmanagedMethods.OleGetClipboard(out var dataObject);
+
+                if (hr == 0)
                 {
                     var wrapper = new OleDataObject(dataObject);
                     var rv = wrapper.Get(format);
@@ -110,7 +136,10 @@ namespace Avalonia.Win32
                     return rv;
                 }
 
-                await Task.Delay(100);
+                if (--i == 0)
+                    Marshal.ThrowExceptionForHR(hr);
+
+                await Task.Delay(OleRetryDelay);
             }
         }
     }

+ 1 - 0
tests/Avalonia.Animation.UnitTests/Avalonia.Animation.UnitTests.csproj

@@ -10,6 +10,7 @@
   <Import Project="..\..\build\XUnit.props" />
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
   <ItemGroup>
     <ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj" />
     <ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj" />

+ 2 - 1
tests/Avalonia.Base.UnitTests/Avalonia.Base.UnitTests.csproj

@@ -10,6 +10,7 @@
   <Import Project="..\..\build\XUnit.props" />
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
   <ItemGroup>
     <ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj" />
     <ProjectReference Include="..\Avalonia.UnitTests\Avalonia.UnitTests.csproj" />
@@ -17,4 +18,4 @@
   <ItemGroup>
     <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
   </ItemGroup>
-</Project>
+</Project>

+ 1 - 0
tests/Avalonia.Controls.DataGrid.UnitTests/Avalonia.Controls.DataGrid.UnitTests.csproj

@@ -12,6 +12,7 @@
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
   <Import Project="..\..\build\Base.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
   <ItemGroup>
     <ProjectReference Include="..\..\src\Avalonia.Controls.DataGrid\Avalonia.Controls.DataGrid.csproj" />
     <ProjectReference Include="..\Avalonia.UnitTests\Avalonia.UnitTests.csproj" />

+ 1 - 0
tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj

@@ -12,6 +12,7 @@
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
   <Import Project="..\..\build\Base.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
   <ItemGroup>
     <ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml.Loader\Avalonia.Markup.Xaml.Loader.csproj" />
     <ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />

+ 1 - 0
tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj

@@ -27,4 +27,5 @@
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\XUnit.props" />
   <Import Project="..\..\build\Magick.NET-Q16-AnyCPU.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
 </Project>

+ 2 - 1
tests/Avalonia.Direct2D1.UnitTests/Avalonia.Direct2D1.UnitTests.csproj

@@ -7,6 +7,7 @@
   <Import Project="..\..\build\XUnit.props" />
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
   <ItemGroup>
     <EmbeddedResource Include="..\Avalonia.RenderTests\**\*.ttf" />
   </ItemGroup>
@@ -22,4 +23,4 @@
     <ProjectReference Include="..\Avalonia.UnitTests\Avalonia.UnitTests.csproj" />
     <ProjectReference Include="..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" />
   </ItemGroup>
-</Project>
+</Project>

+ 1 - 0
tests/Avalonia.Layout.UnitTests/Avalonia.Layout.UnitTests.csproj

@@ -8,6 +8,7 @@
   <Import Project="..\..\build\XUnit.props" />
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
   <ItemGroup>
     <ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj" />
     <ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj" />

+ 2 - 1
tests/Avalonia.LeakTests/Avalonia.LeakTests.csproj

@@ -7,6 +7,7 @@
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\XUnit.props" />
   <Import Project="..\..\build\NetFX.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
   <ItemGroup>
     <ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />
     <ProjectReference Include="..\..\src\Markup\Avalonia.Markup\Avalonia.Markup.csproj" />
@@ -25,4 +26,4 @@
   <ItemGroup>
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
-</Project>
+</Project>

+ 1 - 0
tests/Avalonia.Markup.UnitTests/Avalonia.Markup.UnitTests.csproj

@@ -10,6 +10,7 @@
   <Import Project="..\..\build\XUnit.props" />
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
   <ItemGroup>
     <ProjectReference Include="..\..\src\Markup\Avalonia.Markup\Avalonia.Markup.csproj" />
     <ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj" />

+ 1 - 0
tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj

@@ -10,6 +10,7 @@
   <Import Project="..\..\build\XUnit.props" />
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
   <ItemGroup>
     <ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml.Loader\Avalonia.Markup.Xaml.Loader.csproj" />
     <ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />

+ 1 - 0
tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj

@@ -29,4 +29,5 @@
   <Import Project="..\..\build\XUnit.props" />
   <Import Project="..\..\build\Magick.NET-Q16-AnyCPU.props" />
   <Import Project="..\..\build\SkiaSharp.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
 </Project>

+ 2 - 1
tests/Avalonia.Skia.UnitTests/Avalonia.Skia.UnitTests.csproj

@@ -8,6 +8,7 @@
   <Import Project="..\..\build\XUnit.props" />
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
   <ItemGroup>
     <EmbeddedResource Include="..\Avalonia.RenderTests\**\*.ttf" />
   </ItemGroup>
@@ -23,4 +24,4 @@
     <ProjectReference Include="..\..\src\Skia\Avalonia.Skia\Avalonia.Skia.csproj" />
     <ProjectReference Include="..\Avalonia.UnitTests\Avalonia.UnitTests.csproj" />
   </ItemGroup>
-</Project>
+</Project>

+ 1 - 0
tests/Avalonia.Styling.UnitTests/Avalonia.Styling.UnitTests.csproj

@@ -11,6 +11,7 @@
   <Import Project="..\..\build\XUnit.props" />
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
   <ItemGroup>
     <ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj" />
     <ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj" />

+ 1 - 0
tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj

@@ -28,4 +28,5 @@
   <Import Project="..\..\src\Shared\PlatformSupport\PlatformSupport.projitems" Label="Shared" />
   <Import Project="..\..\build\Moq.props" />
   <Import Project="..\..\build\Rx.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
 </Project>

+ 1 - 0
tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj

@@ -13,6 +13,7 @@
   <Import Project="..\..\build\XUnit.props" />
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
+  <Import Project="..\..\build\SharedVersion.props" />
   <ItemGroup>
     <EmbeddedResource Remove="..\Avalonia.RenderTests\Assets\NotoColorEmoji.ttf" />
   </ItemGroup>