Browse Source

Merge branch 'master' into treeview_custom_items

pull/6854/head
Steven Kirk 4 years ago
committed by GitHub
parent
commit
b595a03b03
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .gitignore
  2. 2
      .ncrunch/Avalonia.Win32.v3.ncrunchproject
  3. 144
      Avalonia.sln
  4. 25
      Documentation/build.md
  5. 1
      NuGet.Config
  6. 19
      azure-pipelines.yml
  7. 10
      build/ApiDiff.props
  8. 5
      build/HarfBuzzSharp.props
  9. 2
      build/MicroCom.targets
  10. 5
      build/SkiaSharp.props
  11. 6
      global.json
  12. 2
      native/Avalonia.Native/src/OSX/dnd.mm
  13. 24
      native/Avalonia.Native/src/OSX/window.mm
  14. 9
      nukebuild/_build.csproj
  15. 2
      packages/Avalonia/AvaloniaBuildTasks.targets
  16. 3
      readme.md
  17. 2
      samples/BindingDemo/BindingDemo.csproj
  18. 2
      samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
  19. 10
      samples/ControlCatalog.Web/App.razor
  20. 14
      samples/ControlCatalog.Web/App.razor.cs
  21. 38
      samples/ControlCatalog.Web/ControlCatalog.Web.csproj
  22. 28
      samples/ControlCatalog.Web/LinkerConfig.xml
  23. 5
      samples/ControlCatalog.Web/Pages/Index.razor
  24. 29
      samples/ControlCatalog.Web/Program.cs
  25. 30
      samples/ControlCatalog.Web/Properties/launchSettings.json
  26. 7
      samples/ControlCatalog.Web/Shared/MainLayout.razor
  27. 70
      samples/ControlCatalog.Web/Shared/MainLayout.razor.css
  28. 11
      samples/ControlCatalog.Web/_Imports.razor
  29. 90
      samples/ControlCatalog.Web/wwwroot/css/app.css
  30. BIN
      samples/ControlCatalog.Web/wwwroot/favicon.ico
  31. 23
      samples/ControlCatalog.Web/wwwroot/index.html
  32. 1
      samples/ControlCatalog.Web/wwwroot/js/app.js
  33. 9
      samples/ControlCatalog/Pages/DragAndDropPage.xaml
  34. 33
      samples/ControlCatalog/Pages/DragAndDropPage.xaml.cs
  35. 2
      samples/PlatformSanityChecks/PlatformSanityChecks.csproj
  36. 2
      samples/Previewer/Previewer.csproj
  37. 2
      samples/RemoteDemo/RemoteDemo.csproj
  38. 2
      samples/RenderDemo/RenderDemo.csproj
  39. 2
      samples/Sandbox/Sandbox.csproj
  40. 2
      samples/VirtualizationDemo/VirtualizationDemo.csproj
  41. 12
      samples/interop/WindowsInteropTest/EmbedToWinFormsDemo.cs
  42. 16
      samples/interop/WindowsInteropTest/EmbedToWpfDemo.xaml.cs
  43. 36
      samples/interop/WindowsInteropTest/Properties/AssemblyInfo.cs
  44. 186
      samples/interop/WindowsInteropTest/WindowsInteropTest.csproj
  45. 6
      src/Avalonia.Animation/Animation.cs
  46. 12
      src/Avalonia.Animation/Animators/Animator`1.cs
  47. 3
      src/Avalonia.Animation/ApiCompatBaseline.txt
  48. 2
      src/Avalonia.Base/Data/BindingValue.cs
  49. 17
      src/Avalonia.Base/Data/Converters/MethodToCommandConverter.cs
  50. 7
      src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs
  51. 52
      src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
  52. 6
      src/Avalonia.Controls/Application.cs
  53. 14
      src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs
  54. 10
      src/Avalonia.Controls/Calendar/Calendar.cs
  55. 8
      src/Avalonia.Controls/Flyouts/FlyoutBase.cs
  56. 2
      src/Avalonia.Controls/MenuItem.cs
  57. 6
      src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs
  58. 2
      src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs
  59. 4
      src/Avalonia.Controls/Platform/PlatformManager.cs
  60. 41
      src/Avalonia.Controls/Primitives/Popup.cs
  61. 3
      src/Avalonia.Controls/Remote/RemoteServer.cs
  62. 17
      src/Avalonia.Controls/Slider.cs
  63. 10
      src/Avalonia.Controls/SplitView.cs
  64. 2
      src/Avalonia.Controls/TextBoxTextInputMethodClient.cs
  65. 2
      src/Avalonia.Controls/TrayIcon.cs
  66. 1
      src/Avalonia.Controls/Window.cs
  67. 6
      src/Avalonia.Controls/WindowBase.cs
  68. 2
      src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs
  69. 25
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs
  70. 2
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs
  71. 6
      src/Avalonia.FreeDesktop/DBusMenuExporter.cs
  72. 3
      src/Avalonia.Input/ApiCompatBaseline.txt
  73. 16
      src/Avalonia.Input/FocusManager.cs
  74. 7
      src/Avalonia.Input/Gestures.cs
  75. 6
      src/Avalonia.Input/ICommandSource.cs
  76. 8
      src/Avalonia.Input/IFocusManager.cs
  77. 2
      src/Avalonia.Input/InputElement.cs
  78. 2
      src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
  79. 6
      src/Avalonia.Styling/Styling/PropertySetterInstance.cs
  80. 4
      src/Avalonia.Styling/Styling/Setter.cs
  81. 23
      src/Avalonia.Themes.Default/Expander.xaml
  82. 4
      src/Avalonia.Themes.Fluent/Controls/NumericUpDown.xaml
  83. 22
      src/Avalonia.Visuals/Matrix.cs
  84. 10
      src/Avalonia.Visuals/Media/Transformation/InterpolationUtilities.cs
  85. 5
      src/Avalonia.Visuals/Media/Transformation/TransformOperation.cs
  86. 25
      src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs
  87. 60
      src/Avalonia.X11/ICELib.cs
  88. 133
      src/Avalonia.X11/SMLib.cs
  89. 17
      src/Avalonia.X11/X11Platform.cs
  90. 259
      src/Avalonia.X11/X11PlatformLifetimeEvents.cs
  91. 4
      src/Avalonia.X11/X11Window.Xim.cs
  92. 1
      src/Avalonia.X11/X11Window.cs
  93. 6
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs
  94. 1
      src/Skia/Avalonia.Skia/Avalonia.Skia.csproj
  95. 2
      src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs
  96. 2
      src/Skia/Avalonia.Skia/SKTypefaceCollection.cs
  97. 2
      src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs
  98. BIN
      src/Web/Avalonia.Web.Blazor/Assets/NotoMono-Regular.ttf
  99. BIN
      src/Web/Avalonia.Web.Blazor/Assets/NotoSans-Italic.ttf
  100. 57
      src/Web/Avalonia.Web.Blazor/Avalonia.Web.Blazor.csproj

3
.gitignore

@ -210,3 +210,6 @@ obj-Skia/
coc-settings.json
.ccls-cache
.ccls
*.map
src/Web/Avalonia.Web.Blazor/wwwroot/*.js
src/Web/Avalonia.Web.Blazor/Interop/Typescript/*.js

2
.ncrunch/Avalonia.Win32.v3.ncrunchproject

@ -1,7 +1,7 @@
<ProjectConfiguration>
<Settings>
<AdditionalFilesToIncludeForProject>
<Value>..\..\tools\MicroComGenerator\bin\Debug\netcoreapp3.1\**.*</Value>
<Value>..\..\tools\MicroComGenerator\bin\Debug\net6.0\**.*</Value>
</AdditionalFilesToIncludeForProject>
<HiddenComponentWarnings>
<Value>MissingOrIgnoredProjectReference</Value>

144
Avalonia.sln

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29102.190
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Base", "src\Avalonia.Base\Avalonia.Base.csproj", "{B09B78D8-9B26-48B0-9149-D64A2F120F3F}"
EndProject
@ -109,8 +109,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VirtualizationDemo", "sampl
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Interop", "Interop", "{A0CC0258-D18C-4AB3-854F-7101680FC3F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsInteropTest", "samples\interop\WindowsInteropTest\WindowsInteropTest.csproj", "{C7A69145-60B6-4882-97D6-A3921DD43978}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RenderDemo", "samples\RenderDemo\RenderDemo.csproj", "{F1FDC5B0-4654-416F-AE69-E3E9BBD87801}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Android", "samples\ControlCatalog.Android\ControlCatalog.Android.csproj", "{29132311-1848-4FD6-AE0C-4FF841151BD3}"
@ -224,11 +222,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup.Xaml.Loader
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sandbox", "samples\Sandbox\Sandbox.csproj", "{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MicroComGenerator", "src\tools\MicroComGenerator\MicroComGenerator.csproj", "{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicroComGenerator", "src\tools\MicroComGenerator\MicroComGenerator.csproj", "{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.MicroCom", "src\Avalonia.MicroCom\Avalonia.MicroCom.csproj", "{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MiniMvvm", "samples\MiniMvvm\MiniMvvm.csproj", "{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web", "Web", "{86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Web.Blazor", "src\Web\Avalonia.Web.Blazor\Avalonia.Web.Blazor.csproj", "{25831348-EB2A-483E-9576-E8F6528674A5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.MicroCom", "src\Avalonia.MicroCom\Avalonia.MicroCom.csproj", "{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Web", "samples\ControlCatalog.Web\ControlCatalog.Web.csproj", "{C08E9894-AA92-426E-BF56-033E262CAD3E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiniMvvm", "samples\MiniMvvm\MiniMvvm.csproj", "{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsInteropTest", "samples\interop\WindowsInteropTest\WindowsInteropTest.csproj", "{26A98DA1-D89D-4A95-8152-349F404DA2E2}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
@ -1192,30 +1198,6 @@ Global
{FBCAF3D0-2808-4934-8E96-3F607594517B}.Release|iPhone.Build.0 = Release|Any CPU
{FBCAF3D0-2808-4934-8E96-3F607594517B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{FBCAF3D0-2808-4934-8E96-3F607594517B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.AppStore|Any CPU.Build.0 = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.AppStore|iPhone.Build.0 = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Debug|iPhone.Build.0 = Debug|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Release|Any CPU.Build.0 = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Release|iPhone.ActiveCfg = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Release|iPhone.Build.0 = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{C7A69145-60B6-4882-97D6-A3921DD43978}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{F1FDC5B0-4654-416F-AE69-E3E9BBD87801}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{F1FDC5B0-4654-416F-AE69-E3E9BBD87801}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{F1FDC5B0-4654-416F-AE69-E3E9BBD87801}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@ -2020,30 +2002,6 @@ Global
{909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhone.Build.0 = Release|Any CPU
{909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhone.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhone.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|Any CPU.Build.0 = Release|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhone.ActiveCfg = Release|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhone.Build.0 = Release|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@ -2140,6 +2098,78 @@ Global
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhone.Build.0 = Release|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.AppStore|iPhone.Build.0 = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Debug|iPhone.Build.0 = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Release|Any CPU.Build.0 = Release|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Release|iPhone.ActiveCfg = Release|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Release|iPhone.Build.0 = Release|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{25831348-EB2A-483E-9576-E8F6528674A5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.AppStore|iPhone.Build.0 = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Debug|iPhone.Build.0 = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Release|Any CPU.Build.0 = Release|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Release|iPhone.ActiveCfg = Release|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Release|iPhone.Build.0 = Release|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{C08E9894-AA92-426E-BF56-033E262CAD3E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.AppStore|iPhone.Build.0 = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Debug|iPhone.Build.0 = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Release|Any CPU.Build.0 = Release|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Release|iPhone.ActiveCfg = Release|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Release|iPhone.Build.0 = Release|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -2176,7 +2206,6 @@ Global
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{FBCAF3D0-2808-4934-8E96-3F607594517B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{A0CC0258-D18C-4AB3-854F-7101680FC3F9} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{C7A69145-60B6-4882-97D6-A3921DD43978} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9}
{F1FDC5B0-4654-416F-AE69-E3E9BBD87801} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{29132311-1848-4FD6-AE0C-4FF841151BD3} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{7D2D3083-71DD-4CC9-8907-39A0D86FB322} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
@ -2201,6 +2230,9 @@ Global
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{25831348-EB2A-483E-9576-E8F6528674A5} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}
{C08E9894-AA92-426E-BF56-033E262CAD3E} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{26A98DA1-D89D-4A95-8152-349F404DA2E2} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}

25
Documentation/build.md

@ -1,6 +1,6 @@
# Windows
Avalonia requires at least Visual Studio 2019 and .NET Core SDK 3.1 to build on Windows.
Avalonia requires at least Visual Studio 2022 and dotnet 6 SDK 6.0.100 to build on all platforms.
### Clone the Avalonia repository
@ -16,7 +16,7 @@ Go to https://dotnet.microsoft.com/download/visual-studio-sdks and install the l
### Open in Visual Studio
Open the `Avalonia.sln` solution in Visual Studio 2019 or newer. The free Visual Studio Community edition works fine. Build and run the `Samples\ControlCatalog.Desktop` or `ControlCatalog.NetCore` project to see the sample application.
Open the `Avalonia.sln` solution in Visual Studio 2022 or newer. The free Visual Studio Community edition works fine. Build and run the `Samples\ControlCatalog.Desktop` or `ControlCatalog.NetCore` project to see the sample application.
### Troubleshooting
@ -43,27 +43,6 @@ Go to https://www.microsoft.com/net/core and follow the instructions for your OS
The build process needs [Xcode](https://developer.apple.com/xcode/) to build the native library. Following the install instructions at the [Xcode](https://developer.apple.com/xcode/) website to properly install.
Linux operating systems ship with their own respective package managers however we will use [Homebrew](https://brew.sh/) to manage packages on macOS. To install follow the instructions [here](https://docs.brew.sh/Installation).
### Install CastXML (pre Nov 2020)
Avalonia requires [CastXML](https://github.com/CastXML/CastXML) for XML processing during the build process. The easiest way to install this is via the operating system's package managers, such as below.
On macOS:
```
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/8a004a91a7fcd3f6620d5b01b6541ff0a640ffba/Formula/castxml.rb
```
On Debian based Linux (Debian, Ubuntu, Mint, etc):
```
sudo apt install castxml
```
On Red Hat based Linux (Fedora, CentOS, RHEL, etc) using `yum` (`dnf` takes same arguments though):
```
sudo yum install castxml
```
### Clone the Avalonia repository

1
NuGet.Config

@ -5,5 +5,6 @@
<clear />
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="dotnet-eng" value="https://nuget.avaloniaui.net/repository/avalonia-devdeps/index.json" protocolVersion="3" />
<add key="skiasharp" value="https://aka.ms/skiasharp-eap/index.json" protocolVersion="3" />
</packageSources>
</configuration>

19
azure-pipelines.yml

@ -1,3 +1,6 @@
variables:
MSBuildEnableWorkloadResolver: 'false'
jobs:
- job: Linux
pool:
@ -9,9 +12,9 @@ jobs:
version: 3.1.414
- task: UseDotNet@2
displayName: 'Use .NET Core SDK 5.0.402'
displayName: 'Use .NET Core SDK 6.0.100'
inputs:
version: 5.0.402
version: 6.0.100
- task: CmdLine@2
displayName: 'Run Build'
@ -40,9 +43,9 @@ jobs:
version: 3.1.414
- task: UseDotNet@2
displayName: 'Use .NET Core SDK 5.0.402'
displayName: 'Use .NET Core SDK 6.0.100'
inputs:
version: 5.0.402
version: 6.0.100
- task: CmdLine@2
displayName: 'Install Mono 5.18'
@ -56,7 +59,7 @@ jobs:
inputs:
script: |
export PATH="`pwd`/sdk:$PATH"
cd src/tools/MicroComGenerator; dotnet run -i ../../Avalonia.Native/avn.idl --cpp ../../../native/Avalonia.Native/inc/avalonia-native.h
cd src/tools/MicroComGenerator; dotnet run -f net6.0 -i ../../Avalonia.Native/avn.idl --cpp ../../../native/Avalonia.Native/inc/avalonia-native.h
- task: Xcode@5
inputs:
@ -100,7 +103,7 @@ jobs:
- job: Windows
pool:
vmImage: 'windows-2019'
vmImage: 'windows-2022'
variables:
SolutionDir: '$(Build.SourcesDirectory)'
steps:
@ -110,9 +113,9 @@ jobs:
version: 3.1.414
- task: UseDotNet@2
displayName: 'Use .NET Core SDK 5.0.402'
displayName: 'Use .NET Core SDK 6.0.100'
inputs:
version: 5.0.402
version: 6.0.100
- task: CmdLine@2
displayName: 'Install Nuke'

10
build/ApiDiff.props

@ -4,9 +4,9 @@
<NugetPackageName Condition="'$(PackageId)' != ''">$(PackageId)</NugetPackageName>
<NugetPackageName Condition="'$(PackageId)' == ''">Avalonia</NugetPackageName>
</PropertyGroup>
<ItemGroup>
<PackageDownload Include="$(NugetPackageName)" Version="[$(ApiContractPackageVersion)]" />
<PackageReference Include="Microsoft.DotNet.ApiCompat" Version="5.0.0-beta.20372.2" PrivateAssets="All" />
<ResolvedMatchingContract Include="$(NuGetPackageRoot)\$(NugetPackageName.ToLowerInvariant())\$(ApiContractPackageVersion)\lib\$(TargetFramework)\$(AssemblyName).dll" />
</ItemGroup>
<ItemGroup>
<PackageDownload Include="$(NugetPackageName)" Version="[$(ApiContractPackageVersion)]" />
<PackageReference Include="Microsoft.DotNet.ApiCompat" Version="5.0.0-beta.20372.2" PrivateAssets="All" />
<ResolvedMatchingContract Include="$(NuGetPackageRoot)\$(NugetPackageName.ToLowerInvariant())\$(ApiContractPackageVersion)\lib\$(TargetFramework)\$(AssemblyName).dll" />
</ItemGroup>
</Project>

5
build/HarfBuzzSharp.props

@ -1,6 +1,7 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="HarfBuzzSharp" Version="2.6.1.7" />
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.6.1.7" />
<PackageReference Include="HarfBuzzSharp" Version="2.8.2-preview.171" />
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.8.2-preview.171" />
<PackageReference Condition="'$(IncludeWasmSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.WebAssembly" Version="2.8.2-preview.171"/>
</ItemGroup>
</Project>

2
build/MicroCom.targets

@ -15,7 +15,7 @@
Inputs="@(AvnComIdl);$(MSBuildThisFileDirectory)../src/tools/MicroComGenerator/**/*.cs"
Outputs="%(AvnComIdl.OutputFile)">
<Message Importance="high" Text="Generating file %(AvnComIdl.OutputFile) from @(AvnComIdl)" />
<Exec Command="dotnet &quot;$(MSBuildThisFileDirectory)../src/tools/MicroComGenerator/bin/$(Configuration)/netcoreapp3.1/MicroComGenerator.dll&quot; -i @(AvnComIdl) --cs %(AvnComIdl.OutputFile)"
<Exec Command="dotnet &quot;$(MSBuildThisFileDirectory)../src/tools/MicroComGenerator/bin/$(Configuration)/net6.0/MicroComGenerator.dll&quot; -i @(AvnComIdl) --cs %(AvnComIdl.OutputFile)"
LogStandardErrorAsError="true" />
<ItemGroup>
<!-- Remove and re-add generated file, this is needed for the clean build -->

5
build/SkiaSharp.props

@ -1,6 +1,7 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="SkiaSharp" Version="2.80.2" />
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="SkiaSharp.NativeAssets.Linux" Version="2.80.2" />
<PackageReference Include="SkiaSharp" Version="2.88.0-preview.171" />
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="SkiaSharp.NativeAssets.Linux" Version="2.88.0-preview.171" />
<PackageReference Condition="'$(IncludeWasmSkia)' == 'true'" Include="SkiaSharp.NativeAssets.WebAssembly" Version="2.88.0-preview.171"/>
</ItemGroup>
</Project>

6
global.json

@ -1,7 +1,7 @@
{
"sdk": {
"version": "5.0.402"
},
"sdk": {
"version": "6.0.100"
},
"msbuild-sdks": {
"Microsoft.Build.Traversal": "1.0.43",
"MSBuild.Sdk.Extras": "2.0.54",

2
native/Avalonia.Native/src/OSX/dnd.mm

@ -32,7 +32,7 @@ extern NSString* GetAvnCustomDataType()
- (NSDragOperation)draggingSession:(nonnull NSDraggingSession *)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context
{
return NSDragOperationCopy;
return _operation;
}
- (AvnDndSource*) initWithOperation: (NSDragOperation)operation

24
native/Avalonia.Native/src/OSX/window.mm

@ -206,7 +206,11 @@ public:
auto window = Window;
Window = nullptr;
[window close];
try{
// Seems to throw sometimes on application exit.
[window close];
}
catch(NSException*){}
}
return S_OK;
@ -724,6 +728,7 @@ private:
if (cparent->WindowState() == Minimized)
cparent->SetWindowState(Normal);
[Window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
[cparent->Window addChildWindow:Window ordered:NSWindowAbove];
UpdateStyle();
@ -1489,7 +1494,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
NSRect rect = NSZeroRect;
rect.size = newSize;
NSTrackingAreaOptions options = NSTrackingActiveAlways | NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag;
NSTrackingAreaOptions options = NSTrackingActiveAlways | NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingEnabledDuringMouseDrag;
_area = [[NSTrackingArea alloc] initWithRect:rect options:options owner:self userInfo:nullptr];
[self addTrackingArea:_area];
@ -2398,11 +2403,18 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
{
case NSEventTypeLeftMouseDown:
{
auto avnPoint = [AvnView toAvnPoint:[event locationInWindow]];
auto point = [self translateLocalPoint:avnPoint];
AvnVector delta;
AvnView* view = _parent->View;
NSPoint windowPoint = [event locationInWindow];
NSPoint viewPoint = [view convertPoint:windowPoint fromView:nil];
_parent->BaseEvents->RawMouseEvent(NonClientLeftButtonDown, [event timestamp] * 1000, AvnInputModifiersNone, point, delta);
if (!NSPointInRect(viewPoint, view.bounds))
{
auto avnPoint = [AvnView toAvnPoint:windowPoint];
auto point = [self translateLocalPoint:avnPoint];
AvnVector delta;
_parent->BaseEvents->RawMouseEvent(NonClientLeftButtonDown, [event timestamp] * 1000, AvnInputModifiersNone, point, delta);
}
}
break;

9
nukebuild/_build.csproj

@ -15,6 +15,7 @@
<PackageReference Include="JetBrains.dotMemoryUnit" Version="3.0.20171219.105559" />
<PackageReference Include="vswhere" Version="2.6.7" Condition=" '$(OS)' == 'Windows_NT' " />
<PackageReference Include="ILRepack.NETStandard" Version="2.0.4" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.7.0" />
<!-- Keep in sync with Avalonia.Build.Tasks -->
<PackageReference Include="Mono.Cecil" Version="0.11.2" />
</ItemGroup>
@ -36,10 +37,10 @@
<None Include="..\GitVersion.yml" Condition="Exists('..\GitVersion.yml')" />
<Compile Remove="Numerge/**/*.*" />
<Compile Include="Numerge/Numerge/**/*.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\src\tools\MicroComGenerator\MicroComGenerator.csproj" />
<Compile Include="..\src\tools\MicroComGenerator\**\*.cs" Exclude="..\src\tools\MicroComGenerator\obj\**">
<Link>MicroComGenerator\%(Filename)%(Extension)</Link>
</Compile>
<Compile Remove="..\src\tools\MicroComGenerator\Program.cs" />
</ItemGroup>
</Project>

2
packages/Avalonia/AvaloniaBuildTasks.targets

@ -88,6 +88,7 @@
<AvaloniaXamlReferencesTemporaryFilePath Condition="'$(AvaloniaXamlReferencesTemporaryFilePath)' == ''">$(IntermediateOutputPath)/Avalonia/references</AvaloniaXamlReferencesTemporaryFilePath>
<AvaloniaXamlOriginalCopyFilePath Condition="'$(AvaloniaXamlOriginalCopyFilePath)' == ''">$(IntermediateOutputPath)/Avalonia/original.dll</AvaloniaXamlOriginalCopyFilePath>
<AvaloniaXamlIlVerifyIl Condition="'$(AvaloniaXamlIlVerifyIl)' == ''">false</AvaloniaXamlIlVerifyIl>
<AvaloniaXamlIlDebuggerLaunch Condition="'$(AvaloniaXamlIlDebuggerLaunch)' == ''">false</AvaloniaXamlIlDebuggerLaunch>
</PropertyGroup>
<WriteLinesToFile
Condition="'$(_AvaloniaForceInternalMSBuild)' != 'true'"
@ -107,6 +108,7 @@
DelaySign="$(DelaySign)"
EnableComInteropPatching="$(_AvaloniaPatchComInterop)"
SkipXamlCompilation="$(_AvaloniaSkipXamlCompilation)"
DebuggerLaunch="$(AvaloniaXamlIlDebuggerLaunch)"
/>
<Exec
Condition="'$(_AvaloniaUseExternalMSBuild)' == 'true'"

3
readme.md

@ -93,7 +93,8 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
<a href="https://opencollective.com/Avalonia/sponsor/6/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/Avalonia/sponsor/7/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/Avalonia/sponsor/8/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/Avalonia/sponsor/9/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/9/avatar.svg"></a>
<a href="https://opencollective.com/Avalonia/sponsor/9/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/9/avatar.svg"></a>
<a href="https://baseheadinc.com/" target="_blank"><img height="50" src="https://baseheadinc.com/wp-content/uploads/2020/09/BH-Logo-for-Site-Header-New.png"></a>
## .NET Foundation

2
samples/BindingDemo/BindingDemo.csproj

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />

2
samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
</PropertyGroup>

10
samples/ControlCatalog.Web/App.razor

@ -0,0 +1,10 @@
<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>

14
samples/ControlCatalog.Web/App.razor.cs

@ -0,0 +1,14 @@
using Avalonia.Web.Blazor;
namespace ControlCatalog.Web;
public partial class App
{
protected override void OnParametersSet()
{
WebAppBuilder.Configure<ControlCatalog.App>()
.SetupWithSingleViewLifetime();
base.OnParametersSet();
}
}

38
samples/ControlCatalog.Web/ControlCatalog.Web.csproj

@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<BlazorLinkerDescriptor Include="LinkerConfig.xml" />
</ItemGroup>
<!-- In debug, make builds faster by reducing optimizations -->
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<WasmNativeStrip>false</WasmNativeStrip>
<EmccCompileOptimizationFlag>-O1</EmccCompileOptimizationFlag>
<RunAOTCompilation>false</RunAOTCompilation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<Optimize>true</Optimize>
<WasmNativeStrip>true</WasmNativeStrip>
<EmccCompileOptimizationFlag>-O3</EmccCompileOptimizationFlag>
<EmccLinkOptimizationFlag>-O3</EmccLinkOptimizationFlag>
<RunAOTCompilation>false</RunAOTCompilation>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.0"/>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.0" PrivateAssets="all"/>
</ItemGroup>
<Import Project="..\..\src\Web\Avalonia.Web.Blazor\Avalonia.Web.Blazor.targets" />
<ItemGroup>
<ProjectReference Include="..\..\src\Web\Avalonia.Web.Blazor\Avalonia.Web.Blazor.csproj"/>
<ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj"/>
</ItemGroup>
</Project>

28
samples/ControlCatalog.Web/LinkerConfig.xml

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
This file specifies which parts of the BCL or Blazor packages must not be
stripped by the IL Linker even if they aren't referenced by user code.
-->
<linker>
<assembly fullname="mscorlib">
<!--
Preserve the methods in WasmRuntime because its methods are called by
JavaScript client-side code to implement timers.
Fixes: https://github.com/dotnet/blazor/issues/239
-->
<type fullname="System.Threading.WasmRuntime"/>
</assembly>
<assembly fullname="System.Core">
<!--
System.Linq.Expressions* is required by Json.NET and any
expression.Compile caller. The assembly isn't stripped.
-->
<type fullname="System.Linq.Expressions*"/>
</assembly>
<!--
In this example, the app's entry point assembly is listed. The assembly
isn't stripped by the IL Linker.
-->
<assembly fullname="ControlCatalog" preserve="All" />
</linker>

5
samples/ControlCatalog.Web/Pages/Index.razor

@ -0,0 +1,5 @@
@page "/"
@using Avalonia.Web.Blazor
<AvaloniaView />

29
samples/ControlCatalog.Web/Program.cs

@ -0,0 +1,29 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
using ControlCatalog.Web;
public class Program
{
public static async Task Main(string[] args)
{
await CreateHostBuilder(args).Build().RunAsync();
}
public static WebAssemblyHostBuilder CreateHostBuilder(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
return builder;
}
}

30
samples/ControlCatalog.Web/Properties/launchSettings.json

@ -0,0 +1,30 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:13961",
"sslPort": 44319
}
},
"profiles": {
"ControlCatalog.Web - IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"ControlCatalog.Web": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

7
samples/ControlCatalog.Web/Shared/MainLayout.razor

@ -0,0 +1,7 @@
@inherits LayoutComponentBase
<div class="page">
<div class="main">
@Body
</div>
</div>

70
samples/ControlCatalog.Web/Shared/MainLayout.razor.css

@ -0,0 +1,70 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}
.main {
flex: 1;
}
.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}
.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}
.top-row ::deep a, .top-row .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
}
.top-row a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 640.98px) {
.top-row:not(.auth) {
display: none;
}
.top-row.auth {
justify-content: space-between;
}
.top-row a, .top-row .btn-link {
margin-left: 0;
}
}
@media (min-width: 641px) {
.page {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.top-row {
position: sticky;
top: 0;
z-index: 1;
}
.main > div {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}

11
samples/ControlCatalog.Web/_Imports.razor

@ -0,0 +1,11 @@
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using ControlCatalog.Web
@using ControlCatalog.Web.Shared
@using SkiaSharp

90
samples/ControlCatalog.Web/wwwroot/css/app.css

@ -0,0 +1,90 @@
html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
margin: 0;
height: 100vh;
overflow: hidden;
touch-action: none;
}
a, .btn-link {
color: #0366d6;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.content {
padding-top: 1.1rem;
}
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;
}
.invalid {
outline: 1px solid red;
}
.validation-message {
color: red;
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}
.canvas-container {
opacity:1;
background-color:#ccc;
position:fixed;
width:100%;
height:100%;
top:0px;
left:0px;
z-index:500;
}
canvas
{
opacity:1;
background-color:#ccc;
position:fixed;
width:100%;
height:100%;
top:0px;
left:0px;
z-index:500;
}
#app, .page {
height: 100%;
}
.overlay{
opacity:0.0;
background-color:#ccc;
position:fixed;
width:100vw;
height:100vh;
top:0px;
left:0px;
z-index:1000;
}

BIN
samples/ControlCatalog.Web/wwwroot/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

23
samples/ControlCatalog.Web/wwwroot/index.html

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Avalonia Sample</title>
<base href="/" />
<link href="css/app.css" rel="stylesheet" />
</head>
<body>
<div id="app">Powered by Avalonia</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="js/app.js"></script>
<script src="_framework/blazor.webassembly.js"></script>
</body>
</html>

1
samples/ControlCatalog.Web/wwwroot/js/app.js

@ -0,0 +1 @@


9
samples/ControlCatalog/Pages/DragAndDropPage.xaml

@ -16,11 +16,16 @@
<Border BorderBrush="{DynamicResource SystemAccentColor}" BorderThickness="2" Padding="16" Name="DragMeCustom">
<TextBlock Name="DragStateCustom">Drag Me (custom)</TextBlock>
</Border>
<TextBlock Name="DropState"></TextBlock>
</StackPanel>
<Border Background="{DynamicResource SystemAccentColorDark1}" Padding="16"
DragDrop.AllowDrop="True">
<TextBlock Name="DropState">Drop some text or files here</TextBlock>
DragDrop.AllowDrop="True" Name="CopyTarget">
<TextBlock>Drop some text or files here (Copy)</TextBlock>
</Border>
<Border Background="{DynamicResource SystemAccentColorDark1}" Padding="16"
DragDrop.AllowDrop="True" Name="MoveTarget">
<TextBlock>Drop some text or files here (Move)</TextBlock>
</Border>
</StackPanel>
</StackPanel>

33
samples/ControlCatalog/Pages/DragAndDropPage.xaml.cs

@ -21,12 +21,12 @@ namespace ControlCatalog.Pages
int textCount = 0;
SetupDnd("Text", d => d.Set(DataFormats.Text,
$"Text was dragged {++textCount} times"));
$"Text was dragged {++textCount} times"), DragDropEffects.Copy | DragDropEffects.Move | DragDropEffects.Link);
SetupDnd("Custom", d => d.Set(CustomFormat, "Test123"));
SetupDnd("Custom", d => d.Set(CustomFormat, "Test123"), DragDropEffects.Move);
}
void SetupDnd(string suffix, Action<DataObject> factory, DragDropEffects effects = DragDropEffects.Copy)
void SetupDnd(string suffix, Action<DataObject> factory, DragDropEffects effects)
{
var dragMe = this.Find<Border>("DragMe" + suffix);
var dragState = this.Find<TextBlock>("DragState"+suffix);
@ -36,9 +36,12 @@ namespace ControlCatalog.Pages
var dragData = new DataObject();
factory(dragData);
var result = await DragDrop.DoDragDrop(e, dragData, DragDropEffects.Copy);
var result = await DragDrop.DoDragDrop(e, dragData, effects);
switch (result)
{
case DragDropEffects.Move:
dragState.Text = "Data was moved";
break;
case DragDropEffects.Copy:
dragState.Text = "Data was copied";
break;
@ -48,13 +51,22 @@ namespace ControlCatalog.Pages
case DragDropEffects.None:
dragState.Text = "The drag operation was canceled";
break;
default:
dragState.Text = "Unknown result";
break;
}
}
void DragOver(object sender, DragEventArgs e)
{
// Only allow Copy or Link as Drop Operations.
e.DragEffects = e.DragEffects & (DragDropEffects.Copy | DragDropEffects.Link);
if (e.Source is Control c && c.Name == "MoveTarget")
{
e.DragEffects = e.DragEffects & (DragDropEffects.Move);
}
else
{
e.DragEffects = e.DragEffects & (DragDropEffects.Copy);
}
// Only allow if the dragged data contains text or filenames.
if (!e.Data.Contains(DataFormats.Text)
@ -65,6 +77,15 @@ namespace ControlCatalog.Pages
void Drop(object sender, DragEventArgs e)
{
if (e.Source is Control c && c.Name == "MoveTarget")
{
e.DragEffects = e.DragEffects & (DragDropEffects.Move);
}
else
{
e.DragEffects = e.DragEffects & (DragDropEffects.Copy);
}
if (e.Data.Contains(DataFormats.Text))
_DropState.Text = e.Data.GetText();
else if (e.Data.Contains(DataFormats.FileNames))

2
samples/PlatformSanityChecks/PlatformSanityChecks.csproj

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>

2
samples/Previewer/Previewer.csproj

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Update="**\*.xaml.cs">

2
samples/RemoteDemo/RemoteDemo.csproj

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" />

2
samples/RenderDemo/RenderDemo.csproj

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\src\Avalonia.Visuals\Rendering\SceneGraph\LineBoundsHelper.cs" Link="LineBoundsHelper.cs" />

2
samples/Sandbox/Sandbox.csproj

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
</PropertyGroup>

2
samples/VirtualizationDemo/VirtualizationDemo.csproj

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />

12
samples/interop/WindowsInteropTest/EmbedToWinFormsDemo.cs

@ -8,16 +8,28 @@ using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Avalonia.Controls;
using Avalonia.Rendering;
using Avalonia.VisualTree;
using ControlCatalog;
namespace WindowsInteropTest
{
public partial class EmbedToWinFormsDemo : Form
{
private readonly IRenderer _renderer;
public EmbedToWinFormsDemo()
{
InitializeComponent();
avaloniaHost.Content = new MainView();
_renderer = ((TopLevel)avaloniaHost.Content.GetVisualRoot()).Renderer;
_renderer.Start();
}
protected override void OnClosed(EventArgs e)
{
_renderer.Stop();
base.OnClosed(e);
}
}
}

16
samples/interop/WindowsInteropTest/EmbedToWpfDemo.xaml.cs

@ -13,6 +13,7 @@ using System.Windows.Navigation;
using System.Windows.Shapes;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Rendering;
using Avalonia.VisualTree;
using ControlCatalog;
using Window = System.Windows.Window;
@ -24,15 +25,16 @@ namespace WindowsInteropTest
/// </summary>
public partial class EmbedToWpfDemo : Window
{
private IRenderer _renderer;
public EmbedToWpfDemo()
{
InitializeComponent();
var view = new MainView();
view.AttachedToVisualTree += delegate
{
((TopLevel) view.GetVisualRoot()).AttachDevTools();
};
Host.Content = view;
var tl = (TopLevel)view.GetVisualRoot();
tl.AttachDevTools();
_renderer = tl.Renderer;
_renderer.Start();
var btn = (Avalonia.Controls.Button) RightBtn.Content;
btn.Click += delegate
{
@ -40,5 +42,11 @@ namespace WindowsInteropTest
};
}
protected override void OnClosed(EventArgs e)
{
_renderer.Stop();
base.OnClosed(e);
}
}
}

36
samples/interop/WindowsInteropTest/Properties/AssemblyInfo.cs

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("WindowsInteropTest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WindowsInteropTest")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("c7a69145-60b6-4882-97d6-a3921dd43978")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

186
samples/interop/WindowsInteropTest/WindowsInteropTest.csproj

@ -1,189 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{C7A69145-60B6-4882-97D6-A3921DD43978}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>WindowsInteropTest</RootNamespace>
<AssemblyName>WindowsInteropTest</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFramework>net461</TargetFramework>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="EmbedToWinFormsDemo.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="EmbedToWinFormsDemo.Designer.cs">
<DependentUpon>EmbedToWinFormsDemo.cs</DependentUpon>
</Compile>
<Compile Include="EmbedToWpfDemo.xaml.cs">
<DependentUpon>EmbedToWpfDemo.xaml</DependentUpon>
</Compile>
<Compile Include="SelectorForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="SelectorForm.Designer.cs">
<DependentUpon>SelectorForm.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="EmbedToWinFormsDemo.resx">
<DependentUpon>EmbedToWinFormsDemo.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<EmbeddedResource Include="SelectorForm.resx">
<DependentUpon>SelectorForm.cs</DependentUpon>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Avalonia.Animation\Avalonia.Animation.csproj">
<Project>{d211e587-d8bc-45b9-95a4-f297c8fa5200}</Project>
<Name>Avalonia.Animation</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Avalonia.Base\Avalonia.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Name>Avalonia.Base</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Avalonia.Controls.DataGrid\Avalonia.Controls.DataGrid.csproj">
<Project>{3278f3a9-9509-4a3f-a15b-bdc8b5bff632}</Project>
<Name>Avalonia.Controls.DataGrid</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Avalonia.Controls\Avalonia.Controls.csproj">
<Project>{d2221c82-4a25-4583-9b43-d791e3f6820c}</Project>
<Name>Avalonia.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj">
<Project>{799a7bb5-3c2c-48b6-85a7-406a12c420da}</Project>
<Name>Avalonia.DesignerSupport</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Avalonia.DesktopRuntime\Avalonia.DesktopRuntime.csproj">
<Project>{878fefe0-cd14-41cb-90b0-dbcb163e8f15}</Project>
<Name>Avalonia.DesktopRuntime</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj">
<Project>{7062ae20-5dcc-4442-9645-8195bdece63e}</Project>
<Name>Avalonia.Diagnostics</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Avalonia.Input\Avalonia.Input.csproj">
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project>
<Name>Avalonia.Input</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Avalonia.Interactivity\Avalonia.Interactivity.csproj">
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project>
<Name>Avalonia.Interactivity</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Avalonia.Layout\Avalonia.Layout.csproj">
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project>
<Name>Avalonia.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Avalonia.Visuals\Avalonia.Visuals.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Name>Avalonia.Visuals</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Avalonia.Styling\Avalonia.Styling.csproj">
<Project>{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}</Project>
<Name>Avalonia.Styling</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj">
<Project>{3e10a5fa-e8da-48b1-ad44-6a5b6cb7750f}</Project>
<Name>Avalonia.Themes.Default</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj">
<Project>{3e53a01a-b331-47f3-b828-4a5717e77a24}</Project>
<Name>Avalonia.Markup.Xaml</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Markup\Avalonia.Markup\Avalonia.Markup.csproj">
<Project>{6417e941-21bc-467b-a771-0de389353ce6}</Project>
<Name>Avalonia.Markup</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Skia\Avalonia.Skia\Avalonia.Skia.csproj">
<Project>{7d2d3083-71dd-4cc9-8907-39a0d86fb322}</Project>
<Name>Avalonia.Skia</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj">
<Project>{3e908f67-5543-4879-a1dc-08eace79b3cd}</Project>
<Name>Avalonia.Direct2D1</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Windows\Avalonia.Win32.Interop\Avalonia.Win32.Interop.csproj">
<Project>{cbc4ff2f-92d4-420b-be21-9fe0b930b04e}</Project>
<Name>Avalonia.Win32.Interop</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Windows\Avalonia.Win32\Avalonia.Win32.csproj">
<Project>{811a76cf-1cf6-440f-963b-bbe31bd72a82}</Project>
<Name>Avalonia.Win32</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Windows\Avalonia.Win32.Interop\Avalonia.Win32.Interop.csproj" />
<ProjectReference Include="..\..\ControlCatalog\ControlCatalog.csproj">
<Project>{d0a739b9-3c68-4ba6-a328-41606954b6bd}</Project>
<Name>ControlCatalog</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Page Include="EmbedToWpfDemo.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<Import Project="..\..\..\build\Rx.props" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\..\build\LegacyProject.targets" />
</Project>

6
src/Avalonia.Animation/Animation.cs

@ -353,6 +353,12 @@ namespace Avalonia.Animation
return new CompositeDisposable(subscriptions);
}
/// <inheritdoc/>
public Task RunAsync(Animatable control, IClock clock = null)
{
return RunAsync(control, clock, default);
}
/// <inheritdoc/>
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;
if (firstKeyframe.isNeutral)
oldValue = neutralValue;
if (!firstKeyframe.isNeutral && firstKeyframe.Value is T firstKeyframeValue)
oldValue = firstKeyframeValue;
else
oldValue = (T)firstKeyframe.Value;
oldValue = neutralValue;
if (lastKeyframe.isNeutral)
newValue = neutralValue;
if (!lastKeyframe.isNeutral && lastKeyframe.Value is T lastKeyframeValue)
newValue = lastKeyframeValue;
else
newValue = (T)lastKeyframe.Value;
newValue = neutralValue;
if (lastKeyframe.KeySpline != null)
progress = lastKeyframe.KeySpline.GetSplineProgress(progress);

3
src/Avalonia.Animation/ApiCompatBaseline.txt

@ -1,6 +1,5 @@
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.
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.
Total Issues: 4
Total Issues: 3

2
src/Avalonia.Base/Data/BindingValue.cs

@ -247,7 +247,7 @@ namespace Avalonia.Data
UnsetValueType _ => Unset,
DoNothingType _ => DoNothing,
BindingNotification n => n.ToBindingValue().Cast<T>(),
_ => new BindingValue<T>((T)value)
_ => new BindingValue<T>((T?)value)
};
}

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

@ -140,18 +140,9 @@ namespace Avalonia.Data.Converters
);
}
Action<object> action = null;
try
{
action = Expression
.Lambda<Action<object>>(body, parameter)
.Compile();
}
catch (Exception ex)
{
throw ex;
}
return action;
return Expression
.Lambda<Action<object>>(body, parameter)
.Compile();
}
static Func<object, bool> CreateCanExecute(object target
@ -170,7 +161,7 @@ namespace Avalonia.Data.Converters
.Compile();
}
private static Expression? ConvertTarget(object? target, MethodInfo method) =>
private static Expression ConvertTarget(object target, MethodInfo method) =>
target is null ? null : Expression.Convert(Expression.Constant(target), method.DeclaringType);
internal class WeakPropertyChangedProxy

7
src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs

@ -1,9 +1,6 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using Microsoft.Build.Framework;
namespace Avalonia.Build.Tasks
@ -41,7 +38,7 @@ namespace Avalonia.Build.Tasks
File.ReadAllLines(ReferencesFilePath).Where(l => !string.IsNullOrWhiteSpace(l)).ToArray(),
ProjectDirectory, OutputPath, VerifyIl, outputImportance,
(SignAssembly && !DelaySign) ? AssemblyOriginatorKeyFile : null,
EnableComInteropPatching, SkipXamlCompilation);
EnableComInteropPatching, SkipXamlCompilation, DebuggerLaunch);
if (!res.Success)
return false;
if (!res.WrittenFile)
@ -87,5 +84,7 @@ namespace Avalonia.Build.Tasks
public IBuildEngine BuildEngine { get; set; }
public ITaskHost HostObject { get; set; }
public bool DebuggerLaunch { get; set; }
}
}

52
src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs

@ -1,13 +1,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions;
using Microsoft.Build.Framework;
using Mono.Cecil;
using Avalonia.Utilities;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using XamlX;
@ -44,16 +41,23 @@ namespace Avalonia.Build.Tasks
string projectDirectory,
string output, bool verifyIl, MessageImportance logImportance, string strongNameKey, bool patchCom,
bool skipXamlCompilation)
{
return Compile(engine, input, references, projectDirectory, output, verifyIl, logImportance, strongNameKey, patchCom, skipXamlCompilation, debuggerLaunch:false);
}
internal static CompileResult Compile(IBuildEngine engine, string input, string[] references,
string projectDirectory,
string output, bool verifyIl, MessageImportance logImportance, string strongNameKey, bool patchCom, bool skipXamlCompilation, bool debuggerLaunch)
{
var typeSystem = new CecilTypeSystem(references
.Where(r => !r.ToLowerInvariant().EndsWith("avalonia.build.tasks.dll"))
.Concat(new[] { input }), input);
var asm = typeSystem.TargetAssemblyDefinition;
if (!skipXamlCompilation)
{
var compileRes = CompileCore(engine, typeSystem, projectDirectory, verifyIl, logImportance);
var compileRes = CompileCore(engine, typeSystem, projectDirectory, verifyIl, logImportance, debuggerLaunch);
if (compileRes == null && !patchCom)
return new CompileResult(true);
if (compileRes == false)
@ -62,7 +66,7 @@ namespace Avalonia.Build.Tasks
if (patchCom)
ComInteropHelper.PatchAssembly(asm, typeSystem);
var writerParameters = new WriterParameters { WriteSymbols = asm.MainModule.HasSymbols };
if (!string.IsNullOrWhiteSpace(strongNameKey))
writerParameters.StrongNameKeyBlob = File.ReadAllBytes(strongNameKey);
@ -70,13 +74,43 @@ namespace Avalonia.Build.Tasks
asm.Write(output, writerParameters);
return new CompileResult(true, true);
}
static bool? CompileCore(IBuildEngine engine, CecilTypeSystem typeSystem,
string projectDirectory, bool verifyIl,
MessageImportance logImportance)
MessageImportance logImportance
, bool debuggerLaunch = false)
{
if (debuggerLaunch)
{
// According this https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.debugger.launch?view=net-6.0#remarks
// documentation, on not windows platform Debugger.Launch() always return true without running a debugger.
if (System.Diagnostics.Debugger.Launch())
{
// Set timeout at 1 minut.
var time = new System.Diagnostics.Stopwatch();
var timeout = TimeSpan.FromMinutes(1);
time.Start();
// wait for the debugger to be attacked or timeout.
while (!System.Diagnostics.Debugger.IsAttached && time.Elapsed < timeout)
{
engine.LogMessage($"[PID:{System.Diagnostics.Process.GetCurrentProcess().Id}] Wating attach debugger. Elapsed {time.Elapsed}...", MessageImportance.High);
System.Threading.Thread.Sleep(100);
}
time.Stop();
if (time.Elapsed >= timeout)
{
engine.LogMessage("Wating attach debugger timeout.", MessageImportance.Normal);
}
}
else
{
engine.LogMessage("Debugging cancelled.", MessageImportance.Normal);
}
}
var asm = typeSystem.TargetAssemblyDefinition;
var emres = new EmbeddedResources(asm);
var avares = new AvaloniaResources(asm, projectDirectory);

6
src/Avalonia.Controls/Application.cs

@ -104,7 +104,7 @@ namespace Avalonia
/// <value>
/// The application's focus manager.
/// </value>
public IFocusManager FocusManager
public IFocusManager? FocusManager
{
get;
private set;
@ -116,7 +116,7 @@ namespace Avalonia
/// <value>
/// The application's input manager.
/// </value>
public InputManager InputManager
public InputManager? InputManager
{
get;
private set;
@ -175,7 +175,7 @@ namespace Avalonia
/// - <see cref="ISingleViewApplicationLifetime"/>
/// - <see cref="IControlledApplicationLifetime"/>
/// </summary>
public IApplicationLifetime ApplicationLifetime { get; set; }
public IApplicationLifetime? ApplicationLifetime { get; set; }
event Action<IReadOnlyList<IStyle>> IGlobalStyles.GlobalStylesAdded
{

14
src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
@ -122,12 +123,23 @@ namespace Avalonia.Controls.ApplicationLifetimes
lifetimeEvents.ShutdownRequested += OnShutdownRequested;
_cts = new CancellationTokenSource();
MainWindow?.Show();
// Note due to a bug in the JIT we wrap this in a method, otherwise MainWindow
// gets stuffed into a local var and can not be GCed until after the program stops.
// this method never exits until program end.
ShowMainWindow();
Dispatcher.UIThread.MainLoop(_cts.Token);
Environment.ExitCode = _exitCode;
return _exitCode;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void ShowMainWindow()
{
MainWindow?.Show();
}
public void Dispose()
{
if (_activeLifetime == this)

10
src/Avalonia.Controls/Calendar/Calendar.cs

@ -1903,6 +1903,11 @@ namespace Avalonia.Controls
}
internal void ProcessPageDownKey(bool shift)
{
if (!shift)
{
OnNextClick();
return;
}
switch (DisplayMode)
{
case CalendarMode.Month:
@ -1927,6 +1932,11 @@ namespace Avalonia.Controls
}
internal void ProcessPageUpKey(bool shift)
{
if (!shift)
{
OnPreviousClick();
return;
}
switch (DisplayMode)
{
case CalendarMode.Month:

8
src/Avalonia.Controls/Flyouts/FlyoutBase.cs

@ -22,7 +22,7 @@ namespace Avalonia.Controls.Primitives
/// <summary>
/// Defines the <see cref="IsOpen"/> property
/// </summary>
private static readonly DirectProperty<FlyoutBase, bool> IsOpenProperty =
public static readonly DirectProperty<FlyoutBase, bool> IsOpenProperty =
AvaloniaProperty.RegisterDirect<FlyoutBase, bool>(nameof(IsOpen),
x => x.IsOpen);
@ -562,8 +562,12 @@ namespace Avalonia.Controls.Primitives
return eventArgs.Cancel;
}
internal static void SetPresenterClasses(IControl presenter, Classes classes)
internal static void SetPresenterClasses(IControl? presenter, Classes classes)
{
if(presenter is null)
{
return;
}
//Remove any classes no longer in use, ignoring pseudo classes
for (int i = presenter.Classes.Count - 1; i >= 0; i--)
{

2
src/Avalonia.Controls/MenuItem.cs

@ -387,7 +387,7 @@ namespace Avalonia.Controls
parent = parent.Parent;
}
_isEmbeddedInMenu = parent is IMenu;
_isEmbeddedInMenu = parent.FindLogicalAncestorOfType<IMenu>(true) != null;
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)

6
src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs

@ -1,4 +1,5 @@
using System;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Interactivity;
@ -376,7 +377,10 @@ namespace Avalonia.Controls.Platform
{
if (item.IsSubMenuOpen)
{
if (item.IsTopLevel)
// PointerPressed events may bubble from disabled items in sub-menus. In this case,
// keep the sub-menu open.
var popup = (e.Source as ILogical)?.FindLogicalAncestorOfType<Popup>();
if (item.IsTopLevel && popup == null)
{
CloseMenu(item);
}

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

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

4
src/Avalonia.Controls/Platform/PlatformManager.cs

@ -29,7 +29,7 @@ namespace Avalonia.Controls.Platform
if (platform == null)
{
throw new Exception("Could not CreateWindow(): IWindowingPlatform is not registered.");
throw new Exception("Could not CreateTrayIcon(): IWindowingPlatform is not registered.");
}
return s_designerMode ? null : platform.CreateTrayIcon();
@ -45,7 +45,7 @@ namespace Avalonia.Controls.Platform
throw new Exception("Could not CreateWindow(): IWindowingPlatform is not registered.");
}
return s_designerMode ? (IWindowImpl)platform.CreateEmbeddableWindow() : platform.CreateWindow();
return s_designerMode ? platform.CreateEmbeddableWindow() : platform.CreateWindow();
}
public static IWindowImpl CreateEmbeddableWindow()

41
src/Avalonia.Controls/Primitives/Popup.cs

@ -8,6 +8,7 @@ using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives.PopupPositioning;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Layout;
using Avalonia.LogicalTree;
using Avalonia.Metadata;
using Avalonia.Platform;
@ -93,8 +94,8 @@ namespace Avalonia.Controls.Primitives
public static readonly StyledProperty<bool> OverlayDismissEventPassThroughProperty =
AvaloniaProperty.Register<Popup, bool>(nameof(OverlayDismissEventPassThrough));
public static readonly DirectProperty<Popup, IInputElement> OverlayInputPassThroughElementProperty =
AvaloniaProperty.RegisterDirect<Popup, IInputElement>(
public static readonly DirectProperty<Popup, IInputElement?> OverlayInputPassThroughElementProperty =
AvaloniaProperty.RegisterDirect<Popup, IInputElement?>(
nameof(OverlayInputPassThroughElement),
o => o.OverlayInputPassThroughElement,
(o, v) => o.OverlayInputPassThroughElement = v);
@ -138,7 +139,7 @@ namespace Avalonia.Controls.Primitives
private bool _isOpen;
private bool _ignoreIsOpenChanged;
private PopupOpenState? _openState;
private IInputElement _overlayInputPassThroughElement;
private IInputElement? _overlayInputPassThroughElement;
private Action<IPopupHost?>? _popupHostChangedHandler;
/// <summary>
@ -310,7 +311,7 @@ namespace Avalonia.Controls.Primitives
/// Gets or sets an element that should receive pointer input events even when underneath
/// the popup's overlay.
/// </summary>
public IInputElement OverlayInputPassThroughElement
public IInputElement? OverlayInputPassThroughElement
{
get => _overlayInputPassThroughElement;
set => SetAndRaise(OverlayInputPassThroughElementProperty, ref _overlayInputPassThroughElement, value);
@ -397,7 +398,7 @@ namespace Avalonia.Controls.Primitives
_isOpenRequested = false;
var popupHost = OverlayPopupHost.CreatePopupHost(placementTarget, DependencyResolver);
var handlerCleanup = new CompositeDisposable(5);
var handlerCleanup = new CompositeDisposable(7);
popupHost.BindConstraints(this, WidthProperty, MinWidthProperty, MaxWidthProperty,
HeightProperty, MinHeightProperty, MaxHeightProperty, TopmostProperty).DisposeWith(handlerCleanup);
@ -425,14 +426,28 @@ namespace Avalonia.Controls.Primitives
(x, handler) => x.Deactivated -= handler).DisposeWith(handlerCleanup);
SubscribeToEventHandler<IWindowImpl, Action>(window.PlatformImpl, WindowLostFocus,
(x, handler) => x.LostFocus += handler,
(x, handler) => x.LostFocus -= handler).DisposeWith(handlerCleanup);
(x, handler) => x.LostFocus += handler,
(x, handler) => x.LostFocus -= handler).DisposeWith(handlerCleanup);
SubscribeToEventHandler<IWindowImpl, Action<PixelPoint>>(window.PlatformImpl, WindowPositionChanged,
(x, handler) => x.PositionChanged += handler,
(x, handler) => x.PositionChanged -= handler).DisposeWith(handlerCleanup);
if (placementTarget is Layoutable layoutTarget)
{
// If the placement target is moved, update the popup position
SubscribeToEventHandler<Layoutable, EventHandler>(layoutTarget, PlacementTargetLayoutUpdated,
(x, handler) => x.LayoutUpdated += handler,
(x, handler) => x.LayoutUpdated -= handler).DisposeWith(handlerCleanup);
}
}
else
else if (topLevel is PopupRoot parentPopupRoot)
{
var parentPopupRoot = topLevel as PopupRoot;
SubscribeToEventHandler<PopupRoot, EventHandler<PixelPointEventArgs>>(parentPopupRoot, ParentPopupPositionChanged,
(x, handler) => x.PositionChanged += handler,
(x, handler) => x.PositionChanged -= handler).DisposeWith(handlerCleanup);
if (parentPopupRoot?.Parent is Popup popup)
if (parentPopupRoot.Parent is Popup popup)
{
SubscribeToEventHandler<Popup, EventHandler<EventArgs>>(popup, ParentClosed,
(x, handler) => x.Closed += handler,
@ -797,6 +812,12 @@ namespace Avalonia.Controls.Primitives
Close();
}
private void WindowPositionChanged(PixelPoint pp) => HandlePositionChange();
private void PlacementTargetLayoutUpdated(object src, EventArgs e) => HandlePositionChange();
private void ParentPopupPositionChanged(object src, PixelPointEventArgs e) => HandlePositionChange();
private IgnoreIsOpenScope BeginIgnoringIsOpen()
{
return new IgnoreIsOpenScope(this);

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

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

17
src/Avalonia.Controls/Slider.cs

@ -331,16 +331,17 @@ namespace Avalonia.Controls
}
}
private void MoveToPoint(PointerPoint x)
private void MoveToPoint(PointerPoint posOnTrack)
{
var orient = Orientation == Orientation.Horizontal;
var pointDen = orient ? _track.Bounds.Width : _track.Bounds.Height;
// Just add epsilon to avoid NaN in case 0/0
pointDen += double.Epsilon;
var pointNum = orient ? x.Position.X : x.Position.Y;
var logicalPos = MathUtilities.Clamp(pointNum / pointDen, 0.0d, 1.0d);
var thumbLength = (orient
? _track.Thumb.Bounds.Width
: _track.Thumb.Bounds.Height) + double.Epsilon;
var trackLength = (orient
? _track.Bounds.Width
: _track.Bounds.Height) - thumbLength;
var trackPos = orient ? posOnTrack.Position.X : posOnTrack.Position.Y;
var logicalPos = MathUtilities.Clamp((trackPos - thumbLength * 0.5) / trackLength, 0.0d, 1.0d);
var invert = orient ?
IsDirectionReversed ? 1 : 0 :
IsDirectionReversed ? 0 : 1;

10
src/Avalonia.Controls/SplitView.cs

@ -129,14 +129,14 @@ namespace Avalonia.Controls
/// <summary>
/// Defines the <see cref="Pane"/> property
/// </summary>
public static readonly StyledProperty<object?> PaneProperty =
AvaloniaProperty.Register<SplitView, object?>(nameof(Pane));
public static readonly StyledProperty<object> PaneProperty =
AvaloniaProperty.Register<SplitView, object>(nameof(Pane));
/// <summary>
/// Defines the <see cref="PaneTemplate"/> property.
/// </summary>
public static readonly StyledProperty<IDataTemplate?> PaneTemplateProperty =
AvaloniaProperty.Register<HeaderedContentControl, IDataTemplate?>(nameof(PaneTemplate));
public static readonly StyledProperty<IDataTemplate> PaneTemplateProperty =
AvaloniaProperty.Register<HeaderedContentControl, IDataTemplate>(nameof(PaneTemplate));
/// <summary>
/// Defines the <see cref="UseLightDismissOverlayMode"/> property
@ -267,7 +267,7 @@ namespace Avalonia.Controls
/// <summary>
/// Gets or sets the data template used to display the header content of the control.
/// </summary>
public IDataTemplate? PaneTemplate
public IDataTemplate PaneTemplate
{
get => GetValue(PaneTemplateProperty);
set => SetValue(PaneTemplateProperty, value);

2
src/Avalonia.Controls/TextBoxTextInputMethodClient.cs

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

2
src/Avalonia.Controls/TrayIcon.cs

@ -140,7 +140,7 @@ namespace Avalonia.Controls
/// Gets or sets the parameter to pass to the <see cref="Command"/> property of a
/// <see cref="TrayIcon"/>.
/// </summary>
public object CommandParameter
public object? CommandParameter
{
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }

1
src/Avalonia.Controls/Window.cs

@ -994,6 +994,7 @@ namespace Avalonia.Controls
protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change)
{
base.OnPropertyChanged(change);
if (change.Property == SystemDecorationsProperty)
{
var typedNewValue = change.NewValue.GetValueOrDefault<SystemDecorations>();

6
src/Avalonia.Controls/WindowBase.cs

@ -193,6 +193,12 @@ namespace Avalonia.Controls
try
{
IsVisible = false;
if (this is IFocusScope scope)
{
FocusManager.Instance?.RemoveFocusScope(scope);
}
base.HandleClosed();
}
finally

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

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

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

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

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

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

6
src/Avalonia.FreeDesktop/DBusMenuExporter.cs

@ -413,10 +413,10 @@ namespace Avalonia.FreeDesktop
#region Events
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<(int id, uint timestamp)> ItemActivationRequested;
private event Action<PropertyChanges> PropertiesChanged;
private event Action<(int id, uint timestamp)> ItemActivationRequested { add { } remove { } }
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)
{

3
src/Avalonia.Input/ApiCompatBaseline.txt

@ -3,6 +3,7 @@ MembersMustExist : Member 'public Avalonia.Platform.IPlatformHandle Avalonia.Inp
MembersMustExist : Member 'public Avalonia.Interactivity.RoutedEvent<Avalonia.Interactivity.RoutedEventArgs> Avalonia.Interactivity.RoutedEvent<Avalonia.Interactivity.RoutedEventArgs> Avalonia.Input.Gestures.DoubleTappedEvent' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public Avalonia.Interactivity.RoutedEvent<Avalonia.Interactivity.RoutedEventArgs> Avalonia.Interactivity.RoutedEvent<Avalonia.Interactivity.RoutedEventArgs> Avalonia.Input.Gestures.RightTappedEvent' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public Avalonia.Interactivity.RoutedEvent<Avalonia.Interactivity.RoutedEventArgs> Avalonia.Interactivity.RoutedEvent<Avalonia.Interactivity.RoutedEventArgs> Avalonia.Input.Gestures.TappedEvent' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Input.IFocusManager.RemoveFocusScope(Avalonia.Input.IFocusScope)' is present in the implementation but not in the contract.
MembersMustExist : Member 'public Avalonia.Interactivity.RoutedEvent<Avalonia.Interactivity.RoutedEventArgs> Avalonia.Interactivity.RoutedEvent<Avalonia.Interactivity.RoutedEventArgs> Avalonia.Input.InputElement.DoubleTappedEvent' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public Avalonia.Interactivity.RoutedEvent<Avalonia.Interactivity.RoutedEventArgs> Avalonia.Interactivity.RoutedEvent<Avalonia.Interactivity.RoutedEventArgs> Avalonia.Input.InputElement.TappedEvent' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public void Avalonia.Input.InputElement.add_DoubleTapped(System.EventHandler<Avalonia.Interactivity.RoutedEventArgs>)' does not exist in the implementation but it does exist in the contract.
@ -10,4 +11,4 @@ MembersMustExist : Member 'public void Avalonia.Input.InputElement.add_Tapped(Sy
MembersMustExist : Member 'public void Avalonia.Input.InputElement.remove_DoubleTapped(System.EventHandler<Avalonia.Interactivity.RoutedEventArgs>)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public void Avalonia.Input.InputElement.remove_Tapped(System.EventHandler<Avalonia.Interactivity.RoutedEventArgs>)' does not exist in the implementation but it does exist in the contract.
TypesMustExist : Type 'Avalonia.Platform.IStandardCursorFactory' does not exist in the implementation but it does exist in the contract.
Total Issues: 11
Total Issues: 12

16
src/Avalonia.Input/FocusManager.cs

@ -162,6 +162,22 @@ namespace Avalonia.Input
Focus(e);
}
public void RemoveFocusScope(IFocusScope scope)
{
scope = scope ?? throw new ArgumentNullException(nameof(scope));
if (_focusScopes.TryGetValue(scope, out _))
{
SetFocusedElement(scope, null);
_focusScopes.Remove(scope);
}
if (Scope == scope)
{
Scope = null;
}
}
public static bool GetIsFocusScope(IInputElement e) => e is IFocusScope;
/// <summary>

7
src/Avalonia.Input/Gestures.cs

@ -30,7 +30,7 @@ namespace Avalonia.Input
"ScrollGestureEnded", RoutingStrategies.Bubble, typeof(Gestures));
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
private static WeakReference<IInteractive> s_lastPress = new WeakReference<IInteractive>(null);
private static readonly WeakReference<IInteractive> s_lastPress = new WeakReference<IInteractive>(null);
#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
static Gestures()
@ -86,16 +86,15 @@ namespace Avalonia.Input
#pragma warning restore CS0618 // Type or member is obsolete
if (clickCount <= 1)
{
s_lastPress = new WeakReference<IInteractive>(ev.Source);
s_lastPress.SetTarget(ev.Source);
}
else if (s_lastPress != null && clickCount == 2 && e.GetCurrentPoint(visual).Properties.IsLeftButtonPressed)
else if (clickCount == 2 && e.GetCurrentPoint(visual).Properties.IsLeftButtonPressed)
{
if (s_lastPress.TryGetTarget(out var target) && target == e.Source)
{
e.Source.RaiseEvent(new TappedEventArgs(DoubleTappedEvent, e));
}
}
}
}

6
src/Avalonia.Input/ICommandSource.cs

@ -1,5 +1,5 @@
using System.Windows.Input;
#nullable enable
namespace Avalonia.Input
{
///<summary>
@ -12,13 +12,13 @@ namespace Avalonia.Input
/// Classes that implement this interface should enable or disable based on the command's CanExecute return value.
/// The property may be implemented as read-write if desired.
/// </summary>
ICommand Command { get; }
ICommand? Command { get; }
/// <summary>
/// The parameter that will be passed to the command when executing the command.
/// The property may be implemented as read-write if desired.
/// </summary>
object CommandParameter { get; }
object? CommandParameter { get; }
/// <summary>

8
src/Avalonia.Input/IFocusManager.cs

@ -35,5 +35,13 @@ namespace Avalonia.Input
/// when it activates, e.g. when a Window is activated.
/// </remarks>
void SetFocusScope(IFocusScope scope);
/// <summary>
/// Notifies the focus manager that a focus scope has been removed.
/// </summary>
/// <param name="scope">The focus scope to be removed.</param>
/// This should not be called by client code. It is called by an <see cref="IFocusScope"/>
/// when it deactivates or closes, e.g. when a Window is closed.
void RemoveFocusScope(IFocusScope scope);
}
}

2
src/Avalonia.Input/InputElement.cs

@ -632,7 +632,7 @@ namespace Avalonia.Input
}
else if (change.Property == IsKeyboardFocusWithinProperty)
{
PseudoClasses.Set(":focus-within", _isKeyboardFocusWithin);
PseudoClasses.Set(":focus-within", change.NewValue.GetValueOrDefault<bool>());
}
}

2
src/Avalonia.Native/AvaloniaNativeMenuExporter.cs

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

6
src/Avalonia.Styling/Styling/PropertySetterInstance.cs

@ -16,14 +16,14 @@ namespace Avalonia.Styling
private readonly IStyleable _target;
private readonly StyledPropertyBase<T>? _styledProperty;
private readonly DirectPropertyBase<T>? _directProperty;
private readonly T _value;
private readonly T? _value;
private IDisposable? _subscription;
private bool _isActive;
public PropertySetterInstance(
IStyleable target,
StyledPropertyBase<T> property,
T value)
T? value)
{
_target = target;
_styledProperty = property;
@ -57,7 +57,7 @@ namespace Avalonia.Styling
{
if (_styledProperty is object)
{
_subscription = _target.SetValue(_styledProperty, _value, BindingPriority.Style);
_subscription = _target.SetValue(_styledProperty!, _value, BindingPriority.Style);
}
else
{

4
src/Avalonia.Styling/Styling/Setter.cs

@ -101,7 +101,7 @@ namespace Avalonia.Styling
data.result = new PropertySetterInstance<T>(
data.target,
property,
(T)data.value);
(T?)data.value);
}
}
@ -128,7 +128,7 @@ namespace Avalonia.Styling
data.result = new PropertySetterInstance<T>(
data.target,
property,
(T)data.value);
(T)data.value!);
}
}

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

@ -15,7 +15,7 @@
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<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"
Grid.Row="1"
IsVisible="{TemplateBinding IsExpanded}"
@ -32,9 +32,12 @@
<Style Selector="Expander[ExpandDirection=Up]">
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<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"
Grid.Row="0"
IsVisible="{TemplateBinding IsExpanded}"
@ -51,9 +54,12 @@
<Style Selector="Expander[ExpandDirection=Right]">
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<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"
Grid.Column="1"
IsVisible="{TemplateBinding IsExpanded}"
@ -70,9 +76,12 @@
<Style Selector="Expander[ExpandDirection=Left]">
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<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"
Grid.Column="0"
IsVisible="{TemplateBinding IsExpanded}"

4
src/Avalonia.Themes.Fluent/Controls/NumericUpDown.xaml

@ -38,6 +38,7 @@
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="0"
MinWidth="{TemplateBinding MinWidth}"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
AllowSpin="{TemplateBinding AllowSpin}"
@ -49,6 +50,9 @@
BorderBrush="Transparent"
Margin="-1"
Padding="{TemplateBinding Padding}"
MinWidth="{TemplateBinding MinWidth}"
Foreground="{TemplateBinding Foreground}"
FontSize="{TemplateBinding FontSize}"
Watermark="{TemplateBinding Watermark}"
IsReadOnly="{TemplateBinding IsReadOnly}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"

22
src/Avalonia.Visuals/Matrix.cs

@ -215,6 +215,28 @@ namespace Avalonia
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>
/// Calculates the determinant for this matrix.
/// </summary>

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

@ -18,11 +18,11 @@ namespace Avalonia.Media.Transformation
public static Matrix ComposeTransform(Matrix.Decomposed decomposed)
{
// According to https://www.w3.org/TR/css-transforms-1/#recomposing-to-a-2d-matrix
return Matrix.CreateTranslation(decomposed.Translate) *
Matrix.CreateRotation(decomposed.Angle) *
Matrix.CreateSkew(decomposed.Skew.X, decomposed.Skew.Y) *
Matrix.CreateScale(decomposed.Scale);
return Matrix.Identity
.Prepend(Matrix.CreateTranslation(decomposed.Translate))
.Prepend(Matrix.CreateRotation(decomposed.Angle))
.Prepend(Matrix.CreateSkew(decomposed.Skew.X, decomposed.Skew.Y))
.Prepend(Matrix.CreateScale(decomposed.Scale));
}
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)
{
result.Matrix = Matrix.Identity;
return true;
}
@ -179,7 +181,8 @@ namespace Avalonia.Media.Transformation
}
case OperationType.Identity:
{
// Do nothing.
result.Matrix = Matrix.Identity;
break;
}
}

25
src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs

@ -20,6 +20,7 @@ namespace Avalonia.Rendering
{
private readonly IVisual _root;
private readonly IRenderRoot _renderRoot;
private bool _updateTransformedBounds = true;
private IRenderTarget _renderTarget;
/// <summary>
@ -34,6 +35,13 @@ namespace Avalonia.Rendering
_renderRoot = root as IRenderRoot;
}
private ImmediateRenderer(IVisual root, bool updateTransformedBounds)
{
_root = root ?? throw new ArgumentNullException(nameof(root));
_renderRoot = root as IRenderRoot;
_updateTransformedBounds = updateTransformedBounds;
}
/// <inheritdoc/>
public bool DrawFps { get; set; }
@ -98,7 +106,7 @@ namespace Avalonia.Rendering
/// <param name="target">The render target.</param>
public static void Render(IVisual visual, IRenderTarget target)
{
using (var renderer = new ImmediateRenderer(visual))
using (var renderer = new ImmediateRenderer(visual, updateTransformedBounds: false))
using (var context = new DrawingContext(target.CreateDrawingContext(renderer)))
{
renderer.Render(context, visual, visual.Bounds);
@ -112,7 +120,7 @@ namespace Avalonia.Rendering
/// <param name="context">The drawing context.</param>
public static void Render(IVisual visual, DrawingContext context)
{
using (var renderer = new ImmediateRenderer(visual))
using (var renderer = new ImmediateRenderer(visual, updateTransformedBounds: false))
{
renderer.Render(context, visual, visual.Bounds);
}
@ -193,6 +201,12 @@ namespace Avalonia.Rendering
Render(new DrawingContext(context), visual, visual.Bounds);
}
internal static void Render(IVisual visual, DrawingContext context, bool updateTransformedBounds)
{
using var renderer = new ImmediateRenderer(visual, updateTransformedBounds);
renderer.Render(context, visual, visual.Bounds);
}
private static void ClearTransformedBounds(IVisual visual)
{
foreach (var e in visual.GetSelfAndVisualDescendants())
@ -308,7 +322,8 @@ namespace Avalonia.Rendering
new TransformedBounds(bounds, new Rect(), context.CurrentContainerTransform);
#pragma warning restore 0618
visual.TransformedBounds = transformed;
if (_updateTransformedBounds)
visual.TransformedBounds = transformed;
foreach (var child in visual.VisualChildren.OrderBy(x => x, ZIndexComparer.Instance))
{
@ -321,7 +336,7 @@ namespace Avalonia.Rendering
: clipRect;
Render(context, child, childClipRect);
}
else
else if (_updateTransformedBounds)
{
ClearTransformedBounds(child);
}
@ -329,7 +344,7 @@ namespace Avalonia.Rendering
}
}
if (!visual.IsVisible)
if (!visual.IsVisible && _updateTransformedBounds)
{
ClearTransformedBounds(visual);
}

60
src/Avalonia.X11/ICELib.cs

@ -0,0 +1,60 @@
using System;
using System.Runtime.InteropServices;
namespace Avalonia.X11
{
internal static class ICELib
{
private const string LibIce = "libICE.so.6";
[DllImport(LibIce, CallingConvention = CallingConvention.StdCall)]
public static extern int IceAddConnectionWatch(
IntPtr watchProc,
IntPtr clientData
);
[DllImport(LibIce, CallingConvention = CallingConvention.StdCall)]
public static extern void IceRemoveConnectionWatch(
IntPtr watchProc,
IntPtr clientData
);
[DllImport(LibIce, CallingConvention = CallingConvention.StdCall)]
public static extern IceProcessMessagesStatus IceProcessMessages(
IntPtr iceConn,
out IntPtr replyWait,
out bool replyReadyRet
);
[DllImport(LibIce, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr IceSetErrorHandler(
IntPtr handler
);
[DllImport(LibIce, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr IceSetIOErrorHandler(
IntPtr handler
);
public enum IceProcessMessagesStatus
{
IceProcessMessagesIoError = 1
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void IceErrorHandler(
IntPtr iceConn,
bool swap,
int offendingMinorOpcode,
ulong offendingSequence,
int errorClass,
int severity,
IntPtr values
);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void IceIOErrorHandler(
IntPtr iceConn
);
}
}

133
src/Avalonia.X11/SMLib.cs

@ -0,0 +1,133 @@
using System;
using System.Runtime.InteropServices;
namespace Avalonia.X11
{
internal static unsafe class SMLib
{
private const string LibSm = "libSM.so.6";
[DllImport(LibSm, CharSet = CharSet.Ansi)]
public static extern IntPtr SmcOpenConnection(
[MarshalAs(UnmanagedType.LPWStr)] string networkId,
IntPtr content,
int xsmpMajorRev,
int xsmpMinorRev,
ulong mask,
ref SmcCallbacks callbacks,
[MarshalAs(UnmanagedType.LPWStr)] [Out]
out string previousId,
[MarshalAs(UnmanagedType.LPWStr)] [Out]
out string clientIdRet,
int errorLength,
[Out] char[] errorStringRet);
[DllImport(LibSm, CallingConvention = CallingConvention.StdCall)]
public static extern int SmcCloseConnection(
IntPtr smcConn,
int count,
string[] reasonMsgs
);
[DllImport(LibSm, CallingConvention = CallingConvention.StdCall)]
public static extern void SmcSaveYourselfDone(
IntPtr smcConn,
bool success
);
[DllImport(LibSm, CallingConvention = CallingConvention.StdCall)]
public static extern int SmcInteractRequest(
IntPtr smcConn,
SmDialogValue dialogType,
IntPtr interactProc,
IntPtr clientData
);
[DllImport(LibSm, CallingConvention = CallingConvention.StdCall)]
public static extern void SmcInteractDone(
IntPtr smcConn,
bool success
);
[DllImport(LibSm, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr SmcGetIceConnection(
IntPtr smcConn
);
[DllImport(LibSm, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr SmcSetErrorHandler(
IntPtr handler
);
public enum SmDialogValue
{
SmDialogError = 0
}
[StructLayout(LayoutKind.Sequential)]
public struct SmcCallbacks
{
public IntPtr SaveYourself;
private readonly IntPtr Unused0;
public IntPtr Die;
private readonly IntPtr Unused1;
public IntPtr SaveComplete;
private readonly IntPtr Unused2;
public IntPtr ShutdownCancelled;
private readonly IntPtr Unused3;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void IceWatchProc(
IntPtr iceConn,
IntPtr clientData,
bool opening,
IntPtr* watchData
);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SmcDieProc(
IntPtr smcConn,
IntPtr clientData
);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SmcInteractProc(
IntPtr smcConn,
IntPtr clientData
);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SmcSaveCompleteProc(
IntPtr smcConn,
IntPtr clientData
);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SmcSaveYourselfProc(
IntPtr smcConn,
IntPtr clientData,
int saveType,
bool shutdown,
int interactStyle,
bool fast
);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SmcShutdownCancelledProc(
IntPtr smcConn,
IntPtr clientData
);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SmcErrorHandler(
IntPtr smcConn,
bool swap,
int offendingMinorOpcode,
ulong offendingSequence,
int errorClass,
int severity,
IntPtr values
);
}
}

17
src/Avalonia.X11/X11Platform.cs

@ -80,7 +80,8 @@ namespace Avalonia.X11
.Bind<IPlatformSettings>().ToConstant(new PlatformSettingsStub())
.Bind<IPlatformIconLoader>().ToConstant(new X11IconLoader(Info))
.Bind<ISystemDialogImpl>().ToConstant(new GtkSystemDialog())
.Bind<IMountedVolumeInfoProvider>().ToConstant(new LinuxMountedVolumeInfoProvider());
.Bind<IMountedVolumeInfoProvider>().ToConstant(new LinuxMountedVolumeInfoProvider())
.Bind<IPlatformLifetimeEventsImpl>().ToConstant(new X11PlatformLifetimeEvents(this));
X11Screens = Avalonia.X11.X11Screens.Init(this);
Screens = new X11Screens(X11Screens);
@ -230,7 +231,19 @@ namespace Avalonia
/// on their input devices by using sequences of characters or mouse operations that are natively available on their input devices.
/// </remarks>
public bool? EnableIme { get; set; }
/// <summary>
/// Determines whether to enable support for the
/// X Session Management Protocol.
/// </summary>
/// <remarks>
/// X Session Management Protocol is a standard implemented on most
/// Linux systems that uses Xorg. This enables apps to control how they
/// can control and/or cancel the pending shutdown requested by the user.
/// </remarks>
public bool EnableSessionManagement { get; set; } =
Environment.GetEnvironmentVariable("AVALONIA_X11_USE_SESSION_MANAGEMENT") != "0";
public IList<GlVersion> GlProfiles { get; set; } = new List<GlVersion>
{
new GlVersion(GlProfileType.OpenGL, 4, 0),

259
src/Avalonia.X11/X11PlatformLifetimeEvents.cs

@ -0,0 +1,259 @@
#nullable enable
using System;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Logging;
using Avalonia.Platform;
using Avalonia.Threading;
namespace Avalonia.X11
{
internal unsafe class X11PlatformLifetimeEvents : IDisposable, IPlatformLifetimeEventsImpl
{
private readonly AvaloniaX11Platform _platform;
private const ulong SmcSaveYourselfProcMask = 1L;
private const ulong SmcDieProcMask = 2L;
private const ulong SmcSaveCompleteProcMask = 4L;
private const ulong SmcShutdownCancelledProcMask = 8L;
private static readonly ConcurrentDictionary<IntPtr, X11PlatformLifetimeEvents> s_nativeToManagedMapper =
new ConcurrentDictionary<IntPtr, X11PlatformLifetimeEvents>();
private static readonly SMLib.SmcSaveYourselfProc s_saveYourselfProcDelegate = SmcSaveYourselfHandler;
private static readonly SMLib.SmcDieProc s_dieDelegate = SmcDieHandler;
private static readonly SMLib.SmcShutdownCancelledProc
s_shutdownCancelledDelegate = SmcShutdownCancelledHandler;
private static readonly SMLib.SmcSaveCompleteProc s_saveCompleteDelegate = SmcSaveCompleteHandler;
private static readonly SMLib.SmcInteractProc s_smcInteractDelegate = StaticInteractHandler;
private static readonly SMLib.SmcErrorHandler s_smcErrorHandlerDelegate = StaticErrorHandler;
private static readonly ICELib.IceErrorHandler s_iceErrorHandlerDelegate = StaticErrorHandler;
private static readonly ICELib.IceIOErrorHandler s_iceIoErrorHandlerDelegate = StaticIceIOErrorHandler;
private static readonly SMLib.IceWatchProc s_iceWatchProcDelegate = IceWatchHandler;
private static SMLib.SmcCallbacks s_callbacks = new SMLib.SmcCallbacks()
{
ShutdownCancelled = Marshal.GetFunctionPointerForDelegate(s_shutdownCancelledDelegate),
Die = Marshal.GetFunctionPointerForDelegate(s_dieDelegate),
SaveYourself = Marshal.GetFunctionPointerForDelegate(s_saveYourselfProcDelegate),
SaveComplete = Marshal.GetFunctionPointerForDelegate(s_saveCompleteDelegate)
};
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
private readonly IntPtr _currentIceConn;
private readonly IntPtr _currentSmcConn;
private bool _saveYourselfPhase;
internal X11PlatformLifetimeEvents(AvaloniaX11Platform platform)
{
_platform = platform;
if (ICELib.IceAddConnectionWatch(
Marshal.GetFunctionPointerForDelegate(s_iceWatchProcDelegate),
IntPtr.Zero) == 0)
{
Logger.TryGet(LogEventLevel.Warning, LogArea.X11Platform)?.Log(this,
"SMLib was unable to add an ICE connection watcher.");
return;
}
var errorBuf = new char[255];
var smcConn = SMLib.SmcOpenConnection(null!,
IntPtr.Zero, 1, 0,
SmcSaveYourselfProcMask |
SmcSaveCompleteProcMask |
SmcShutdownCancelledProcMask |
SmcDieProcMask,
ref s_callbacks,
out _,
out _,
errorBuf.Length,
errorBuf);
if (smcConn == IntPtr.Zero)
{
Logger.TryGet(LogEventLevel.Warning, LogArea.X11Platform)?.Log(this,
$"SMLib/ICELib reported a new error: {new string(errorBuf)}");
return;
}
if (!s_nativeToManagedMapper.TryAdd(smcConn, this))
{
Logger.TryGet(LogEventLevel.Warning, LogArea.X11Platform)?.Log(this,
"SMLib was unable to add this instance to the native to managed map.");
return;
}
_ = SMLib.SmcSetErrorHandler(Marshal.GetFunctionPointerForDelegate(s_smcErrorHandlerDelegate));
_ = ICELib.IceSetErrorHandler(Marshal.GetFunctionPointerForDelegate(s_iceErrorHandlerDelegate));
_ = ICELib.IceSetIOErrorHandler(Marshal.GetFunctionPointerForDelegate(s_iceIoErrorHandlerDelegate));
_currentSmcConn = smcConn;
_currentIceConn = SMLib.SmcGetIceConnection(smcConn);
Task.Run(() =>
{
var token = _cancellationTokenSource.Token;
while (!token.IsCancellationRequested) HandleRequests();
}, _cancellationTokenSource.Token);
}
public void Dispose()
{
if (_currentSmcConn == IntPtr.Zero) return;
s_nativeToManagedMapper.TryRemove(_currentSmcConn, out _);
_ = SMLib.SmcCloseConnection(_currentSmcConn, 1,
new[] { $"{nameof(X11PlatformLifetimeEvents)} was disposed in managed code." });
}
private static void SmcSaveCompleteHandler(IntPtr smcConn, IntPtr clientData)
{
GetInstance(smcConn)?.SaveCompleteHandler();
}
private static X11PlatformLifetimeEvents? GetInstance(IntPtr smcConn)
{
return s_nativeToManagedMapper.TryGetValue(smcConn, out var instance) ? instance : null;
}
private static void SmcShutdownCancelledHandler(IntPtr smcConn, IntPtr clientData)
{
GetInstance(smcConn)?.ShutdownCancelledHandler();
}
private static void SmcDieHandler(IntPtr smcConn, IntPtr clientData)
{
GetInstance(smcConn)?.DieHandler();
}
private static void SmcSaveYourselfHandler(IntPtr smcConn, IntPtr clientData, int saveType,
bool shutdown, int interactStyle, bool fast)
{
GetInstance(smcConn)?.SaveYourselfHandler(smcConn, clientData, shutdown, fast);
}
private static void StaticInteractHandler(IntPtr smcConn, IntPtr clientData)
{
GetInstance(smcConn)?.InteractHandler(smcConn);
}
private static void StaticIceIOErrorHandler(IntPtr iceConn)
{
Logger.TryGet(LogEventLevel.Warning, LogArea.X11Platform)?.Log(null,
"ICELib reported an unknown IO Error.");
}
private static void StaticErrorHandler(IntPtr smcConn, bool swap, int offendingMinorOpcode,
ulong offendingSequence, int errorClass, int severity, IntPtr values)
{
GetInstance(smcConn)
?.ErrorHandler(swap, offendingMinorOpcode, offendingSequence, errorClass, severity, values);
}
// ReSharper disable UnusedParameter.Local
private void ErrorHandler(bool swap, int offendingMinorOpcode, ulong offendingSequence, int errorClass,
int severity, IntPtr values)
{
Logger.TryGet(LogEventLevel.Warning, LogArea.X11Platform)?.Log(this,
"SMLib reported an error:" +
$" severity {severity:X}" +
$" mOpcode {offendingMinorOpcode:X}" +
$" mSeq {offendingSequence:X}" +
$" errClass {errorClass:X}.");
}
private void HandleRequests()
{
if (ICELib.IceProcessMessages(_currentIceConn, out _, out _) ==
ICELib.IceProcessMessagesStatus.IceProcessMessagesIoError)
{
Logger.TryGet(LogEventLevel.Warning, LogArea.X11Platform)?.Log(this,
"SMLib lost its underlying ICE connection.");
Dispose();
}
}
private void SaveCompleteHandler()
{
_saveYourselfPhase = false;
}
private void ShutdownCancelledHandler()
{
if (_saveYourselfPhase)
SMLib.SmcSaveYourselfDone(_currentSmcConn, true);
_saveYourselfPhase = false;
}
private void DieHandler()
{
Dispose();
}
private void SaveYourselfHandler(IntPtr smcConn, IntPtr clientData, bool shutdown, bool fast)
{
if (_saveYourselfPhase)
{
SMLib.SmcSaveYourselfDone(smcConn, true);
}
_saveYourselfPhase = true;
if (shutdown && !fast)
{
var _ = SMLib.SmcInteractRequest(smcConn, SMLib.SmDialogValue.SmDialogError,
Marshal.GetFunctionPointerForDelegate(s_smcInteractDelegate),
clientData);
}
else
{
SMLib.SmcSaveYourselfDone(smcConn, true);
_saveYourselfPhase = false;
}
}
private void InteractHandler(IntPtr smcConn)
{
Dispatcher.UIThread.Post(() => ActualInteractHandler(smcConn));
}
private void ActualInteractHandler(IntPtr smcConn)
{
var e = new ShutdownRequestedEventArgs();
if (_platform.Options?.EnableSessionManagement ?? false)
{
ShutdownRequested?.Invoke(this, e);
}
SMLib.SmcInteractDone(smcConn, e.Cancel);
if (e.Cancel)
{
return;
}
_saveYourselfPhase = false;
SMLib.SmcSaveYourselfDone(smcConn, true);
}
private static void IceWatchHandler(IntPtr iceConn, IntPtr clientData, bool opening, IntPtr* watchData)
{
if (!opening) return;
ICELib.IceRemoveConnectionWatch(Marshal.GetFunctionPointerForDelegate(s_iceWatchProcDelegate),
IntPtr.Zero);
}
public event EventHandler<ShutdownRequestedEventArgs>? ShutdownRequested;
}
}

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

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

1
src/Avalonia.X11/X11Window.cs

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

6
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs

@ -5,6 +5,7 @@ using Avalonia.Controls;
using Avalonia.Markup.Data;
using Avalonia.Markup.Xaml.Converters;
using Avalonia.Markup.Xaml.XamlIl.Runtime;
using Avalonia.Styling;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
@ -33,6 +34,11 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
_ => null,
};
if (provideTarget.TargetObject is Setter setter)
{
targetType = setter.Property.PropertyType;
}
// Look upwards though the ambient context for IResourceHosts and IResourceProviders
// which might be able to give us the resource.
foreach (var e in stack.Parents)

1
src/Skia/Avalonia.Skia/Avalonia.Skia.csproj

@ -5,6 +5,7 @@
<AssemblyName>Avalonia.Skia</AssemblyName>
<PackageId>Avalonia.Skia</PackageId>
<IncludeLinuxSkia>true</IncludeLinuxSkia>
<IncludeWasmSkia>true</IncludeWasmSkia>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>

2
src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs

@ -25,7 +25,7 @@ namespace Avalonia.Skia
GRGlInterface.CreateOpenGl(proc => context.GlInterface.GetProcAddress(proc)) :
GRGlInterface.CreateGles(proc => context.GlInterface.GetProcAddress(proc)))
{
_grContext = GRContext.CreateGl(iface);
_grContext = GRContext.CreateGl(iface, new GRContextOptions { AvoidStencilBuffers = true });
if (maxResourceBytes.HasValue)
{
_grContext.SetResourceCacheLimit(maxResourceBytes.Value);

2
src/Skia/Avalonia.Skia/SKTypefaceCollection.cs

@ -6,7 +6,7 @@ using SkiaSharp;
namespace Avalonia.Skia
{
internal class SKTypefaceCollection
public class SKTypefaceCollection
{
private readonly ConcurrentDictionary<Typeface, SKTypeface> _typefaces =
new ConcurrentDictionary<Typeface, SKTypeface>();

2
src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs

@ -7,7 +7,7 @@ using SkiaSharp;
namespace Avalonia.Skia
{
internal static class SKTypefaceCollectionCache
public static class SKTypefaceCollectionCache
{
private static readonly ConcurrentDictionary<FontFamily, SKTypefaceCollection> s_cachedCollections;

BIN
src/Web/Avalonia.Web.Blazor/Assets/NotoMono-Regular.ttf

Binary file not shown.

BIN
src/Web/Avalonia.Web.Blazor/Assets/NotoSans-Italic.ttf

Binary file not shown.

57
src/Web/Avalonia.Web.Blazor/Avalonia.Web.Blazor.csproj

@ -0,0 +1,57 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<PackageId>Avalonia.Web.Blazor</PackageId>
<LangVersion>preview</LangVersion>
</PropertyGroup>
<ItemGroup>
<SupportedPlatform Include="browser" />
<Compile Include="..\..\Shared\PlatformSupport\AssetLoader.cs" />
</ItemGroup>
<PropertyGroup>
<TypescriptOutDir>wwwroot</TypescriptOutDir>
<TypeScriptNoEmitOnError>true</TypeScriptNoEmitOnError>
<TypeScriptNoImplicitReturns>true</TypeScriptNoImplicitReturns>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<TypeScriptRemoveComments>false</TypeScriptRemoveComments>
<TypeScriptSourceMap>true</TypeScriptSourceMap>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<TypeScriptRemoveComments>true</TypeScriptRemoveComments>
<TypeScriptSourceMap>false</TypeScriptSourceMap>
</PropertyGroup>
<Import Project="..\..\..\build\BuildTargets.targets" />
<Import Project="..\..\..\build\SkiaSharp.props" />
<Import Project="..\..\..\build\HarfBuzzSharp.props" />
<ItemGroup>
<AvaloniaResource Include="Assets\*" />
<Content Include="*.props">
<Pack>true</Pack>
<PackagePath>build\;buildTransitive\</PackagePath>
</Content>
<Content Include="*.targets">
<Pack>true</Pack>
<PackagePath>build\;buildTransitive\</PackagePath>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="6.0.0" />
<PackageReference Include="Microsoft.TypeScript.MSBuild" Version="4.5.2" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Avalonia.Base\Avalonia.Base.csproj" />
<ProjectReference Include="..\..\Avalonia.Controls\Avalonia.Controls.csproj" />
<ProjectReference Include="..\..\Skia\Avalonia.Skia\Avalonia.Skia.csproj" />
</ItemGroup>
</Project>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save