Browse Source

Merge branch 'release/11.1.3' into customers/outsystems-11.1.X

customers/outsystems-11.1.X
Steven Kirk 1 year ago
parent
commit
a049d992d6
  1. 94
      api/Avalonia.Android.nupkg.xml
  2. 22
      api/Avalonia.Browser.nupkg.xml
  3. 76
      api/Avalonia.Controls.ColorPicker.nupkg.xml
  4. 16
      api/Avalonia.Controls.DataGrid.nupkg.xml
  5. 64
      api/Avalonia.Diagnostics.nupkg.xml
  6. 2
      api/Avalonia.Skia.nupkg.xml
  7. 448
      api/Avalonia.Themes.Fluent.nupkg.xml
  8. 424
      api/Avalonia.Themes.Simple.nupkg.xml
  9. 1114
      api/Avalonia.nupkg.xml
  10. 18
      azure-pipelines-integrationtests.yml
  11. 3
      build/SharedVersion.props
  12. 12
      nukebuild/BuildParameters.cs
  13. 21
      samples/ControlCatalog.Android/MainActivity.cs
  14. 1
      samples/IntegrationTestApp/App.axaml.cs
  15. 7
      samples/IntegrationTestApp/IntegrationTestApp.csproj
  16. 201
      samples/IntegrationTestApp/MainWindow.axaml
  17. 301
      samples/IntegrationTestApp/MainWindow.axaml.cs
  18. 6
      samples/IntegrationTestApp/Models/Page.cs
  19. 17
      samples/IntegrationTestApp/Pages/AutomationPage.axaml
  20. 11
      samples/IntegrationTestApp/Pages/AutomationPage.axaml.cs
  21. 22
      samples/IntegrationTestApp/Pages/ButtonPage.axaml
  22. 11
      samples/IntegrationTestApp/Pages/ButtonPage.axaml.cs
  23. 12
      samples/IntegrationTestApp/Pages/CheckBoxPage.axaml
  24. 11
      samples/IntegrationTestApp/Pages/CheckBoxPage.axaml.cs
  25. 16
      samples/IntegrationTestApp/Pages/ComboBoxPage.axaml
  26. 22
      samples/IntegrationTestApp/Pages/ComboBoxPage.axaml.cs
  27. 17
      samples/IntegrationTestApp/Pages/ContextMenuPage.axaml
  28. 11
      samples/IntegrationTestApp/Pages/ContextMenuPage.axaml.cs
  29. 14
      samples/IntegrationTestApp/Pages/DesktopPage.axaml
  30. 19
      samples/IntegrationTestApp/Pages/DesktopPage.axaml.cs
  31. 29
      samples/IntegrationTestApp/Pages/GesturesPage.axaml
  32. 44
      samples/IntegrationTestApp/Pages/GesturesPage.axaml.cs
  33. 15
      samples/IntegrationTestApp/Pages/ListBoxPage.axaml
  34. 23
      samples/IntegrationTestApp/Pages/ListBoxPage.axaml.cs
  35. 22
      samples/IntegrationTestApp/Pages/MenuPage.axaml
  36. 24
      samples/IntegrationTestApp/Pages/MenuPage.axaml.cs
  37. 14
      samples/IntegrationTestApp/Pages/RadioButtonPage.axaml
  38. 11
      samples/IntegrationTestApp/Pages/RadioButtonPage.axaml.cs
  39. 8
      samples/IntegrationTestApp/Pages/ScrollBarPage.axaml
  40. 11
      samples/IntegrationTestApp/Pages/ScrollBarPage.axaml.cs
  41. 17
      samples/IntegrationTestApp/Pages/SliderPage.axaml
  42. 17
      samples/IntegrationTestApp/Pages/SliderPage.axaml.cs
  43. 21
      samples/IntegrationTestApp/Pages/WindowDecorationsPage.axaml
  44. 63
      samples/IntegrationTestApp/Pages/WindowDecorationsPage.axaml.cs
  45. 44
      samples/IntegrationTestApp/Pages/WindowPage.axaml
  46. 182
      samples/IntegrationTestApp/Pages/WindowPage.axaml.cs
  47. 8
      samples/IntegrationTestApp/ShowWindowTest.axaml.cs
  48. 23
      samples/IntegrationTestApp/ViewModels/MainWindowViewModel.cs
  49. 24
      samples/IntegrationTestApp/ViewModels/ViewModelBase.cs
  50. 12
      src/Android/Avalonia.Android/AndroidInputMethod.cs
  51. 32
      src/Android/Avalonia.Android/AvaloniaActivity.cs
  52. 18
      src/Android/Avalonia.Android/AvaloniaMainActivity.cs
  53. 65
      src/Android/Avalonia.Android/Platform/AndroidActivatableLifetime.cs
  54. 36
      src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
  55. 16
      src/Avalonia.Base/Input/TextInput/TextInputMethodClient.cs
  56. 2
      src/Avalonia.Base/Media/Brush.cs
  57. 18
      src/Avalonia.Base/Media/DrawingBrush.cs
  58. 2
      src/Avalonia.Base/Media/Typeface.cs
  59. 65
      src/Avalonia.Base/Media/VisualBrush.cs
  60. 6
      src/Avalonia.Base/Platform/IDrawingContextImpl.cs
  61. 8
      src/Avalonia.Base/Platform/IPlatformRenderInterface.cs
  62. 44
      src/Avalonia.Base/Platform/IScopedResource.cs
  63. 95
      src/Avalonia.Base/Platform/Storage/FallbackStorageProvider.cs
  64. 1
      src/Avalonia.Base/Reactive/Operators/Switch.cs
  65. 11
      src/Avalonia.Base/Rendering/Composition/Brushes/ServerSimpleContentBrush.cs
  66. 45
      src/Avalonia.Base/Rendering/Composition/Compositor.cs
  67. 19
      src/Avalonia.Base/Rendering/Composition/Drawing/CompositionRenderDataSceneBrushContent.cs
  68. 7
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionContainerVisual.cs
  69. 10
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionDrawListVisual.cs
  70. 7
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionExperimentalAcrylicVisual.cs
  71. 5
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionSolidColorVisual.cs
  72. 5
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionSurfaceVisual.cs
  73. 2
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.DirtyRects.cs
  74. 5
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs
  75. 22
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs
  76. 40
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.UserApis.cs
  77. 25
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs
  78. 9
      src/Avalonia.Base/Rendering/Composition/Server/ServerCustomCompositionVisual.cs
  79. 75
      src/Avalonia.Base/Rendering/Composition/Server/ServerVisualRenderContext.cs
  80. 12
      src/Avalonia.Base/Utilities/SmallDictionary.cs
  81. 2
      src/Avalonia.Controls.DataGrid/DataGridCell.cs
  82. 2
      src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs
  83. 2
      src/Avalonia.Controls.DataGrid/DataGridRow.cs
  84. 6
      src/Avalonia.Controls.DataGrid/DataGridRowHeader.cs
  85. 12
      src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs
  86. 14
      src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs
  87. 6
      src/Avalonia.Controls/BorderVisual.cs
  88. 2
      src/Avalonia.Controls/ListBoxItem.cs
  89. 2
      src/Avalonia.Controls/MenuItem.cs
  90. 2
      src/Avalonia.Controls/Platform/IWindowImpl.cs
  91. 1
      src/Avalonia.Controls/Presenters/TextPresenter.cs
  92. 2
      src/Avalonia.Controls/Primitives/TextSelectorLayer.cs
  93. 1
      src/Avalonia.Controls/TabItem.cs
  94. 1
      src/Avalonia.Controls/TextBlock.cs
  95. 21
      src/Avalonia.Controls/TextBox.cs
  96. 71
      src/Avalonia.Controls/TextBoxTextInputMethodClient.cs
  97. 2
      src/Avalonia.Controls/ToolTipService.cs
  98. 3
      src/Avalonia.Controls/TreeViewItem.cs
  99. 3
      src/Avalonia.Dialogs/Avalonia.Dialogs.csproj
  100. 2
      src/Avalonia.FreeDesktop/DBusIme/X11DBusImeHelper.cs

94
api/Avalonia.Android.nupkg.xml

@ -1,94 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource.Animation</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource.Animator</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource.Attribute</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource.Boolean</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource.Color</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource.Dimension</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource.Drawable</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource.Id</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource.Integer</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource.Interpolator</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource.Layout</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource.String</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource.Style</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource.Styleable</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0007</DiagnosticId>
<Target>T:Avalonia.Android.Internal.Resource</Target>
<Left>baseline/net6.0-android31.0/Avalonia.Android.dll</Left>
<Right>target/net8.0-android34.0/Avalonia.Android.dll</Right>
</Suppression>
</Suppressions>

22
api/Avalonia.Browser.nupkg.xml

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Browser.AvaloniaView.get_IsComposing</Target>
<Left>baseline/net7.0/Avalonia.Browser.dll</Left>
<Right>target/net8.0-browser1.0/Avalonia.Browser.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Browser.AvaloniaView.OnDragEvent(System.Runtime.InteropServices.JavaScript.JSObject)</Target>
<Left>baseline/net7.0/Avalonia.Browser.dll</Left>
<Right>target/net8.0-browser1.0/Avalonia.Browser.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0008</DiagnosticId>
<Target>T:Avalonia.Browser.AvaloniaView</Target>
<Left>baseline/net7.0/Avalonia.Browser.dll</Left>
<Right>target/net8.0-browser1.0/Avalonia.Browser.dll</Right>
</Suppression>
</Suppressions>

76
api/Avalonia.Controls.ColorPicker.nupkg.xml

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorPicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorPreviewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorSlider.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorSpectrum.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/Fluent.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorPicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorPreviewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorSlider.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorSpectrum.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/Simple.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
</Suppressions>

16
api/Avalonia.Controls.DataGrid.nupkg.xml

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.DataGrid.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.DataGrid.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.DataGrid.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.DataGrid.dll</Right>
</Suppression>
</Suppressions>

64
api/Avalonia.Diagnostics.nupkg.xml

@ -1,64 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Diagnostics/Controls/BrushEditor.axaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Diagnostics.dll</Left>
<Right>target/netstandard2.0/Avalonia.Diagnostics.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Diagnostics/Controls/FilterTextBox.axaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Diagnostics.dll</Left>
<Right>target/netstandard2.0/Avalonia.Diagnostics.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Diagnostics/Controls/ThicknessEditor.axaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Diagnostics.dll</Left>
<Right>target/netstandard2.0/Avalonia.Diagnostics.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Diagnostics/Views/ConsoleView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Diagnostics.dll</Left>
<Right>target/netstandard2.0/Avalonia.Diagnostics.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Diagnostics/Views/ControlDetailsView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Diagnostics.dll</Left>
<Right>target/netstandard2.0/Avalonia.Diagnostics.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Diagnostics/Views/EventsPageView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Diagnostics.dll</Left>
<Right>target/netstandard2.0/Avalonia.Diagnostics.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Diagnostics/Views/LayoutExplorerView.axaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Diagnostics.dll</Left>
<Right>target/netstandard2.0/Avalonia.Diagnostics.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Diagnostics/Views/MainView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Diagnostics.dll</Left>
<Right>target/netstandard2.0/Avalonia.Diagnostics.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Diagnostics/Views/MainWindow.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Diagnostics.dll</Left>
<Right>target/netstandard2.0/Avalonia.Diagnostics.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Diagnostics/Views/TreePageView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Diagnostics.dll</Left>
<Right>target/netstandard2.0/Avalonia.Diagnostics.dll</Right>
</Suppression>
</Suppressions>

2
api/Avalonia.Skia.nupkg.xml

@ -3,7 +3,7 @@
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaSharpApiLease.TryLeasePlatformGraphicsApi</Target>
<Target>M:Avalonia.Skia.ISkiaGpuWithPlatformGraphicsContext.TryGetGrContext</Target>
<Left>baseline/netstandard2.0/Avalonia.Skia.dll</Left>
<Right>target/netstandard2.0/Avalonia.Skia.dll</Right>
</Suppression>

448
api/Avalonia.Themes.Fluent.nupkg.xml

@ -1,448 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Accents/BaseColorsPalette.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Accents/BaseResources.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Accents/FluentControlResources.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/AdornerLayer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/AutoCompleteBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Button.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ButtonSpinner.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Calendar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarDatePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarDayButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CaptionButtons.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Carousel.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CheckBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ComboBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ComboBoxItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ContentControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ContextMenu.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DataValidationErrors.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DatePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DateTimePickerShared.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DropDownButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/EmbeddableControlRoot.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Expander.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/FluentControls.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/FlyoutPresenter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/GridSplitter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ItemsControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Label.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ListBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ListBoxItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ManagedFileChooser.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Menu.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuFlyoutPresenter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuScrollViewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NativeMenuBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NotificationCard.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NumericUpDown.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/OverlayPopupHost.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/PathIcon.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/PopupRoot.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ProgressBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RadioButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RefreshContainer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RefreshVisualizer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RepeatButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ScrollBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ScrollViewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SelectableTextBlock.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Separator.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Slider.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SplitButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SplitView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabStrip.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabStripItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TextBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ThemeVariantScope.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TimePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TitleBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToggleButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToggleSwitch.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToolTip.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TransitioningContentControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TreeView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TreeViewItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/UserControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Window.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/WindowNotificationManager.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/DensityStyles/Compact.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/FluentTheme.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
</Suppressions>

424
api/Avalonia.Themes.Simple.nupkg.xml

@ -1,424 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Accents/Base.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/AdornerLayer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/AutoCompleteBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Button.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ButtonSpinner.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Calendar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarDatePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarDayButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CaptionButtons.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Carousel.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CheckBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ComboBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ComboBoxItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ContentControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ContextMenu.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DataValidationErrors.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DatePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DateTimePickerShared.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DropDownButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/EmbeddableControlRoot.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Expander.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/FlyoutPresenter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/GridSplitter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ItemsControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Label.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ListBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ListBoxItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ManagedFileChooser.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Menu.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuFlyoutPresenter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NativeMenuBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NotificationCard.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NumericUpDown.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/OverlayPopupHost.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/PathIcon.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/PopupRoot.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ProgressBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RadioButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RefreshContainer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RefreshVisualizer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RepeatButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ScrollBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ScrollViewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SelectableTextBlock.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Separator.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SimpleControls.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Slider.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SplitButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SplitView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabStrip.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabStripItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TextBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ThemeVariantScope.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TimePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TitleBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToggleButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToggleSwitch.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToolTip.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TransitioningContentControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TreeView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TreeViewItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/UserControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Window.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/WindowNotificationManager.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/SimpleTheme.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
</Suppressions>

1114
api/Avalonia.nupkg.xml

File diff suppressed because it is too large

18
azure-pipelines-integrationtests.yml

@ -83,11 +83,23 @@ jobs:
projects: 'samples/IntegrationTestApp/IntegrationTestApp.csproj'
- task: DotNetCoreCLI@2
displayName: 'Build test project'
inputs:
command: 'build'
projects: 'tests\Avalonia.IntegrationTests.Appium\Avalonia.IntegrationTests.Appium.csproj'
- task: VSTest@2
displayName: 'Run Integration Tests'
retryCountOnTaskFailure: 3
inputs:
command: 'test'
projects: 'tests/Avalonia.IntegrationTests.Appium/Avalonia.IntegrationTests.Appium.csproj'
testAssemblyVer2: '**\bin\**\Avalonia.IntegrationTests.Appium.dll'
runSettingsFile: 'tests\Avalonia.IntegrationTests.Appium\record-video.runsettings'
- task: PublishTestResults@2
displayName: 'Publish test results'
inputs:
testResultsFormat: 'XUnit'
testResultsFiles: '**/*.trx'
condition: succeededOrFailed()
- task: Windows Application Driver@0
inputs:

3
build/SharedVersion.props

@ -2,7 +2,8 @@
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Product>Avalonia</Product>
<Version>11.1.2</Version>
<Version>11.1.3</Version>
<ApiCompatVersion>11.1.0</ApiCompatVersion>
<Authors>Avalonia Team</Authors>
<Copyright>Copyright 2013-$([System.DateTime]::Now.ToString(`yyyy`)) &#169; The AvaloniaUI Project</Copyright>
<PackageProjectUrl>https://avaloniaui.net</PackageProjectUrl>

12
nukebuild/BuildParameters.cs

@ -116,9 +116,10 @@ public partial class Build
IsNuGetRelease = IsMainRepo && IsReleasable && IsReleaseBranch;
// VERSION
Version = b.ForceNugetVersion ?? GetVersion();
var (propsVersion, propsApiCompatVersion) = GetVersion();
Version = b.ForceNugetVersion ?? propsVersion;
ApiValidationBaseline = b.ApiValidationBaseline ?? new Version(new Version(Version.Split('-', StringSplitOptions.None).First()).Major, 0).ToString();
ApiValidationBaseline = b.ApiValidationBaseline ?? propsApiCompatVersion;
UpdateApiValidationSuppression = b.UpdateApiValidationSuppression ?? IsLocalBuild;
if (IsRunningOnAzure)
@ -153,10 +154,13 @@ public partial class Build
VersionOutputDir = b.VersionOutputDir;
}
string GetVersion()
(string Version, string ApiCompatVersion) GetVersion()
{
var xdoc = XDocument.Load(RootDirectory / "build/SharedVersion.props");
return xdoc.Descendants().First(x => x.Name.LocalName == "Version").Value;
return (
xdoc.Descendants().First(x => x.Name.LocalName == "Version").Value,
xdoc.Descendants().First(x => x.Name.LocalName == "ApiCompatVersion").Value
);
}
}

21
samples/ControlCatalog.Android/MainActivity.cs

@ -1,5 +1,6 @@
using Android.App;
using Android.Content.PM;
using Android.OS;
using Avalonia;
using Avalonia.Android;
using static Android.Content.Intent;
@ -10,10 +11,9 @@ using static Android.Content.Intent;
namespace ControlCatalog.Android
{
[Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", MainLauncher = true, Exported = true, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)]
// CategoryBrowsable and DataScheme are required for Protocol activation.
[Activity(Name = "com.Avalonia.ControlCatalog.MainActivity", Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", MainLauncher = true, Exported = true, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)]
// CategoryLeanbackLauncher is required for Android TV.
[IntentFilter(new [] { ActionView }, Categories = new [] { CategoryDefault, CategoryBrowsable, CategoryLeanbackLauncher }, DataScheme = "avln" )]
[IntentFilter(new [] { ActionView }, Categories = new [] { CategoryDefault, CategoryLeanbackLauncher })]
public class MainActivity : AvaloniaMainActivity<App>
{
protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
@ -25,4 +25,19 @@ namespace ControlCatalog.Android
});
}
}
/// <summary>
/// Special activity to handle OpenUri activation.
/// `AvaloniaActivity` internally will redirect parameters to the Avalonia Application.
/// </summary>
[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true, Theme = "@android:style/Theme.NoDisplay")]
[IntentFilter(new[] {ActionView}, Categories = new[] {CategoryDefault, CategoryBrowsable}, DataScheme = "avln")]
public class DataSchemeActivity : AvaloniaActivity
{
protected override void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);
Finish();
}
}
}

1
samples/IntegrationTestApp/App.axaml.cs

@ -1,6 +1,7 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using MiniMvvm;
namespace IntegrationTestApp
{

7
samples/IntegrationTestApp/IntegrationTestApp.csproj

@ -4,6 +4,7 @@
<TargetFramework>$(AvsCurrentTargetFramework)</TargetFramework>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);AVP1012</NoWarn>
<IncludeAvaloniaGenerators>true</IncludeAvaloniaGenerators>
</PropertyGroup>
<PropertyGroup>
@ -25,10 +26,12 @@
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Fluent\Avalonia.Themes.Fluent.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Fonts.Inter\Avalonia.Fonts.Inter.csproj" />
<ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />
</ItemGroup>
<Import Project="..\..\build\BuildTargets.targets" />
<Import Project="..\..\build\SampleApp.props" />
<Import Project="..\..\build\ReferenceCoreLibraries.props" />
<Import Project="..\..\build\SourceGenerators.props" />
</Project>

201
samples/IntegrationTestApp/MainWindow.axaml

@ -2,13 +2,12 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:integrationTestApp="using:IntegrationTestApp"
xmlns:vm="using:IntegrationTestApp.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.MainWindow"
Name="MainWindow"
Icon="/Assets/icon.ico"
Title="IntegrationTestApp"
x:DataType="integrationTestApp:MainWindow">
x:DataType="vm:MainWindowViewModel">
<NativeMenu.Menu>
<NativeMenu>
<NativeMenuItem Header="File">
@ -19,7 +18,7 @@
<NativeMenuItem Header="View">
<NativeMenu/>
</NativeMenuItem>
<NativeMenuItem Header="_Options">
<NativeMenuItem Header="_Options">
<NativeMenu/>
</NativeMenuItem>
</NativeMenu>
@ -28,185 +27,25 @@
<NativeMenuBar DockPanel.Dock="Top"/>
<StackPanel DockPanel.Dock="Bottom" Margin="4" Orientation="Horizontal">
<TextBlock Margin="0,0,4,0">WindowState:</TextBlock>
<TextBlock Name="MainWindowState" Text="{Binding WindowState}"/>
<TextBlock Name="MainWindowState" Text="{Binding $parent[Window].WindowState}"/>
<TextBlock Name="AppOverlayPopups" Margin="8 0"/>
</StackPanel>
<TabControl TabStripPlacement="Left" Name="MainTabs">
<TabItem Header="Automation">
<StackPanel>
<TextBlock Name="TextBlockWithName">TextBlockWithName</TextBlock>
<TextBlock Name="NotTheAutomationId" AutomationProperties.AutomationId="TextBlockWithNameAndAutomationId">
TextBlockWithNameAndAutomationId
</TextBlock>
<TextBlock Name="TextBlockAsLabel">Label for TextBox</TextBlock>
<TextBox Name="LabeledByTextBox" AutomationProperties.LabeledBy="{Binding #TextBlockAsLabel}">
Foo
</TextBox>
</StackPanel>
</TabItem>
<TabItem Header="Button">
<StackPanel>
<Button Name="DisabledButton" IsEnabled="False">
Disabled Button
</Button>
<Button Name="EffectivelyDisabledButton" Command="{ReflectionBinding DoesntExist}">
Effectively Disabled Button
</Button>
<Button Name="BasicButton">
Basic Button
</Button>
<Button Name="ButtonWithTextBlock">
<TextBlock>Button with TextBlock</TextBlock>
</Button>
<Button Name="ButtonWithAcceleratorKey" HotKey="Ctrl+B">Button with Accelerator Key</Button>
</StackPanel>
</TabItem>
<TabItem Header="RadioButton">
<StackPanel Orientation="Vertical">
<RadioButton Name="BasicRadioButton">Sample RadioButton</RadioButton>
<StackPanel Orientation="Vertical">
<RadioButton Name="ThreeStatesRadioButton1" IsChecked="True" IsThreeState="True">Three States: Option 1</RadioButton>
<RadioButton Name="ThreeStatesRadioButton2" IsChecked="False" IsThreeState="True">Three States: Option 2</RadioButton>
</StackPanel>
</StackPanel>
</TabItem>
<TabItem Header="CheckBox">
<StackPanel>
<CheckBox Name="UncheckedCheckBox">Unchecked</CheckBox>
<CheckBox Name="CheckedCheckBox" IsChecked="True">Checked</CheckBox>
<CheckBox Name="ThreeStateCheckBox" IsThreeState="True" IsChecked="{x:Null}">ThreeState</CheckBox>
</StackPanel>
</TabItem>
<TabItem Header="ComboBox">
<StackPanel>
<ComboBox Name="BasicComboBox">
<ComboBoxItem>Item 0</ComboBoxItem>
<ComboBoxItem>Item 1</ComboBoxItem>
</ComboBox>
<CheckBox Name="ComboBoxWrapSelection" IsChecked="{Binding #BasicComboBox.WrapSelection}">Wrap Selection</CheckBox>
<Button Name="ComboBoxSelectionClear">Clear Selection</Button>
<Button Name="ComboBoxSelectFirst">Select First</Button>
</StackPanel>
</TabItem>
<TabItem Header="ContextMenu">
<StackPanel>
<Button Name="ShowContextMenu" Content="Right-click to show context menu.">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Name="ContextMenuItem1" Header="Item 1"/>
<MenuItem Name="ContextMenuItem2" Header="Item 2"/>
</ContextMenu>
</Button.ContextMenu>
</Button>
</StackPanel>
</TabItem>
<TabItem Header="Gestures">
<DockPanel>
<DockPanel DockPanel.Dock="Top">
<Button Name="ResetGestures" DockPanel.Dock="Right">Reset</Button>
<TextBlock Name="LastGesture" />
</DockPanel>
<Panel>
<Border Name="GestureBorder" Background="Blue"
AutomationProperties.AccessibilityView="Content"
AutomationProperties.ControlTypeOverride="Image"/>
<Border Name="GestureBorder2" Background="Green" IsVisible="False"
AutomationProperties.AccessibilityView="Content"
AutomationProperties.ControlTypeOverride="Image"/>
</Panel>
</DockPanel>
</TabItem>
<TabItem Header="ListBox">
<DockPanel>
<StackPanel DockPanel.Dock="Bottom">
<Button Name="ListBoxSelectionClear">Clear Selection</Button>
</StackPanel>
<ListBox Name="BasicListBox" ItemsSource="{Binding ListBoxItems}" SelectionMode="Multiple"/>
</DockPanel>
</TabItem>
<TabItem Header="Menu">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Name="RootMenuItem" Header="_Root">
<MenuItem Name="Child1MenuItem" Header="_Child 1" InputGesture="Ctrl+O" Click="MenuClicked"/>
<MenuItem Name="Child2MenuItem" Header="C_hild 2">
<MenuItem Name="GrandchildMenuItem" Header="_Grandchild" Click="MenuClicked"/>
</MenuItem>
</MenuItem>
</Menu>
<StackPanel>
<TextBlock Name="ClickedMenuItem">None</TextBlock>
<Button Name="MenuClickedMenuItemReset">Reset</Button>
<TextBox Name="MenuFocusTest"/>
</StackPanel>
</DockPanel>
</TabItem>
<TabItem Header="Window">
<Grid ColumnDefinitions="*,8,*">
<StackPanel Grid.Column="0">
<TextBox Name="ShowWindowSize" Watermark="Window Size"/>
<ComboBox Name="ShowWindowMode" SelectedIndex="0">
<ComboBoxItem>NonOwned</ComboBoxItem>
<ComboBoxItem>Owned</ComboBoxItem>
<ComboBoxItem>Modal</ComboBoxItem>
</ComboBox>
<ComboBox Name="ShowWindowLocation" SelectedIndex="0">
<ComboBoxItem>Manual</ComboBoxItem>
<ComboBoxItem>CenterScreen</ComboBoxItem>
<ComboBoxItem>CenterOwner</ComboBoxItem>
</ComboBox>
<ComboBox Name="ShowWindowState" SelectedIndex="0">
<ComboBoxItem Name="ShowWindowStateNormal">Normal</ComboBoxItem>
<ComboBoxItem Name="ShowWindowStateMinimized">Minimized</ComboBoxItem>
<ComboBoxItem Name="ShowWindowStateMaximized">Maximized</ComboBoxItem>
<ComboBoxItem Name="ShowWindowStateFullScreen">FullScreen</ComboBoxItem>
</ComboBox>
<ComboBox Name="ShowWindowSystemDecorations" SelectedIndex="2">
<ComboBoxItem Name="ShowWindowSystemDecorationsNone">None</ComboBoxItem>
<ComboBoxItem Name="ShowWindowSystemDecorationsBorderOnly">BorderOnly</ComboBoxItem>
<ComboBoxItem Name="ShowWindowSystemDecorationsFull">Full</ComboBoxItem>
</ComboBox>
<CheckBox Name="ShowWindowExtendClientAreaToDecorationsHint">ExtendClientAreaToDecorationsHint</CheckBox>
<CheckBox Name="ShowWindowCanResize" IsChecked="True">Can Resize</CheckBox>
<Button Name="ShowWindow">Show Window</Button>
<Button Name="SendToBack">Send to Back</Button>
<Button Name="EnterFullscreen">Enter Fullscreen</Button>
<Button Name="ExitFullscreen">Exit Fullscreen</Button>
<Button Name="RestoreAll">Restore All</Button>
</StackPanel>
<StackPanel Grid.Column="2">
<Button Name="ShowTransparentWindow">Transparent Window</Button>
<Button Name="ShowTransparentPopup">Transparent Popup</Button>
</StackPanel>
</Grid>
</TabItem>
<TabItem Header="Slider">
<DockPanel>
<DockPanel DockPanel.Dock="Top">
<TextBox Name="HorizontalSliderValue"
DockPanel.Dock="Right"
Text="{Binding #HorizontalSlider.Value, Mode=OneWay, StringFormat=\{0:0\}}"
VerticalAlignment="Top"/>
<Slider Name="HorizontalSlider" Value="50"/>
</DockPanel>
<Button Name="ResetSliders">Reset</Button>
</DockPanel>
</TabItem>
<TabItem Header="ScrollBar">
<ScrollBar Name="MyScrollBar" Orientation="Horizontal" AllowAutoHide="False" Width="200" Height="30" Value="20"/>
</TabItem>
</TabControl>
<DockPanel>
<ListBox Name="Pager"
DockPanel.Dock="Left"
DisplayMemberBinding="{Binding Name}"
ItemsSource="{Binding Pages}"
SelectedItem="{Binding SelectedPage}"
SelectionChanged="Pager_SelectionChanged">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
<Decorator Name="PagerContent"/>
</DockPanel>
</DockPanel>
</Window>

301
samples/IntegrationTestApp/MainWindow.axaml.cs

@ -1,289 +1,96 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia;
using Avalonia.Automation;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Primitives.PopupPositioning;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.VisualTree;
using Microsoft.CodeAnalysis;
using IntegrationTestApp.Models;
using IntegrationTestApp.Pages;
using IntegrationTestApp.ViewModels;
namespace IntegrationTestApp
{
public class MainWindow : Window
public partial class MainWindow : Window
{
public MainWindow()
{
// Set name in code behind, so source generator will ignore it.
Name = "MainWindow";
InitializeComponent();
InitializeViewMenu();
InitializeGesturesTab();
this.AttachDevTools();
var overlayPopups = this.Get<TextBlock>("AppOverlayPopups");
overlayPopups.Text = Program.OverlayPopups ? "Overlay Popups" : "Native Popups";
var viewModel = new MainWindowViewModel(CreatePages());
InitializeViewMenu(viewModel.Pages);
AddHandler(Button.ClickEvent, OnButtonClick);
ListBoxItems = Enumerable.Range(0, 100).Select(x => "Item " + x).ToList();
DataContext = this;
DataContext = viewModel;
AppOverlayPopups.Text = Program.OverlayPopups ? "Overlay Popups" : "Native Popups";
PositionChanged += OnPositionChanged;
}
public List<string> ListBoxItems { get; }
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
private MainWindowViewModel? ViewModel => (MainWindowViewModel?)DataContext;
private void InitializeViewMenu()
private void InitializeViewMenu(IEnumerable<Page> pages)
{
var mainTabs = this.Get<TabControl>("MainTabs");
var viewMenu = (NativeMenuItem?)NativeMenu.GetMenu(this)?.Items[1];
foreach (var tabItem in mainTabs.Items.Cast<TabItem>())
foreach (var page in pages)
{
var menuItem = new NativeMenuItem
{
Header = (string?)tabItem.Header,
ToolTip = $"Tip:{(string?)tabItem.Header}",
IsChecked = tabItem.IsSelected,
Header = (string?)page.Name,
ToolTip = $"Tip:{(string?)page.Name}",
ToggleType = NativeMenuItemToggleType.Radio,
};
menuItem.Click += (_, _) => tabItem.IsSelected = true;
viewMenu?.Menu?.Items.Add(menuItem);
}
}
private void ShowWindow()
{
var sizeTextBox = this.GetControl<TextBox>("ShowWindowSize");
var modeComboBox = this.GetControl<ComboBox>("ShowWindowMode");
var locationComboBox = this.GetControl<ComboBox>("ShowWindowLocation");
var stateComboBox = this.GetControl<ComboBox>("ShowWindowState");
var size = !string.IsNullOrWhiteSpace(sizeTextBox.Text) ? Size.Parse(sizeTextBox.Text) : (Size?)null;
var systemDecorations = this.GetControl<ComboBox>("ShowWindowSystemDecorations");
var extendClientArea = this.GetControl<CheckBox>("ShowWindowExtendClientAreaToDecorationsHint");
var canResizeCheckBox = this.GetControl<CheckBox>("ShowWindowCanResize");
var owner = (Window)this.GetVisualRoot()!;
var window = new ShowWindowTest
{
WindowStartupLocation = (WindowStartupLocation)locationComboBox.SelectedIndex,
CanResize = canResizeCheckBox.IsChecked ?? false,
};
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime lifetime)
{
// Make sure the windows have unique names and AutomationIds.
var existing = lifetime.Windows.OfType<ShowWindowTest>().Count();
if (existing > 0)
menuItem.Click += (_, _) =>
{
AutomationProperties.SetAutomationId(window, window.Name + (existing + 1));
window.Title += $" {existing + 1}";
}
}
if (size.HasValue)
{
window.Width = size.Value.Width;
window.Height = size.Value.Height;
}
sizeTextBox.Text = string.Empty;
window.ExtendClientAreaToDecorationsHint = extendClientArea.IsChecked ?? false;
window.SystemDecorations = (SystemDecorations)systemDecorations.SelectedIndex;
window.WindowState = (WindowState)stateComboBox.SelectedIndex;
if (ViewModel is { } viewModel)
viewModel.SelectedPage = page;
};
switch (modeComboBox.SelectedIndex)
{
case 0:
window.Show();
break;
case 1:
window.Show(owner);
break;
case 2:
window.ShowDialog(owner);
break;
viewMenu?.Menu?.Items.Add(menuItem);
}
}
private void ShowTransparentWindow()
{
// Show a background window to make sure the color behind the transparent window is
// a known color (green).
var backgroundWindow = new Window
{
Title = "Transparent Window Background",
Name = "TransparentWindowBackground",
Width = 300,
Height = 300,
Background = Brushes.Green,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
};
// This is the transparent window with a red circle.
var window = new Window
{
Title = "Transparent Window",
Name = "TransparentWindow",
SystemDecorations = SystemDecorations.None,
Background = Brushes.Transparent,
TransparencyLevelHint = new[] { WindowTransparencyLevel.Transparent },
WindowStartupLocation = WindowStartupLocation.CenterOwner,
Width = 200,
Height = 200,
Content = new Border
{
Background = Brushes.Red,
CornerRadius = new CornerRadius(100),
}
};
window.PointerPressed += (_, _) =>
{
window.Close();
backgroundWindow.Close();
};
backgroundWindow.Show(this);
window.Show(backgroundWindow);
}
private void ShowTransparentPopup()
private void Pager_SelectionChanged(object? sender, SelectionChangedEventArgs e)
{
var popup = new Popup
{
WindowManagerAddShadowHint = false,
Placement = PlacementMode.AnchorAndGravity,
PlacementAnchor = PopupAnchor.Top,
PlacementGravity = PopupGravity.Bottom,
Width= 200,
Height= 200,
Child = new Border
{
Background = Brushes.Red,
CornerRadius = new CornerRadius(100),
}
};
// Show a background window to make sure the color behind the transparent window is
// a known color (green).
var backgroundWindow = new Window
{
Title = "Transparent Popup Background",
Name = "TransparentPopupBackground",
Width = 200,
Height = 200,
Background = Brushes.Green,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
Content = new Border
{
Name = "PopupContainer",
Child = popup,
[AutomationProperties.AccessibilityViewProperty] = AccessibilityView.Content,
}
};
backgroundWindow.PointerPressed += (_, _) => backgroundWindow.Close();
backgroundWindow.Show(this);
popup.Open();
if (Pager.SelectedItem is Page page)
PagerContent.Child = page.CreateContent();
}
private void SendToBack()
private void OnPositionChanged(object? sender, PixelPointEventArgs e)
{
var lifetime = (ClassicDesktopStyleApplicationLifetime)Application.Current!.ApplicationLifetime!;
foreach (var window in lifetime.Windows.ToArray())
// HACK: Toggling the window decorations can cause the window to be moved off screen,
// causing test failures. Until this bug is fixed, detect this and move the window
// to the screen origin. See #11411.
if (Screens.ScreenFromWindow(this) is { } screen)
{
window.Activate();
}
}
private void RestoreAll()
{
var lifetime = (ClassicDesktopStyleApplicationLifetime)Application.Current!.ApplicationLifetime!;
var bounds = new PixelRect(
e.Point,
PixelSize.FromSize(ClientSize, DesktopScaling));
foreach (var window in lifetime.Windows.ToArray())
{
window.Show();
if (window.WindowState == WindowState.Minimized)
window.WindowState = WindowState.Normal;
if (!screen.WorkingArea.Contains(bounds))
Position = screen.WorkingArea.Position;
}
}
private void InitializeGesturesTab()
{
var gestureBorder = this.GetControl<Border>("GestureBorder");
var gestureBorder2 = this.GetControl<Border>("GestureBorder2");
var lastGesture = this.GetControl<TextBlock>("LastGesture");
var resetGestures = this.GetControl<Button>("ResetGestures");
gestureBorder.Tapped += (_, _) => lastGesture.Text = "Tapped";
gestureBorder.DoubleTapped += (_, _) =>
{
lastGesture.Text = "DoubleTapped";
// Testing #8733
gestureBorder.IsVisible = false;
gestureBorder2.IsVisible = true;
};
gestureBorder2.DoubleTapped += (_, _) =>
{
lastGesture.Text = "DoubleTapped2";
};
Gestures.AddRightTappedHandler(gestureBorder, (_, _) => lastGesture.Text = "RightTapped");
resetGestures.Click += (_, _) =>
{
lastGesture.Text = string.Empty;
gestureBorder.IsVisible = true;
gestureBorder2.IsVisible = false;
};
}
private void MenuClicked(object? sender, RoutedEventArgs e)
private static IEnumerable<Page> CreatePages()
{
var clickedMenuItemTextBlock = this.Get<TextBlock>("ClickedMenuItem");
clickedMenuItemTextBlock.Text = (sender as MenuItem)?.Header?.ToString();
}
private void OnButtonClick(object? sender, RoutedEventArgs e)
{
var source = e.Source as Button;
if (source?.Name == "ComboBoxSelectionClear")
this.Get<ComboBox>("BasicComboBox").SelectedIndex = -1;
if (source?.Name == "ComboBoxSelectFirst")
this.Get<ComboBox>("BasicComboBox").SelectedIndex = 0;
if (source?.Name == "ListBoxSelectionClear")
this.Get<ListBox>("BasicListBox").SelectedIndex = -1;
if (source?.Name == "MenuClickedMenuItemReset")
this.Get<TextBlock>("ClickedMenuItem").Text = "None";
if (source?.Name == "ResetSliders")
this.Get<Slider>("HorizontalSlider").Value = 50;
if (source?.Name == "ShowTransparentWindow")
ShowTransparentWindow();
if (source?.Name == "ShowTransparentPopup")
ShowTransparentPopup();
if (source?.Name == "ShowWindow")
ShowWindow();
if (source?.Name == "SendToBack")
SendToBack();
if (source?.Name == "EnterFullscreen")
WindowState = WindowState.FullScreen;
if (source?.Name == "ExitFullscreen")
WindowState = WindowState.Normal;
if (source?.Name == "RestoreAll")
RestoreAll();
return
[
new("Automation", () => new AutomationPage()),
new("Button", () => new ButtonPage()),
new("CheckBox", () => new CheckBoxPage()),
new("ComboBox", () => new ComboBoxPage()),
new("ContextMenu", () => new ContextMenuPage()),
new("DesktopPage", () => new DesktopPage()),
new("Gestures", () => new GesturesPage()),
new("ListBox", () => new ListBoxPage()),
new("Menu", () => new MenuPage()),
new("RadioButton", () => new RadioButtonPage()),
new("ScrollBar", () => new ScrollBarPage()),
new("Slider", () => new SliderPage()),
new("Window Decorations", () => new WindowDecorationsPage()),
new("Window", () => new WindowPage()),
];
}
}
}

6
samples/IntegrationTestApp/Models/Page.cs

@ -0,0 +1,6 @@
using System;
using Avalonia.Controls;
namespace IntegrationTestApp.Models;
internal record Page(string Name, Func<Control> CreateContent);

17
samples/IntegrationTestApp/Pages/AutomationPage.axaml

@ -0,0 +1,17 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.Pages.AutomationPage">
<StackPanel>
<TextBlock Name="TextBlockWithName">TextBlockWithName</TextBlock>
<TextBlock Name="NotTheAutomationId" AutomationProperties.AutomationId="TextBlockWithNameAndAutomationId">
TextBlockWithNameAndAutomationId
</TextBlock>
<TextBlock Name="TextBlockAsLabel">Label for TextBox</TextBlock>
<TextBox Name="LabeledByTextBox" AutomationProperties.LabeledBy="{Binding #TextBlockAsLabel}">
Foo
</TextBox>
</StackPanel>
</UserControl>

11
samples/IntegrationTestApp/Pages/AutomationPage.axaml.cs

@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace IntegrationTestApp.Pages;
public partial class AutomationPage : UserControl
{
public AutomationPage()
{
InitializeComponent();
}
}

22
samples/IntegrationTestApp/Pages/ButtonPage.axaml

@ -0,0 +1,22 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.Pages.ButtonPage">
<StackPanel>
<Button Name="DisabledButton" IsEnabled="False">
Disabled Button
</Button>
<Button Name="EffectivelyDisabledButton" Command="{ReflectionBinding DoesntExist}">
Effectively Disabled Button
</Button>
<Button Name="BasicButton">
Basic Button
</Button>
<Button Name="ButtonWithTextBlock">
<TextBlock>Button with TextBlock</TextBlock>
</Button>
<Button Name="ButtonWithAcceleratorKey" HotKey="Ctrl+B">Button with Accelerator Key</Button>
</StackPanel>
</UserControl>

11
samples/IntegrationTestApp/Pages/ButtonPage.axaml.cs

@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace IntegrationTestApp.Pages;
public partial class ButtonPage : UserControl
{
public ButtonPage()
{
InitializeComponent();
}
}

12
samples/IntegrationTestApp/Pages/CheckBoxPage.axaml

@ -0,0 +1,12 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.Pages.CheckBoxPage">
<StackPanel>
<CheckBox Name="UncheckedCheckBox">Unchecked</CheckBox>
<CheckBox Name="CheckedCheckBox" IsChecked="True">Checked</CheckBox>
<CheckBox Name="ThreeStateCheckBox" IsThreeState="True" IsChecked="{x:Null}">ThreeState</CheckBox>
</StackPanel>
</UserControl>

11
samples/IntegrationTestApp/Pages/CheckBoxPage.axaml.cs

@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace IntegrationTestApp.Pages;
public partial class CheckBoxPage : UserControl
{
public CheckBoxPage()
{
InitializeComponent();
}
}

16
samples/IntegrationTestApp/Pages/ComboBoxPage.axaml

@ -0,0 +1,16 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.Pages.ComboBoxPage">
<StackPanel>
<ComboBox Name="BasicComboBox">
<ComboBoxItem>Item 0</ComboBoxItem>
<ComboBoxItem>Item 1</ComboBoxItem>
</ComboBox>
<CheckBox Name="ComboBoxWrapSelection" IsChecked="{Binding #BasicComboBox.WrapSelection}">Wrap Selection</CheckBox>
<Button Name="ComboBoxSelectionClear" Click="ComboBoxSelectionClear_Click">Clear Selection</Button>
<Button Name="ComboBoxSelectFirst" Click="ComboBoxSelectFirst_Click">Select First</Button>
</StackPanel>
</UserControl>

22
samples/IntegrationTestApp/Pages/ComboBoxPage.axaml.cs

@ -0,0 +1,22 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
namespace IntegrationTestApp.Pages;
public partial class ComboBoxPage : UserControl
{
public ComboBoxPage()
{
InitializeComponent();
}
private void ComboBoxSelectionClear_Click(object? sender, RoutedEventArgs e)
{
BasicComboBox.SelectedIndex = -1;
}
private void ComboBoxSelectFirst_Click(object? sender, RoutedEventArgs e)
{
BasicComboBox.SelectedIndex = 0;
}
}

17
samples/IntegrationTestApp/Pages/ContextMenuPage.axaml

@ -0,0 +1,17 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.Pages.ContextMenuPage">
<StackPanel>
<Button Name="ShowContextMenu" Content="Right-click to show context menu.">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Name="ContextMenuItem1" Header="Item 1"/>
<MenuItem Name="ContextMenuItem2" Header="Item 2"/>
</ContextMenu>
</Button.ContextMenu>
</Button>
</StackPanel>
</UserControl>

11
samples/IntegrationTestApp/Pages/ContextMenuPage.axaml.cs

@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace IntegrationTestApp.Pages;
public partial class ContextMenuPage : UserControl
{
public ContextMenuPage()
{
InitializeComponent();
}
}

14
samples/IntegrationTestApp/Pages/DesktopPage.axaml

@ -0,0 +1,14 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.Pages.DesktopPage">
<StackPanel>
<CheckBox x:FieldModifier="public" Name="TrayIconClicked">Tray Icon Clicked</CheckBox>
<CheckBox x:FieldModifier="public" Name="TrayIconMenuClicked">Tray Icon Menu Clicked</CheckBox>
<Button Name="ToggleTrayIconVisible"
Content="Toggle TrayIcon Visible"
Click="ToggleTrayIconVisible_Click"/>
</StackPanel>
</UserControl>

19
samples/IntegrationTestApp/Pages/DesktopPage.axaml.cs

@ -0,0 +1,19 @@
using System.Linq;
using Avalonia;
using Avalonia.Controls;
namespace IntegrationTestApp.Pages;
public partial class DesktopPage : UserControl
{
public DesktopPage()
{
InitializeComponent();
}
private void ToggleTrayIconVisible_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
var icon = TrayIcon.GetIcons(Application.Current!)!.FirstOrDefault()!;
icon.IsVisible = !icon.IsVisible;
}
}

29
samples/IntegrationTestApp/Pages/GesturesPage.axaml

@ -0,0 +1,29 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.Pages.GesturesPage">
<DockPanel>
<DockPanel DockPanel.Dock="Top">
<Button Name="ResetGestures"
DockPanel.Dock="Right"
Click="ResetGestures_Click">
Reset
</Button>
<TextBlock Name="LastGesture" />
</DockPanel>
<Panel>
<Border Name="GestureBorder" Background="Blue"
AutomationProperties.AccessibilityView="Content"
AutomationProperties.ControlTypeOverride="Image"
Tapped="GestureBorder_Tapped"
DoubleTapped="GestureBorder_DoubleTapped"
Gestures.RightTapped="GestureBorder_RightTapped"/>
<Border Name="GestureBorder2" Background="Green" IsVisible="False"
AutomationProperties.AccessibilityView="Content"
AutomationProperties.ControlTypeOverride="Image"
DoubleTapped="GestureBorder2_DoubleTapped"/>
</Panel>
</DockPanel>
</UserControl>

44
samples/IntegrationTestApp/Pages/GesturesPage.axaml.cs

@ -0,0 +1,44 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
namespace IntegrationTestApp.Pages;
public partial class GesturesPage : UserControl
{
public GesturesPage()
{
InitializeComponent();
}
private void GestureBorder_Tapped(object? sender, TappedEventArgs e)
{
LastGesture.Text = "Tapped";
}
private void GestureBorder_DoubleTapped(object? sender, TappedEventArgs e)
{
LastGesture.Text = "DoubleTapped";
// Testing #8733
GestureBorder.IsVisible = false;
GestureBorder2.IsVisible = true;
}
private void GestureBorder_RightTapped(object? sender, RoutedEventArgs e)
{
LastGesture.Text = "RightTapped";
}
private void GestureBorder2_DoubleTapped(object? sender, TappedEventArgs e)
{
LastGesture.Text = "DoubleTapped2";
}
private void ResetGestures_Click(object? sender, RoutedEventArgs e)
{
LastGesture.Text = string.Empty;
GestureBorder.IsVisible = true;
GestureBorder2.IsVisible = false;
}
}

15
samples/IntegrationTestApp/Pages/ListBoxPage.axaml

@ -0,0 +1,15 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pages="using:IntegrationTestApp.Pages"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.Pages.ListBoxPage"
x:DataType="pages:ListBoxPage">
<DockPanel>
<StackPanel DockPanel.Dock="Bottom">
<Button Name="ListBoxSelectionClear" Click="ListBoxSelectionClear_Click">Clear Selection</Button>
</StackPanel>
<ListBox Name="BasicListBox" ItemsSource="{Binding ListBoxItems}" SelectionMode="Multiple"/>
</DockPanel>
</UserControl>

23
samples/IntegrationTestApp/Pages/ListBoxPage.axaml.cs

@ -0,0 +1,23 @@
using System.Collections.Generic;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Interactivity;
namespace IntegrationTestApp.Pages;
public partial class ListBoxPage : UserControl
{
public ListBoxPage()
{
InitializeComponent();
ListBoxItems = Enumerable.Range(0, 100).Select(x => "Item " + x).ToList();
DataContext = this;
}
public List<string> ListBoxItems { get; }
private void ListBoxSelectionClear_Click(object? sender, RoutedEventArgs e)
{
BasicListBox.SelectedIndex = -1;
}
}

22
samples/IntegrationTestApp/Pages/MenuPage.axaml

@ -0,0 +1,22 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.Pages.MenuPage">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Name="RootMenuItem" Header="_Root">
<MenuItem Name="Child1MenuItem" Header="_Child 1" InputGesture="Ctrl+O" Click="MenuClicked"/>
<MenuItem Name="Child2MenuItem" Header="C_hild 2">
<MenuItem Name="GrandchildMenuItem" Header="_Grandchild" Click="MenuClicked"/>
</MenuItem>
</MenuItem>
</Menu>
<StackPanel>
<TextBlock Name="ClickedMenuItem">None</TextBlock>
<Button Name="MenuClickedMenuItemReset" Click="MenuClickedMenuItemReset_Click">Reset</Button>
<TextBox Name="MenuFocusTest"/>
</StackPanel>
</DockPanel>
</UserControl>

24
samples/IntegrationTestApp/Pages/MenuPage.axaml.cs

@ -0,0 +1,24 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
namespace IntegrationTestApp.Pages;
public partial class MenuPage : UserControl
{
public MenuPage()
{
InitializeComponent();
}
private void MenuClicked(object? sender, RoutedEventArgs e)
{
var clickedMenuItemTextBlock = ClickedMenuItem;
clickedMenuItemTextBlock.Text = (sender as MenuItem)?.Header?.ToString();
}
private void MenuClickedMenuItemReset_Click(object? sender, RoutedEventArgs e)
{
ClickedMenuItem.Text = "None";
}
}

14
samples/IntegrationTestApp/Pages/RadioButtonPage.axaml

@ -0,0 +1,14 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.Pages.RadioButtonPage">
<StackPanel Orientation="Vertical">
<RadioButton Name="BasicRadioButton">Sample RadioButton</RadioButton>
<StackPanel Orientation="Vertical">
<RadioButton Name="ThreeStatesRadioButton1" IsChecked="True" IsThreeState="True">Three States: Option 1</RadioButton>
<RadioButton Name="ThreeStatesRadioButton2" IsChecked="False" IsThreeState="True">Three States: Option 2</RadioButton>
</StackPanel>
</StackPanel>
</UserControl>

11
samples/IntegrationTestApp/Pages/RadioButtonPage.axaml.cs

@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace IntegrationTestApp.Pages;
public partial class RadioButtonPage : UserControl
{
public RadioButtonPage()
{
InitializeComponent();
}
}

8
samples/IntegrationTestApp/Pages/ScrollBarPage.axaml

@ -0,0 +1,8 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.Pages.ScrollBarPage">
<ScrollBar Name="MyScrollBar" Orientation="Horizontal" AllowAutoHide="False" Width="200" Height="30" Value="20"/>
</UserControl>

11
samples/IntegrationTestApp/Pages/ScrollBarPage.axaml.cs

@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace IntegrationTestApp.Pages;
public partial class ScrollBarPage : UserControl
{
public ScrollBarPage()
{
InitializeComponent();
}
}

17
samples/IntegrationTestApp/Pages/SliderPage.axaml

@ -0,0 +1,17 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.Pages.SliderPage">
<DockPanel>
<DockPanel DockPanel.Dock="Top">
<TextBox Name="HorizontalSliderValue"
DockPanel.Dock="Right"
Text="{Binding #HorizontalSlider.Value, Mode=OneWay, StringFormat=\{0:0\}}"
VerticalAlignment="Top"/>
<Slider Name="HorizontalSlider" Value="50"/>
</DockPanel>
<Button Name="ResetSliders" Click="ResetSliders_Click">Reset</Button>
</DockPanel>
</UserControl>

17
samples/IntegrationTestApp/Pages/SliderPage.axaml.cs

@ -0,0 +1,17 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
namespace IntegrationTestApp.Pages;
public partial class SliderPage : UserControl
{
public SliderPage()
{
InitializeComponent();
}
private void ResetSliders_Click(object? sender, RoutedEventArgs e)
{
HorizontalSlider.Value = 50;
}
}

21
samples/IntegrationTestApp/Pages/WindowDecorationsPage.axaml

@ -0,0 +1,21 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.Pages.WindowDecorationsPage">
<StackPanel Spacing="4">
<CheckBox Name="WindowExtendClientAreaToDecorationsHint" Content="Extend Client Area to Decorations" />
<CheckBox Name="WindowForceSystemChrome" Content="Force SystemChrome" />
<CheckBox Name="WindowPreferSystemChrome" Content="Prefer SystemChrome" />
<CheckBox Name="WindowMacThickSystemChrome" Content="Mac Thick SystemChrome" />
<TextBox Name="WindowTitleBarHeightHint" Text="-1" Watermark="In dips" />
<Button Name="ApplyWindowDecorations"
Content="Apply decorations on this Window"
Click="ApplyWindowDecorations_Click"/>
<Button Name="ShowNewWindowDecorations"
Content="Show new Window with decorations"
Click="ShowNewWindowDecorations_Click"/>
<TextBox Name="WindowDecorationProperties" AcceptsReturn="True" />
</StackPanel>
</UserControl>

63
samples/IntegrationTestApp/Pages/WindowDecorationsPage.axaml.cs

@ -0,0 +1,63 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
using Avalonia.Platform;
namespace IntegrationTestApp.Pages;
public partial class WindowDecorationsPage : UserControl
{
public WindowDecorationsPage()
{
InitializeComponent();
}
private void SetWindowDecorations(Window window)
{
window.ExtendClientAreaToDecorationsHint = WindowExtendClientAreaToDecorationsHint.IsChecked!.Value;
window.ExtendClientAreaTitleBarHeightHint =
int.TryParse(WindowTitleBarHeightHint.Text, out var val) ? val / window.DesktopScaling : -1;
window.ExtendClientAreaChromeHints = ExtendClientAreaChromeHints.NoChrome
| (WindowForceSystemChrome.IsChecked == true ? ExtendClientAreaChromeHints.SystemChrome : 0)
| (WindowPreferSystemChrome.IsChecked == true ? ExtendClientAreaChromeHints.PreferSystemChrome : 0)
| (WindowMacThickSystemChrome.IsChecked == true ? ExtendClientAreaChromeHints.OSXThickTitleBar : 0);
AdjustOffsets(window);
window.Background = Brushes.Transparent;
window.PropertyChanged += WindowOnPropertyChanged;
void WindowOnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
var window = (Window)sender!;
if (e.Property == Window.OffScreenMarginProperty || e.Property == Window.WindowDecorationMarginProperty)
{
AdjustOffsets(window);
}
}
void AdjustOffsets(Window window)
{
var scaling = window.DesktopScaling;
window.Padding = window.OffScreenMargin;
((Control)window.Content!).Margin = window.WindowDecorationMargin;
WindowDecorationProperties.Text =
$"{window.OffScreenMargin.Top * scaling} {window.WindowDecorationMargin.Top * scaling} {window.IsExtendedIntoWindowDecorations}";
}
}
private void ApplyWindowDecorations_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
var window = TopLevel.GetTopLevel(this) as Window ??
throw new AvaloniaInternalException("WindowDecorationsPage is not attached to a Window.");
SetWindowDecorations(window);
}
private void ShowNewWindowDecorations_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
var window = new ShowWindowTest();
SetWindowDecorations(window);
window.Show();
}
}

44
samples/IntegrationTestApp/Pages/WindowPage.axaml

@ -0,0 +1,44 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="IntegrationTestApp.Pages.WindowPage">
<Grid ColumnDefinitions="*,8,*">
<StackPanel Grid.Column="0">
<TextBox Name="ShowWindowSize" Watermark="Window Size"/>
<ComboBox Name="ShowWindowMode" SelectedIndex="0">
<ComboBoxItem>NonOwned</ComboBoxItem>
<ComboBoxItem>Owned</ComboBoxItem>
<ComboBoxItem>Modal</ComboBoxItem>
</ComboBox>
<ComboBox Name="ShowWindowLocation" SelectedIndex="0">
<ComboBoxItem>Manual</ComboBoxItem>
<ComboBoxItem>CenterScreen</ComboBoxItem>
<ComboBoxItem>CenterOwner</ComboBoxItem>
</ComboBox>
<ComboBox Name="ShowWindowState" SelectedIndex="0">
<ComboBoxItem Name="ShowWindowStateNormal">Normal</ComboBoxItem>
<ComboBoxItem Name="ShowWindowStateMinimized">Minimized</ComboBoxItem>
<ComboBoxItem Name="ShowWindowStateMaximized">Maximized</ComboBoxItem>
<ComboBoxItem Name="ShowWindowStateFullScreen">FullScreen</ComboBoxItem>
</ComboBox>
<ComboBox Name="ShowWindowSystemDecorations" SelectedIndex="2">
<ComboBoxItem Name="ShowWindowSystemDecorationsNone">None</ComboBoxItem>
<ComboBoxItem Name="ShowWindowSystemDecorationsBorderOnly">BorderOnly</ComboBoxItem>
<ComboBoxItem Name="ShowWindowSystemDecorationsFull">Full</ComboBoxItem>
</ComboBox>
<CheckBox Name="ShowWindowExtendClientAreaToDecorationsHint">ExtendClientAreaToDecorationsHint</CheckBox>
<CheckBox Name="ShowWindowCanResize" IsChecked="True">Can Resize</CheckBox>
<Button Name="ShowWindow" Click="ShowWindow_Click">Show Window</Button>
<Button Name="SendToBack" Click="SendToBack_Click">Send to Back</Button>
<Button Name="EnterFullscreen" Click="EnterFullscreen_Click">Enter Fullscreen</Button>
<Button Name="ExitFullscreen" Click="ExitFullscreen_Click">Exit Fullscreen</Button>
<Button Name="RestoreAll" Click="RestoreAll_Click">Restore All</Button>
</StackPanel>
<StackPanel Grid.Column="2">
<Button Name="ShowTransparentWindow" Click="ShowTransparentWindow_Click">Transparent Window</Button>
<Button Name="ShowTransparentPopup" Click="ShowTransparentPopup_Click">Transparent Popup</Button>
</StackPanel>
</Grid>
</UserControl>

182
samples/IntegrationTestApp/Pages/WindowPage.axaml.cs

@ -0,0 +1,182 @@
using System.Linq;
using Avalonia;
using Avalonia.Automation;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Primitives.PopupPositioning;
using Avalonia.Interactivity;
using Avalonia.Media;
namespace IntegrationTestApp.Pages;
public partial class WindowPage : UserControl
{
public WindowPage()
{
InitializeComponent();
}
private Window Window => TopLevel.GetTopLevel(this) as Window ??
throw new AvaloniaInternalException("WindowPage is not attached to a Window.");
private void ShowWindow_Click(object? sender, RoutedEventArgs e)
{
var size = !string.IsNullOrWhiteSpace(ShowWindowSize.Text) ? Size.Parse(ShowWindowSize.Text) : (Size?)null;
var window = new ShowWindowTest
{
WindowStartupLocation = (WindowStartupLocation)ShowWindowLocation.SelectedIndex,
CanResize = ShowWindowCanResize.IsChecked ?? false,
};
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime lifetime)
{
// Make sure the windows have unique names and AutomationIds.
var existing = lifetime.Windows.OfType<ShowWindowTest>().Count();
if (existing > 0)
{
AutomationProperties.SetAutomationId(window, window.Name + (existing + 1));
window.Title += $" {existing + 1}";
}
}
if (size.HasValue)
{
window.Width = size.Value.Width;
window.Height = size.Value.Height;
}
ShowWindowSize.Text = string.Empty;
window.ExtendClientAreaToDecorationsHint = ShowWindowExtendClientAreaToDecorationsHint.IsChecked ?? false;
window.SystemDecorations = (SystemDecorations)ShowWindowSystemDecorations.SelectedIndex;
window.WindowState = (WindowState)ShowWindowState.SelectedIndex;
switch (ShowWindowMode.SelectedIndex)
{
case 0:
window.Show();
break;
case 1:
window.Show(Window);
break;
case 2:
window.ShowDialog(Window);
break;
}
}
private void ShowTransparentWindow_Click(object? sender, RoutedEventArgs e)
{
// Show a background window to make sure the color behind the transparent window is
// a known color (green).
var backgroundWindow = new Window
{
Title = "Transparent Window Background",
Name = "TransparentWindowBackground",
Width = 300,
Height = 300,
Background = Brushes.Green,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
};
// This is the transparent window with a red circle.
var window = new Window
{
Title = "Transparent Window",
Name = "TransparentWindow",
SystemDecorations = SystemDecorations.None,
Background = Brushes.Transparent,
TransparencyLevelHint = new[] { WindowTransparencyLevel.Transparent },
WindowStartupLocation = WindowStartupLocation.CenterOwner,
Width = 200,
Height = 200,
Content = new Border
{
Background = Brushes.Red,
CornerRadius = new CornerRadius(100),
}
};
window.PointerPressed += (_, _) =>
{
window.Close();
backgroundWindow.Close();
};
backgroundWindow.Show(Window);
window.Show(backgroundWindow);
}
private void ShowTransparentPopup_Click(object? sender, RoutedEventArgs e)
{
var popup = new Popup
{
WindowManagerAddShadowHint = false,
Placement = PlacementMode.AnchorAndGravity,
PlacementAnchor = PopupAnchor.Top,
PlacementGravity = PopupGravity.Bottom,
Width = 200,
Height = 200,
Child = new Border
{
Background = Brushes.Red,
CornerRadius = new CornerRadius(100),
}
};
// Show a background window to make sure the color behind the transparent window is
// a known color (green).
var backgroundWindow = new Window
{
Title = "Transparent Popup Background",
Name = "TransparentPopupBackground",
Width = 200,
Height = 200,
Background = Brushes.Green,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
Content = new Border
{
Name = "PopupContainer",
Child = popup,
[AutomationProperties.AccessibilityViewProperty] = AccessibilityView.Content,
}
};
backgroundWindow.PointerPressed += (_, _) => backgroundWindow.Close();
backgroundWindow.Show(Window);
popup.Open();
}
private void SendToBack_Click(object? sender, RoutedEventArgs e)
{
var lifetime = (ClassicDesktopStyleApplicationLifetime)Application.Current!.ApplicationLifetime!;
foreach (var window in lifetime.Windows.ToArray())
{
window.Activate();
}
}
private void EnterFullscreen_Click(object? sender, RoutedEventArgs e)
{
Window.WindowState = WindowState.FullScreen;
}
private void ExitFullscreen_Click(object? sender, RoutedEventArgs e)
{
Window.WindowState = WindowState.Normal;
}
private void RestoreAll_Click(object? sender, RoutedEventArgs e)
{
var lifetime = (ClassicDesktopStyleApplicationLifetime)Application.Current!.ApplicationLifetime!;
foreach (var window in lifetime.Windows.ToArray())
{
window.Show();
if (window.WindowState == WindowState.Minimized)
window.WindowState = WindowState.Normal;
}
}
}

8
samples/IntegrationTestApp/ShowWindowTest.axaml.cs

@ -2,7 +2,6 @@ using System;
using System.Runtime.InteropServices;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Threading;
namespace IntegrationTestApp
@ -26,7 +25,7 @@ namespace IntegrationTestApp
}
}
public class ShowWindowTest : Window
public partial class ShowWindowTest : Window
{
private readonly DispatcherTimer? _timer;
private readonly TextBox? _orderTextBox;
@ -45,11 +44,6 @@ namespace IntegrationTestApp
_timer.Start();
}
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
protected override void OnOpened(EventArgs e)
{

23
samples/IntegrationTestApp/ViewModels/MainWindowViewModel.cs

@ -0,0 +1,23 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using IntegrationTestApp.Models;
namespace IntegrationTestApp.ViewModels;
internal class MainWindowViewModel : ViewModelBase
{
private Page? _selectedPage;
public MainWindowViewModel(IEnumerable<Page> pages)
{
Pages = new(pages);
}
public ObservableCollection<Page> Pages { get; }
public Page? SelectedPage
{
get => _selectedPage;
set => RaiseAndSetIfChanged(ref _selectedPage, value);
}
}

24
samples/IntegrationTestApp/ViewModels/ViewModelBase.cs

@ -0,0 +1,24 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace IntegrationTestApp.ViewModels;
internal class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected bool RaiseAndSetIfChanged<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
RaisePropertyChanged(propertyName);
return true;
}
return false;
}
protected void RaisePropertyChanged([CallerMemberName] string? propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

12
src/Android/Avalonia.Android/AndroidInputMethod.cs

@ -117,16 +117,20 @@ namespace Avalonia.Android
private void OnSelectionChanged()
{
if (Client is null)
if (Client is null || _inputConnection is null)
{
return;
}
OnSurroundingTextChanged();
var selection = Client.Selection;
_imm.UpdateSelection(_host, selection.Start, selection.End, selection.Start, selection.End);
_inputConnection.SetSelection(selection.Start, selection.End);
var composition = _inputConnection.EditableWrapper.CurrentComposition;
_inputConnection?.SetSelection(selection.Start, selection.End);
_imm.UpdateSelection(_host, selection.Start, selection.End, composition.Start, composition.End);
}
private void _client_SurroundingTextChanged(object? sender, EventArgs e)
@ -140,8 +144,6 @@ namespace Avalonia.Android
{
if (_inputConnection is null || _inputConnection.IsInBatchEdit)
return;
OnSurroundingTextChanged();
OnSelectionChanged();
}

32
src/Android/Avalonia.Android/AvaloniaActivity.cs

@ -8,6 +8,8 @@ using Android.OS;
using Android.Runtime;
using Android.Views;
using AndroidX.AppCompat.App;
using Avalonia.Platform;
using Avalonia.Android.Platform;
using Avalonia.Android.Platform.Storage;
using Avalonia.Controls.ApplicationLifetimes;
@ -22,6 +24,7 @@ public class AvaloniaActivity : AppCompatActivity, IAvaloniaActivity
private EventHandler<ActivatedEventArgs>? _onActivated, _onDeactivated;
private GlobalLayoutListener? _listener;
private object? _content;
private bool _contentViewSet;
internal AvaloniaView? _view;
public Action<int, Result, Intent?>? ActivityResult { get; set; }
@ -39,6 +42,17 @@ public class AvaloniaActivity : AppCompatActivity, IAvaloniaActivity
_content = value;
if (_view is not null)
{
if (!_contentViewSet)
{
_contentViewSet = true;
SetContentView(_view);
_listener = new GlobalLayoutListener(_view);
_view.ViewTreeObserver?.AddOnGlobalLayoutListener(_listener);
}
_view.Content = _content;
}
}
@ -76,14 +90,13 @@ public class AvaloniaActivity : AppCompatActivity, IAvaloniaActivity
base.OnCreate(savedInstanceState);
SetContentView(_view);
_listener = new GlobalLayoutListener(_view);
_view.ViewTreeObserver?.AddOnGlobalLayoutListener(_listener);
if (Avalonia.Application.Current?.TryGetFeature<IActivatableLifetime>()
is AndroidActivatableLifetime activatableLifetime)
{
activatableLifetime.CurrentIntendActivity = this;
}
// TODO: we probably don't need to create AvaloniaView, if it's just a protocol activation, and main activity is already created.
if (Intent?.Data is {} androidUri
if (Intent?.Data is { } androidUri
&& androidUri.IsAbsolute
&& Uri.TryCreate(androidUri.ToString(), UriKind.Absolute, out var uri))
{
@ -131,8 +144,11 @@ public class AvaloniaActivity : AppCompatActivity, IAvaloniaActivity
{
if (_view is not null)
{
if (_listener is not null)
{
_view.ViewTreeObserver?.RemoveOnGlobalLayoutListener(_listener);
}
_view.Content = null;
_view.ViewTreeObserver?.RemoveOnGlobalLayoutListener(_listener);
_view.Dispose();
_view = null;
}

18
src/Android/Avalonia.Android/AvaloniaMainActivity.cs

@ -10,18 +10,6 @@ public class AvaloniaMainActivity : AvaloniaActivity
{
private protected static SingleViewLifetime? Lifetime;
public override void OnCreate(Bundle? savedInstanceState, PersistableBundle? persistentState)
{
// Global IActivatableLifetime expects a main activity, so we need to replace it on each OnCreate.
if (Avalonia.Application.Current?.TryGetFeature<IActivatableLifetime>()
is AndroidActivatableLifetime activatableLifetime)
{
activatableLifetime.Activity = this;
}
base.OnCreate(savedInstanceState, persistentState);
}
private protected override void InitializeAvaloniaView(object? initialContent)
{
// Android can run OnCreate + InitializeAvaloniaView multiple times per process lifetime.
@ -55,6 +43,12 @@ public class AvaloniaMainActivity : AvaloniaActivity
if (_view is null)
throw new InvalidOperationException("Unknown error: AvaloniaView initialization has failed.");
}
if (Avalonia.Application.Current?.TryGetFeature<IActivatableLifetime>()
is AndroidActivatableLifetime activatableLifetime)
{
activatableLifetime.CurrentMainActivity = this;
}
}
protected virtual AppBuilder CreateAppBuilder() => AppBuilder.Configure<Application>().UseAndroid();

65
src/Android/Avalonia.Android/Platform/AndroidActivatableLifetime.cs

@ -5,32 +5,71 @@ namespace Avalonia.Android.Platform;
internal class AndroidActivatableLifetime : ActivatableLifetimeBase
{
private IAvaloniaActivity? _activity;
private IAvaloniaActivity? _mainActivity, _intendActivity;
public IAvaloniaActivity? Activity
/// <summary>
/// While we primarily handle main activity lifecycle events.
/// Any secondary activity might send protocol or file activation.
/// </summary>
public IAvaloniaActivity? CurrentIntendActivity
{
get => _activity;
get => _intendActivity;
set
{
if (_activity is not null)
if (_intendActivity is not null)
{
_activity.Activated -= ActivityOnActivated;
_activity.Deactivated -= ActivityOnDeactivated;
_intendActivity.Activated -= IntendActivityOnActivated;
}
_activity = value;
_intendActivity = value;
if (_activity is not null)
if (_intendActivity is not null)
{
_activity.Activated += ActivityOnActivated;
_activity.Deactivated += ActivityOnDeactivated;
_intendActivity.Activated += IntendActivityOnActivated;
}
}
}
public IAvaloniaActivity? CurrentMainActivity
{
get => _mainActivity;
set
{
if (_mainActivity is not null)
{
_mainActivity.Activated -= MainActivityOnActivated;
_mainActivity.Deactivated -= MainActivityOnDeactivated;
}
_mainActivity = value;
if (_mainActivity is not null)
{
_mainActivity.Activated += MainActivityOnActivated;
_mainActivity.Deactivated += MainActivityOnDeactivated;
}
}
}
public override bool TryEnterBackground() => (_activity as Activity)?.MoveTaskToBack(true) == true;
public override bool TryEnterBackground() => (_mainActivity as Activity)?.MoveTaskToBack(true) == true;
private void ActivityOnDeactivated(object? sender, ActivatedEventArgs e) => OnDeactivated(e);
private void MainActivityOnDeactivated(object? sender, ActivatedEventArgs e) => OnDeactivated(e);
private void MainActivityOnActivated(object? sender, ActivatedEventArgs e)
{
if (!IsIntendActivation(e.Kind))
{
OnActivated(e);
}
}
private void IntendActivityOnActivated(object? sender, ActivatedEventArgs e)
{
if (IsIntendActivation(e.Kind))
{
OnActivated(e);
}
}
private void ActivityOnActivated(object? sender, ActivatedEventArgs e) => OnActivated(e);
private static bool IsIntendActivation(ActivationKind kind) => kind is ActivationKind.File or ActivationKind.OpenUri;
}

36
src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs

@ -54,7 +54,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
{
throw new ArgumentException("AvaloniaView.Context must not be null");
}
_view = new ViewImpl(avaloniaView.Context, this, placeOnTop);
_textInputMethod = new AndroidInputMethod<ViewImpl>(_view);
_keyboardHelper = new AndroidKeyboardEventsHelper<TopLevelImpl>(this);
@ -85,7 +85,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
public virtual Size ClientSize => _view.Size.ToSize(RenderScaling);
public Size? FrameSize => null;
public Action? Closed { get; set; }
public Action<RawInputEventArgs>? Input { get; set; }
@ -138,7 +138,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
{
InputRoot = inputRoot;
}
public virtual void Show()
{
_view.Visibility = ViewStates.Visible;
@ -150,7 +150,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
{
Paint?.Invoke(new Rect(new Point(0, 0), ClientSize));
}
public virtual void Dispose()
{
_systemNavigationManager.Dispose();
@ -266,11 +266,11 @@ namespace Avalonia.Android.Platform.SkiaPlatform
}
public IPopupImpl? CreatePopup() => null;
public Action? LostFocus { get; set; }
public Action<WindowTransparencyLevel>? TransparencyLevelChanged { get; set; }
public WindowTransparencyLevel TransparencyLevel
public WindowTransparencyLevel TransparencyLevel
{
get => _transparencyLevel;
private set
@ -683,5 +683,29 @@ namespace Avalonia.Android.Platform.SkiaPlatform
return extract;
}
public override bool PerformContextMenuAction(int id)
{
if (InputMethod.Client is not { } client) return false;
switch (id)
{
case global::Android.Resource.Id.SelectAll:
client.ExecuteContextMenuAction(ContextMenuAction.SelectAll);
return true;
case global::Android.Resource.Id.Cut:
client.ExecuteContextMenuAction(ContextMenuAction.Cut);
return true;
case global::Android.Resource.Id.Copy:
client.ExecuteContextMenuAction(ContextMenuAction.Copy);
return true;
case global::Android.Resource.Id.Paste:
client.ExecuteContextMenuAction(ContextMenuAction.Paste);
return true;
default:
break;
}
return base.PerformContextMenuAction(id);
}
}
}

16
src/Avalonia.Base/Input/TextInput/TextInputMethodClient.cs

@ -64,6 +64,12 @@ namespace Avalonia.Input.TextInput
/// </summary>
public virtual void SetPreeditText(string? preeditText) { }
/// <summary>
/// Execute specific context menu actions
/// </summary>
/// <param name="action">The <see cref="ContextMenuAction"/> to perform</param>
public virtual void ExecuteContextMenuAction(ContextMenuAction action) { }
/// <summary>
/// Sets the non-committed input string and cursor offset in that string
/// </summary>
@ -71,6 +77,8 @@ namespace Avalonia.Input.TextInput
{
SetPreeditText(preeditText);
}
public virtual void ShowInputPanel() { }
protected virtual void RaiseTextViewVisualChanged()
{
@ -99,4 +107,12 @@ namespace Avalonia.Input.TextInput
}
public record struct TextSelection(int Start, int End);
public enum ContextMenuAction
{
Copy,
Cut,
Paste,
SelectAll
}
}

2
src/Avalonia.Base/Media/Brush.cs

@ -101,6 +101,8 @@ namespace Avalonia.Media
private protected void RegisterForSerialization() =>
_resource.RegisterForInvalidationOnAllCompositors(this);
private protected bool IsOnCompositor(Compositor c) => _resource.TryGetForCompositor(c) != null;
private CompositorResourceHolder<ServerCompositionSimpleBrush> _resource;
IBrush ICompositionRenderResource<IBrush>.GetForCompositor(Compositor c) => _resource.GetForCompositor(c);

18
src/Avalonia.Base/Media/DrawingBrush.cs

@ -58,7 +58,7 @@ namespace Avalonia.Media
internal override Func<Compositor, ServerCompositionSimpleBrush> Factory =>
static c => new ServerCompositionSimpleContentBrush(c.Server);
private InlineDictionary<Compositor, CompositionRenderDataSceneBrushContent?> _renderDataDictionary;
private InlineDictionary<Compositor, CompositionRenderData?> _renderDataDictionary;
private protected override void OnReferencedFromCompositor(Compositor c)
{
@ -69,33 +69,27 @@ namespace Avalonia.Media
protected override void OnUnreferencedFromCompositor(Compositor c)
{
if (_renderDataDictionary.TryGetAndRemoveValue(c, out var content))
content?.RenderData.Dispose();
content?.Dispose();
base.OnUnreferencedFromCompositor(c);
}
private protected override void SerializeChanges(Compositor c, BatchStreamWriter writer)
{
base.SerializeChanges(c, writer);
if (_renderDataDictionary.TryGetValue(c, out var content))
writer.WriteObject(content);
if (_renderDataDictionary.TryGetValue(c, out var content) && content != null)
writer.WriteObject(new CompositionRenderDataSceneBrushContent.Properties(content.Server, null, true));
else
writer.WriteObject(null);
}
CompositionRenderDataSceneBrushContent? CreateServerContent(Compositor c)
CompositionRenderData? CreateServerContent(Compositor c)
{
if (Drawing == null)
return null;
using var recorder = new RenderDataDrawingContext(c);
Drawing?.Draw(recorder);
var renderData = recorder.GetRenderResults();
if (renderData == null)
return null;
return new CompositionRenderDataSceneBrushContent(
(ServerCompositionSimpleContentBrush)((ICompositionRenderResource<IBrush>)this).GetForCompositor(c),
renderData, null, true);
return recorder.GetRenderResults();
}
}
}

2
src/Avalonia.Base/Media/Typeface.cs

@ -31,7 +31,7 @@ namespace Avalonia.Media
throw new ArgumentException("Font stretch must be > 1.");
}
FontFamily = fontFamily;
FontFamily = fontFamily ?? FontFamily.Default;
Style = style;
Weight = weight;
Stretch = stretch;

65
src/Avalonia.Base/Media/VisualBrush.cs

@ -1,4 +1,5 @@
using System;
using Avalonia.Collections.Pooled;
using Avalonia.Media.Immutable;
using Avalonia.Rendering;
using Avalonia.Rendering.Composition;
@ -62,31 +63,65 @@ namespace Avalonia.Media
internal override Func<Compositor, ServerCompositionSimpleBrush> Factory =>
static c => new ServerCompositionSimpleContentBrush(c.Server);
private InlineDictionary<Compositor, CompositionRenderDataSceneBrushContent?> _renderDataDictionary;
private protected override void OnReferencedFromCompositor(Compositor c)
class RenderDataItem(CompositionRenderData data, Rect rect) : IDisposable
{
_renderDataDictionary.Add(c, CreateServerContent(c));
base.OnReferencedFromCompositor(c);
public CompositionRenderData Data { get; } = data;
public Rect Rect { get; } = rect;
public bool IsDirty;
public void Dispose() => Data?.Dispose();
}
private InlineDictionary<Compositor, RenderDataItem?> _renderDataDictionary;
protected override void OnUnreferencedFromCompositor(Compositor c)
{
if (_renderDataDictionary.TryGetAndRemoveValue(c, out var content))
content?.RenderData.Dispose();
content?.Dispose();
base.OnUnreferencedFromCompositor(c);
}
private protected override void SerializeChanges(Compositor c, BatchStreamWriter writer)
{
base.SerializeChanges(c, writer);
if (_renderDataDictionary.TryGetValue(c, out var content))
writer.WriteObject(content);
else
writer.WriteObject(null);
CompositionRenderDataSceneBrushContent.Properties? content = null;
if (IsOnCompositor(c)) // Should always be true here, but just in case do this check
{
_renderDataDictionary.TryGetValue(c, out var data);
if (data == null || data.IsDirty)
{
var created = CreateServerContent(c);
// Dispose the old render list _after_ creating a new one to avoid unnecessary detach/attach
// sequence for referenced resources
if (data != null)
data.Dispose();
_renderDataDictionary[c] = data = created;
}
if (data != null)
content = new(data.Data.Server, data.Rect, false);
}
writer.WriteObject(content);
}
CompositionRenderDataSceneBrushContent? CreateServerContent(Compositor c)
void InvalidateContent()
{
foreach(var item in _renderDataDictionary)
if (item.Value != null)
item.Value.IsDirty = true;
RegisterForSerialization();
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
// We are supposed to be only calling this when content is actually changed,
// but instead we are calling this on brush property change for backwards compat with 0.10.x
InvalidateContent();
base.OnPropertyChanged(change);
}
RenderDataItem? CreateServerContent(Compositor c)
{
if (Visual == null)
return null;
@ -99,10 +134,8 @@ namespace Avalonia.Media
var renderData = recorder.GetRenderResults();
if (renderData == null)
return null;
return new CompositionRenderDataSceneBrushContent(
(ServerCompositionSimpleContentBrush)((ICompositionRenderResource<IBrush>)this).GetForCompositor(c),
renderData, new(Visual.Bounds.Size), false);
return new(renderData, new(Visual.Bounds.Size));
}
}
}

6
src/Avalonia.Base/Platform/IDrawingContextImpl.cs

@ -229,4 +229,10 @@ namespace Avalonia.Platform
/// </summary>
bool CanBlit { get; }
}
public interface IDrawingContextLayerWithRenderContextAffinityImpl : IDrawingContextLayerImpl
{
bool HasRenderContextAffinity { get; }
IBitmapImpl CreateNonAffinedSnapshot();
}
}

8
src/Avalonia.Base/Platform/IPlatformRenderInterface.cs

@ -215,6 +215,14 @@ namespace Avalonia.Platform
/// </param>
/// <returns>An <see cref="IRenderTarget"/>.</returns>
IRenderTarget CreateRenderTarget(IEnumerable<object> surfaces);
/// <summary>
/// Creates an offscreen render target
/// </summary>
/// <param name="pixelSize">The size, in pixels, of the render target</param>
/// <param name="scaling">The scaling which will be reported by IBitmap.Dpi</param>
/// <returns></returns>
IDrawingContextLayerImpl CreateOffscreenRenderTarget(PixelSize pixelSize, double scaling);
/// <summary>
/// Indicates that the context is no longer usable. This method should be thread-safe

44
src/Avalonia.Base/Platform/IScopedResource.cs

@ -0,0 +1,44 @@
using System;
using System.Threading;
namespace Avalonia.Platform;
public interface IScopedResource<T> : IDisposable
{
public T Value { get; }
}
public class ScopedResource<T> : IScopedResource<T>
{
private int _disposed = 0;
private T _value;
private Action? _dispose;
private ScopedResource(T value, Action dispose)
{
_value = value;
_dispose = dispose;
}
public static IScopedResource<T> Create(T value, Action dispose) => new ScopedResource<T>(value, dispose);
public void Dispose()
{
if (Interlocked.CompareExchange(ref _disposed, 1, 0) == 0)
{
var disp = _dispose!;
_value = default!;
_dispose = null;
disp();
}
}
public T Value
{
get
{
if (_disposed == 1)
throw new ObjectDisposedException(this.GetType().FullName);
return _value;
}
}
}

95
src/Avalonia.Base/Platform/Storage/FallbackStorageProvider.cs

@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
namespace Avalonia.Platform.Storage;
#pragma warning disable CA1823
internal class FallbackStorageProvider : IStorageProvider
{
private readonly Func<Task<IStorageProvider?>>[] _factories;
private readonly List<IStorageProvider> _providers = new();
private int _nextProviderFactory = 0;
public FallbackStorageProvider(Func<Task<IStorageProvider?>>[] factories)
{
_factories = factories;
}
async IAsyncEnumerable<IStorageProvider> GetProviders()
{
foreach (var p in _providers)
yield return p;
for (;_nextProviderFactory < _factories.Length;)
{
var p = await _factories[_nextProviderFactory]();
_nextProviderFactory++;
if (p != null)
{
_providers.Add(p);
yield return p;
}
}
}
async Task<IStorageProvider> GetFor(Func<IStorageProvider, bool> filter)
{
await foreach (var p in GetProviders())
if (filter(p))
return p;
throw new IOException("Unable to select a suitable storage provider");
}
// Those should _really_ have been asynchronous,
// but this class is expected to fall back to the managed implementation anyway
public bool CanOpen => true;
public bool CanSave => true;
public bool CanPickFolder => true;
public async Task<IReadOnlyList<IStorageFile>> OpenFilePickerAsync(FilePickerOpenOptions options)
{
return await (await GetFor(p => p.CanOpen)).OpenFilePickerAsync(options);
}
public async Task<IStorageFile?> SaveFilePickerAsync(FilePickerSaveOptions options)
{
return await (await GetFor(p => p.CanSave)).SaveFilePickerAsync(options);
}
public async Task<IReadOnlyList<IStorageFolder>> OpenFolderPickerAsync(FolderPickerOpenOptions options)
{
return await (await GetFor(p => p.CanPickFolder)).OpenFolderPickerAsync(options);
}
async Task<TResult?> FirstNotNull<TArg, TResult>(TArg arg, Func<IStorageProvider, TArg, Task<TResult?>> cb)
where TResult : class
{
await foreach (var p in GetProviders())
{
var res = await cb(p, arg);
if (res != null)
return res;
}
return null;
}
public Task<IStorageBookmarkFile?> OpenFileBookmarkAsync(string bookmark) =>
FirstNotNull(bookmark, (p, a) => p.OpenFileBookmarkAsync(a));
public Task<IStorageBookmarkFolder?> OpenFolderBookmarkAsync(string bookmark) =>
FirstNotNull(bookmark, (p, a) => p.OpenFolderBookmarkAsync(a));
public Task<IStorageFile?> TryGetFileFromPathAsync(Uri filePath) =>
FirstNotNull(filePath, (p, a) => p.TryGetFileFromPathAsync(filePath));
public Task<IStorageFolder?> TryGetFolderFromPathAsync(Uri folderPath)
=> FirstNotNull(folderPath, (p, a) => p.TryGetFolderFromPathAsync(a));
public Task<IStorageFolder?> TryGetWellKnownFolderAsync(WellKnownFolder wellKnownFolder) =>
FirstNotNull(wellKnownFolder, (p, a) => p.TryGetWellKnownFolderAsync(a));
}

1
src/Avalonia.Base/Reactive/Operators/Switch.cs

@ -54,6 +54,7 @@ internal sealed class Switch<TSource> : IObservable<TSource>
var innerObserver = new InnerObserver(this, id);
_innerSerialDisposable?.Dispose();
_innerSerialDisposable = innerObserver;
innerObserver.Disposable = value.Subscribe(innerObserver);
}

11
src/Avalonia.Base/Rendering/Composition/Brushes/ServerSimpleContentBrush.cs

@ -7,18 +7,21 @@ namespace Avalonia.Rendering.Composition.Server;
internal sealed class ServerCompositionSimpleContentBrush : ServerCompositionSimpleTileBrush, ITileBrush, ISceneBrush
{
private CompositionRenderDataSceneBrushContent? _content;
private CompositionRenderDataSceneBrushContent.Properties? _content;
internal ServerCompositionSimpleContentBrush(ServerCompositor compositor) : base(compositor)
{
}
// TODO: Figure out something about disposable
public ISceneBrushContent? CreateContent() => _content;
public ISceneBrushContent? CreateContent() =>
_content == null || _content.RenderData.IsDisposed
? null
: new CompositionRenderDataSceneBrushContent(this, _content);
protected override void DeserializeChangesCore(BatchStreamReader reader, TimeSpan committedAt)
{
base.DeserializeChangesCore(reader, committedAt);
_content = reader.ReadObject<CompositionRenderDataSceneBrushContent?>();
_content = reader.ReadObject<CompositionRenderDataSceneBrushContent.Properties?>();
}
}

45
src/Avalonia.Base/Rendering/Composition/Compositor.cs

@ -5,6 +5,7 @@ using Avalonia.Animation;
using Avalonia.Animation.Easings;
using Avalonia.Controls;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Metadata;
using Avalonia.Platform;
using Avalonia.Rendering.Composition.Server;
@ -34,6 +35,7 @@ namespace Avalonia.Rendering.Composition
private CompositionBatch? _pendingBatch;
private readonly object _pendingBatchLock = new();
private readonly List<Action> _pendingServerCompositorJobs = new();
private readonly List<Action> _pendingServerCompositorPostTargetJobs = new();
private DiagnosticTextRenderer? _diagnosticTextRenderer;
private readonly Action _triggerCommitRequested;
@ -170,14 +172,23 @@ namespace Avalonia.Rendering.Composition
_disposeOnNextBatch.Clear();
}
if (_pendingServerCompositorJobs.Count > 0)
static void SerializeServerJobs(BatchStreamWriter writer, List<Action> list, object startMarker, object endMarker)
{
writer.WriteObject(ServerCompositor.RenderThreadJobsStartMarker);
foreach (var job in _pendingServerCompositorJobs)
writer.WriteObject(job);
writer.WriteObject(ServerCompositor.RenderThreadJobsEndMarker);
if (list.Count > 0)
{
writer.WriteObject(startMarker);
foreach (var job in list)
writer.WriteObject(job);
writer.WriteObject(endMarker);
}
list.Clear();
}
_pendingServerCompositorJobs.Clear();
SerializeServerJobs(writer, _pendingServerCompositorJobs, ServerCompositor.RenderThreadJobsStartMarker,
ServerCompositor.RenderThreadJobsEndMarker);
SerializeServerJobs(writer, _pendingServerCompositorPostTargetJobs, ServerCompositor.RenderThreadPostTargetJobsStartMarker,
ServerCompositor.RenderThreadPostTargetJobsEndMarker);
}
_nextCommit.CommittedAt = Server.Clock.Elapsed;
@ -227,21 +238,21 @@ namespace Avalonia.Rendering.Composition
RequestCommitAsync();
}
internal void PostServerJob(Action job)
internal void PostServerJob(Action job, bool postTarget = false)
{
Dispatcher.VerifyAccess();
_pendingServerCompositorJobs.Add(job);
(postTarget ? _pendingServerCompositorPostTargetJobs : _pendingServerCompositorJobs).Add(job);
RequestCommitAsync();
}
internal Task InvokeServerJobAsync(Action job) =>
internal Task InvokeServerJobAsync(Action job, bool postTarget = false) =>
InvokeServerJobAsync<object?>(() =>
{
job();
return null;
});
}, postTarget);
internal Task<T> InvokeServerJobAsync<T>(Func<T> job)
internal Task<T> InvokeServerJobAsync<T>(Func<T> job, bool postTarget = false)
{
var tcs = new TaskCompletionSource<T>(TaskCreationOptions.RunContinuationsAsynchronously);
PostServerJob(() =>
@ -254,7 +265,7 @@ namespace Avalonia.Rendering.Composition
{
tcs.TrySetException(e);
}
});
}, postTarget);
return tcs.Task;
}
@ -275,6 +286,16 @@ namespace Avalonia.Rendering.Composition
(await GetRenderInterfacePublicFeatures().ConfigureAwait(false)).TryGetValue(featureType, out var rv);
return rv;
}
public async Task<Bitmap> CreateCompositionVisualSnapshot(CompositionVisual visual, double scaling)
{
if (visual.Compositor != this)
throw new InvalidOperationException();
if (visual.Root == null)
throw new InvalidOperationException();
var impl = await InvokeServerJobAsync(() => _server.CreateCompositionVisualSnapshot(visual.Server, scaling), true);
return new Bitmap(RefCountable.Create(impl));
}
/// <summary>
/// Attempts to query for GPU interop feature from the platform render interface

19
src/Avalonia.Base/Rendering/Composition/Drawing/CompositionRenderDataSceneBrushContent.cs

@ -6,20 +6,21 @@ namespace Avalonia.Rendering.Composition.Drawing;
internal class CompositionRenderDataSceneBrushContent : ISceneBrushContent
{
public CompositionRenderData RenderData { get; }
public ServerCompositionRenderData RenderData { get; }
private readonly Rect? _rect;
public CompositionRenderDataSceneBrushContent(ITileBrush brush, CompositionRenderData renderData, Rect? rect,
bool useScalableRasterization)
public record Properties(ServerCompositionRenderData RenderData, Rect? Rect, bool UseScalableRasterization);
public CompositionRenderDataSceneBrushContent(ITileBrush brush, Properties properties)
{
Brush = brush;
_rect = rect;
UseScalableRasterization = useScalableRasterization;
RenderData = renderData;
_rect = properties.Rect;
UseScalableRasterization = properties.UseScalableRasterization;
RenderData = properties.RenderData;
}
public ITileBrush Brush { get; }
public Rect Rect => _rect ?? (RenderData.Server?.Bounds?.ToRect() ?? default);
public Rect Rect => _rect ?? (RenderData?.Bounds?.ToRect() ?? default);
public double Opacity => Brush.Opacity;
public ITransform? Transform => Brush.Transform;
@ -36,11 +37,11 @@ internal class CompositionRenderDataSceneBrushContent : ISceneBrushContent
{
var oldTransform = context.Transform;
context.Transform = transform.Value * oldTransform;
RenderData.Server.Render(context);
RenderData.Render(context);
context.Transform = oldTransform;
}
else
RenderData.Server.Render(context);
RenderData.Render(context);
}
public bool UseScalableRasterization { get; }

7
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionContainerVisual.cs

@ -16,14 +16,13 @@ namespace Avalonia.Rendering.Composition.Server
private LtrbRect? _transformedContentBounds;
private IImmutableEffect? _oldEffect;
protected override void RenderCore(CompositorDrawingContextProxy canvas, LtrbRect currentTransformedClip,
IDirtyRectTracker dirtyRects)
protected override void RenderCore(ServerVisualRenderContext context, LtrbRect currentTransformedClip)
{
base.RenderCore(canvas, currentTransformedClip, dirtyRects);
base.RenderCore(context, currentTransformedClip);
foreach (var ch in Children)
{
ch.Render(canvas, currentTransformedClip, dirtyRects);
ch.Render(context, currentTransformedClip);
}
}

10
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionDrawListVisual.cs

@ -40,17 +40,15 @@ internal class ServerCompositionDrawListVisual : ServerCompositionContainerVisua
base.DeserializeChangesCore(reader, committedAt);
}
protected override void RenderCore(CompositorDrawingContextProxy canvas, LtrbRect currentTransformedClip,
IDirtyRectTracker dirtyRects)
protected override void RenderCore(ServerVisualRenderContext context, LtrbRect currentTransformedClip)
{
if (_renderCommands != null
&& currentTransformedClip.Intersects(TransformedOwnContentBounds)
&& dirtyRects.Intersects(TransformedOwnContentBounds))
&& context.ShouldRenderOwnContent(this, currentTransformedClip))
{
_renderCommands.Render(canvas);
_renderCommands.Render(context.Canvas);
}
base.RenderCore(canvas, currentTransformedClip, dirtyRects);
base.RenderCore(context, currentTransformedClip);
}
public void DependencyQueuedInvalidate(IServerRenderResource sender) => ValuesInvalidated();

7
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionExperimentalAcrylicVisual.cs

@ -5,18 +5,17 @@ namespace Avalonia.Rendering.Composition.Server;
internal partial class ServerCompositionExperimentalAcrylicVisual
{
protected override void RenderCore(CompositorDrawingContextProxy canvas, LtrbRect currentTransformedClip,
IDirtyRectTracker dirtyRects)
protected override void RenderCore(ServerVisualRenderContext context, LtrbRect currentTransformedClip)
{
var cornerRadius = CornerRadius;
canvas.DrawRectangle(
context.Canvas.DrawRectangle(
Material,
new RoundedRect(
new Rect(0, 0, Size.X, Size.Y),
cornerRadius.TopLeft, cornerRadius.TopRight,
cornerRadius.BottomRight, cornerRadius.BottomLeft));
base.RenderCore(canvas, currentTransformedClip, dirtyRects);
base.RenderCore(context, currentTransformedClip);
}
public override LtrbRect OwnContentBounds => new(0, 0, Size.X, Size.Y);

5
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionSolidColorVisual.cs

@ -5,9 +5,8 @@ namespace Avalonia.Rendering.Composition.Server;
internal partial class ServerCompositionSolidColorVisual
{
protected override void RenderCore(CompositorDrawingContextProxy canvas, LtrbRect currentTransformedClip,
IDirtyRectTracker dirtyRects)
protected override void RenderCore(ServerVisualRenderContext context, LtrbRect currentTransformedClip)
{
canvas.DrawRectangle(new ImmutableSolidColorBrush(Color), null, new Rect(0, 0, Size.X, Size.Y));
context.Canvas.DrawRectangle(new ImmutableSolidColorBrush(Color), null, new Rect(0, 0, Size.X, Size.Y));
}
}

5
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionSurfaceVisual.cs

@ -5,8 +5,7 @@ namespace Avalonia.Rendering.Composition.Server;
internal partial class ServerCompositionSurfaceVisual
{
protected override void RenderCore(CompositorDrawingContextProxy canvas, LtrbRect currentTransformedClip,
IDirtyRectTracker dirtyRects)
protected override void RenderCore(ServerVisualRenderContext context, LtrbRect currentTransformedClip)
{
if (Surface == null)
return;
@ -15,7 +14,7 @@ internal partial class ServerCompositionSurfaceVisual
var bmp = Surface.Bitmap.Item;
//TODO: add a way to always render the whole bitmap instead of just assuming 96 DPI
canvas.DrawBitmap(Surface.Bitmap.Item, 1, new Rect(bmp.PixelSize.ToSize(1)), new Rect(
context.Canvas.DrawBitmap(Surface.Bitmap.Item, 1, new Rect(bmp.PixelSize.ToSize(1)), new Rect(
new Size(Size.X, Size.Y)));
}

2
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.DirtyRects.cs

@ -35,7 +35,7 @@ internal partial class ServerCompositionTarget
public Rect SnapToDevicePixels(Rect rect) => SnapToDevicePixels(new(rect), Scaling).ToRect();
public LtrbRect SnapToDevicePixels(LtrbRect rect) => SnapToDevicePixels(rect, Scaling);
private static LtrbRect SnapToDevicePixels(LtrbRect rect, double scale)
public static LtrbRect SnapToDevicePixels(LtrbRect rect, double scale)
{
return new LtrbRect(
Math.Floor(rect.Left * scale) / scale,

5
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs

@ -214,7 +214,10 @@ namespace Avalonia.Rendering.Composition.Server
context.PushLayer(DirtyRects.CombinedRect.ToRectUnscaled());
using (var proxy = new CompositorDrawingContextProxy(context))
root.Render(proxy, null, DirtyRects);
{
var ctx = new ServerVisualRenderContext(proxy, DirtyRects, false);
root.Render(ctx, null);
}
if (useLayerClip)
context.PopLayer();

22
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs

@ -22,24 +22,22 @@ namespace Avalonia.Rendering.Composition.Server
private LtrbRect? _transformedClipBounds;
private LtrbRect _combinedTransformedClipBounds;
protected virtual void RenderCore(CompositorDrawingContextProxy canvas, LtrbRect currentTransformedClip,
IDirtyRectTracker dirtyRects)
protected virtual void RenderCore(ServerVisualRenderContext canvas, LtrbRect currentTransformedClip)
{
}
public void Render(CompositorDrawingContextProxy canvas, LtrbRect? parentTransformedClip, IDirtyRectTracker dirtyRects)
public void Render(ServerVisualRenderContext context, LtrbRect? parentTransformedClip)
{
if (Visible == false || IsVisibleInFrame == false)
return;
if (Opacity == 0)
return;
var canvas = context.Canvas;
var currentTransformedClip = parentTransformedClip.HasValue
? parentTransformedClip.Value.Intersect(_combinedTransformedClipBounds)
: _combinedTransformedClipBounds;
if (currentTransformedClip.IsZeroSize)
return;
if(!dirtyRects.Intersects(currentTransformedClip))
if(!context.ShouldRender(this, currentTransformedClip))
return;
Root!.RenderedVisuals++;
@ -49,12 +47,16 @@ namespace Avalonia.Rendering.Composition.Server
if (AdornedVisual != null)
{
// Adorners are currently not supported in detached rendering mode
if(context.DetachedRendering)
return;
canvas.Transform = Matrix.Identity;
if (AdornerIsClipped)
canvas.PushClip(AdornedVisual._combinedTransformedClipBounds.ToRect());
}
var transform = GlobalTransformMatrix;
canvas.Transform = transform;
using var _ = context.SetOrPushTransform(this);
var applyRenderOptions = RenderOptions != default;
@ -72,7 +74,7 @@ namespace Avalonia.Rendering.Composition.Server
if (OpacityMaskBrush != null)
canvas.PushOpacityMask(OpacityMaskBrush, boundsRect);
RenderCore(canvas, currentTransformedClip, dirtyRects);
RenderCore(context, currentTransformedClip);
if (OpacityMaskBrush != null)
canvas.PopOpacityMask();

40
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.UserApis.cs

@ -47,4 +47,44 @@ internal partial class ServerCompositor
lock (_renderInterfaceFeaturesUserApiLock)
return _renderInterfaceFeatureCache ??= RenderInterface.Value.PublicFeatures;
}
public IBitmapImpl CreateCompositionVisualSnapshot(ServerCompositionVisual visual,
double scaling)
{
using (RenderInterface.EnsureCurrent())
{
var pixelSize = PixelSize.FromSize(new Size(visual.Size.X, visual.Size.Y), scaling);
var scaleTransform = Matrix.CreateScale(scaling, scaling);
var invertRootTransform = visual.CombinedTransformMatrix.Invert();
IDrawingContextLayerImpl? target = null;
try
{
target = RenderInterface.Value.CreateOffscreenRenderTarget(pixelSize, scaling);
using (var canvas = target.CreateDrawingContext(false))
{
var proxy = new CompositorDrawingContextProxy(canvas)
{
PostTransform = invertRootTransform * scaleTransform,
Transform = Matrix.Identity
};
var ctx = new ServerVisualRenderContext(proxy, null, true);
visual.Render(ctx, null);
}
if (target is IDrawingContextLayerWithRenderContextAffinityImpl affined)
return affined.CreateNonAffinedSnapshot();
// We are returning the original target, so prevent it from being disposed
var rv = target;
target = null;
return rv;
}
finally
{
target?.Dispose();
}
}
}
}

25
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs

@ -23,6 +23,7 @@ namespace Avalonia.Rendering.Composition.Server
private readonly Queue<CompositionBatch> _batches = new Queue<CompositionBatch>();
private readonly Queue<Action> _receivedJobQueue = new();
private readonly Queue<Action> _receivedPostTargetJobQueue = new();
public long LastBatchId { get; private set; }
public Stopwatch Clock { get; } = Stopwatch.StartNew();
public TimeSpan ServerNow { get; private set; }
@ -38,6 +39,8 @@ namespace Avalonia.Rendering.Composition.Server
internal static readonly object RenderThreadDisposeStartMarker = new();
internal static readonly object RenderThreadJobsStartMarker = new();
internal static readonly object RenderThreadJobsEndMarker = new();
internal static readonly object RenderThreadPostTargetJobsStartMarker = new();
internal static readonly object RenderThreadPostTargetJobsEndMarker = new();
public CompositionOptions Options { get; }
public ServerCompositor(IRenderLoop renderLoop, IPlatformGraphics? platformGraphics,
@ -83,7 +86,12 @@ namespace Avalonia.Rendering.Composition.Server
var readObject = stream.ReadObject();
if (readObject == RenderThreadJobsStartMarker)
{
ReadServerJobs(stream);
ReadServerJobs(stream, _receivedJobQueue, RenderThreadJobsEndMarker);
continue;
}
if (readObject == RenderThreadPostTargetJobsStartMarker)
{
ReadServerJobs(stream, _receivedPostTargetJobQueue, RenderThreadPostTargetJobsEndMarker);
continue;
}
@ -111,11 +119,11 @@ namespace Avalonia.Rendering.Composition.Server
}
}
void ReadServerJobs(BatchStreamReader reader)
void ReadServerJobs(BatchStreamReader reader, Queue<Action> queue, object endMarker)
{
object? readObject;
while ((readObject = reader.ReadObject()) != RenderThreadJobsEndMarker)
_receivedJobQueue.Enqueue((Action)readObject!);
while ((readObject = reader.ReadObject()) != endMarker)
queue.Enqueue((Action)readObject!);
}
void ReadDisposeJobs(BatchStreamReader reader)
@ -128,12 +136,12 @@ namespace Avalonia.Rendering.Composition.Server
}
}
void ExecuteServerJobs()
void ExecuteServerJobs(Queue<Action> queue)
{
while(_receivedJobQueue.Count > 0)
while(queue.Count > 0)
try
{
_receivedJobQueue.Dequeue()();
queue.Dequeue()();
}
catch
{
@ -224,9 +232,10 @@ namespace Avalonia.Rendering.Composition.Server
try
{
RenderInterface.EnsureValidBackendContext();
ExecuteServerJobs();
ExecuteServerJobs(_receivedJobQueue);
foreach (var t in _activeTargets)
t.Render();
ExecuteServerJobs(_receivedPostTargetJobQueue);
}
catch (Exception e) when(RT_OnContextLostExceptionFilterObserver(e) && catchExceptions)
{

9
src/Avalonia.Base/Rendering/Composition/Server/ServerCustomCompositionVisual.cs

@ -71,11 +71,10 @@ internal sealed class ServerCompositionCustomVisual : ServerCompositionContainer
Compositor.AddToClock(this);
}
protected override void RenderCore(CompositorDrawingContextProxy canvas, LtrbRect currentTransformedClip,
IDirtyRectTracker dirtyRects)
protected override void RenderCore(ServerVisualRenderContext ctx, LtrbRect currentTransformedClip)
{
canvas.AutoFlush = true;
using var context = new ImmediateDrawingContext(canvas, GlobalTransformMatrix, false);
ctx.Canvas.AutoFlush = true;
using var context = new ImmediateDrawingContext(ctx.Canvas, GlobalTransformMatrix, false);
try
{
_handler.Render(context, currentTransformedClip.ToRect());
@ -86,6 +85,6 @@ internal sealed class ServerCompositionCustomVisual : ServerCompositionContainer
?.Log(_handler, $"Exception in {_handler.GetType().Name}.{nameof(CompositionCustomVisualHandler.OnRender)} {{0}}", e);
}
canvas.AutoFlush = false;
ctx.Canvas.AutoFlush = false;
}
}

75
src/Avalonia.Base/Rendering/Composition/Server/ServerVisualRenderContext.cs

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using Avalonia.Platform;
namespace Avalonia.Rendering.Composition.Server;
internal class ServerVisualRenderContext
{
public IDirtyRectTracker? DirtyRects { get; }
public bool DetachedRendering { get; }
public CompositorDrawingContextProxy Canvas { get; }
private readonly Stack<Matrix>? _transformStack;
public ServerVisualRenderContext(CompositorDrawingContextProxy canvas, IDirtyRectTracker? dirtyRects,
bool detachedRendering)
{
Canvas = canvas;
DirtyRects = dirtyRects;
DetachedRendering = detachedRendering;
if (detachedRendering)
{
_transformStack = new();
_transformStack.Push(canvas.Transform);
}
}
public bool ShouldRender(ServerCompositionVisual visual, LtrbRect currentTransformedClip)
{
if (DetachedRendering)
return true;
if (currentTransformedClip.IsZeroSize)
return false;
if (DirtyRects?.Intersects(currentTransformedClip) == false)
return false;
return true;
}
public bool ShouldRenderOwnContent(ServerCompositionVisual visual, LtrbRect currentTransformedClip)
{
if (DetachedRendering)
return true;
return currentTransformedClip.Intersects(visual.TransformedOwnContentBounds)
&& DirtyRects?.Intersects(visual.TransformedOwnContentBounds) != false;
}
public RestoreTransform SetOrPushTransform(ServerCompositionVisual visual)
{
if (!DetachedRendering)
{
Canvas.Transform = visual.GlobalTransformMatrix;
return default;
}
else
{
var transform = visual.CombinedTransformMatrix * _transformStack!.Peek();
Canvas.Transform = transform;
_transformStack.Push(transform);
return new RestoreTransform(this);
}
}
public struct RestoreTransform(ServerVisualRenderContext? parent) : IDisposable
{
public void Dispose()
{
if (parent != null)
{
parent._transformStack!.Pop();
parent.Canvas.Transform = parent._transformStack.Peek();
}
}
}
}

12
src/Avalonia.Base/Utilities/SmallDictionary.cs

@ -127,6 +127,18 @@ internal struct InlineDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey,
return false;
}
public void Clear()
{
if(_data == null)
return;
if(_data is KeyValuePair[] arr)
Array.Clear(arr, 0, arr.Length);
else if (_data is Dictionary<TKey, TValue?> dic)
dic.Clear();
else
_data = null;
}
public bool HasEntries => _data != null;
public bool TryGetValue(TKey key, [MaybeNullWhen(false)]out TValue value)

2
src/Avalonia.Controls.DataGrid/DataGridCell.cs

@ -3,6 +3,7 @@
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using Avalonia.Automation;
using Avalonia.Automation.Peers;
using Avalonia.Controls.Automation.Peers;
using Avalonia.Controls.Metadata;
@ -37,6 +38,7 @@ namespace Avalonia.Controls
(x,e) => x.DataGridCell_PointerPressed(e), handledEventsToo: true);
FocusableProperty.OverrideDefaultValue<DataGridCell>(true);
IsTabStopProperty.OverrideDefaultValue<DataGridCell>(false);
AutomationProperties.IsOffscreenBehaviorProperty.OverrideDefaultValue<DataGridCell>(IsOffscreenBehavior.FromClip);
}
public DataGridCell()
{ }

2
src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs

@ -6,6 +6,7 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using Avalonia.Automation;
using Avalonia.Automation.Peers;
using Avalonia.Collections;
using Avalonia.Controls.Automation.Peers;
@ -74,6 +75,7 @@ namespace Avalonia.Controls
AreSeparatorsVisibleProperty.Changed.AddClassHandler<DataGridColumnHeader>((x, e) => x.OnAreSeparatorsVisibleChanged(e));
PressedMixin.Attach<DataGridColumnHeader>();
IsTabStopProperty.OverrideDefaultValue<DataGridColumnHeader>(false);
AutomationProperties.IsOffscreenBehaviorProperty.OverrideDefaultValue<DataGridColumnHeader>(IsOffscreenBehavior.FromClip);
}
/// <summary>

2
src/Avalonia.Controls.DataGrid/DataGridRow.cs

@ -17,6 +17,7 @@ using System;
using System.Diagnostics;
using Avalonia.Automation.Peers;
using Avalonia.Reactive;
using Avalonia.Automation;
namespace Avalonia.Controls
{
@ -143,6 +144,7 @@ namespace Avalonia.Controls
AreDetailsVisibleProperty.Changed.AddClassHandler<DataGridRow>((x, e) => x.OnAreDetailsVisibleChanged(e));
PointerPressedEvent.AddClassHandler<DataGridRow>((x, e) => x.DataGridRow_PointerPressed(e), handledEventsToo: true);
IsTabStopProperty.OverrideDefaultValue<DataGridRow>(false);
AutomationProperties.IsOffscreenBehaviorProperty.OverrideDefaultValue<DataGridRow>(IsOffscreenBehavior.FromClip);
}
/// <summary>

6
src/Avalonia.Controls.DataGrid/DataGridRowHeader.cs

@ -3,6 +3,7 @@
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using Avalonia.Automation;
using Avalonia.Controls.Metadata;
using Avalonia.Input;
using Avalonia.Media;
@ -50,6 +51,11 @@ namespace Avalonia.Controls.Primitives
AddHandler(PointerPressedEvent, DataGridRowHeader_PointerPressed, handledEventsToo: true);
}
static DataGridRowHeader()
{
AutomationProperties.IsOffscreenBehaviorProperty.OverrideDefaultValue<DataGridRowHeader>(IsOffscreenBehavior.FromClip);
}
internal Control Owner
{
get;

12
src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs

@ -153,6 +153,17 @@ namespace Avalonia.Automation.Peers
/// <returns></returns>
public bool IsKeyboardFocusable() => IsKeyboardFocusableCore();
/// <summary>
/// Gets a value that indicates whether an element is off the screen.
/// </summary>
/// <remarks>
/// This property does not indicate whether the element is visible. In some circumstances,
/// an element is on the screen but is still not visible. For example, if the element is
/// on the screen but obscured by other elements, it might not be visible. In this case,
/// the method returns false.
/// </remarks>
public bool IsOffscreen() => IsOffscreenCore();
/// <summary>
/// Sets the keyboard focus on the element that is associated with this automation peer.
/// </summary>
@ -245,6 +256,7 @@ namespace Avalonia.Automation.Peers
protected abstract bool IsControlElementCore();
protected abstract bool IsEnabledCore();
protected abstract bool IsKeyboardFocusableCore();
protected virtual bool IsOffscreenCore() => false;
protected abstract void SetFocusCore();
protected abstract bool ShowContextMenuCore();

14
src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Utilities;
using Avalonia.VisualTree;
namespace Avalonia.Automation.Peers
@ -201,6 +202,19 @@ namespace Avalonia.Automation.Peers
return view == AccessibilityView.Default ? IsControlElementCore() : view >= AccessibilityView.Control;
}
protected override bool IsOffscreenCore()
{
return AutomationProperties.GetIsOffscreenBehavior(Owner) switch
{
IsOffscreenBehavior.Onscreen => false,
IsOffscreenBehavior.Offscreen => true,
IsOffscreenBehavior.FromClip => Owner.GetTransformedBounds() is not { } bounds ||
MathUtilities.IsZero(bounds.Clip.Width) ||
MathUtilities.IsZero(bounds.Clip.Height),
_ => !Owner.IsVisible,
};
}
private static Rect GetBounds(Control control)
{
var root = control.GetVisualRoot();

6
src/Avalonia.Controls/BorderVisual.cs

@ -46,9 +46,9 @@ class CompositionBorderVisual : CompositionDrawListVisual
{
}
protected override void RenderCore(CompositorDrawingContextProxy canvas, LtrbRect currentTransformedClip,
IDirtyRectTracker dirtyRects)
protected override void RenderCore(ServerVisualRenderContext ctx, LtrbRect currentTransformedClip)
{
var canvas = ctx.Canvas;
if (ClipToBounds)
{
var clipRect = Root!.SnapToDevicePixels(new Rect(new Size(Size.X, Size.Y)));
@ -58,7 +58,7 @@ class CompositionBorderVisual : CompositionDrawListVisual
canvas.PushClip(new RoundedRect(clipRect, _cornerRadius));
}
base.RenderCore(canvas, currentTransformedClip, dirtyRects);
base.RenderCore(ctx, currentTransformedClip);
if(ClipToBounds)
canvas.PopClip();

2
src/Avalonia.Controls/ListBoxItem.cs

@ -1,3 +1,4 @@
using Avalonia.Automation;
using Avalonia.Automation.Peers;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Mixins;
@ -30,6 +31,7 @@ namespace Avalonia.Controls
SelectableMixin.Attach<ListBoxItem>(IsSelectedProperty);
PressedMixin.Attach<ListBoxItem>();
FocusableProperty.OverrideDefaultValue<ListBoxItem>(true);
AutomationProperties.IsOffscreenBehaviorProperty.OverrideDefaultValue<ListBoxItem>(IsOffscreenBehavior.FromClip);
}
/// <summary>

2
src/Avalonia.Controls/MenuItem.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using Avalonia.Automation;
using Avalonia.Automation.Peers;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Mixins;
@ -141,6 +142,7 @@ namespace Avalonia.Controls
ItemsPanelProperty.OverrideDefaultValue<MenuItem>(DefaultPanel);
ClickEvent.AddClassHandler<MenuItem>((x, e) => x.OnClick(e));
SubmenuOpenedEvent.AddClassHandler<MenuItem>((x, e) => x.OnSubmenuOpened(e));
AutomationProperties.IsOffscreenBehaviorProperty.OverrideDefaultValue<MenuItem>(IsOffscreenBehavior.FromClip);
}
public MenuItem()

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

@ -152,6 +152,6 @@ namespace Avalonia.Platform
/// </summary>
/// <param name="windows">A span of windows to get their z-order</param>
/// <param name="zOrder">Span to be filled with associated window z-order</param>
internal void GetWindowsZOrder(Span<Window> windows, Span<long> zOrder);
void GetWindowsZOrder(Span<Window> windows, Span<long> zOrder);
}
}

1
src/Avalonia.Controls/Presenters/TextPresenter.cs

@ -604,6 +604,7 @@ namespace Avalonia.Controls.Presenters
_textLayout?.Dispose();
_textLayout = null;
InvalidateVisual();
InvalidateMeasure();
}

2
src/Avalonia.Controls/Primitives/TextSelectorLayer.cs

@ -27,7 +27,7 @@ namespace Avalonia.Controls.Primitives
{
foreach (Control child in Children)
child.Measure(availableSize);
return availableSize;
return default;
}
protected override Size ArrangeOverride(Size finalSize)

1
src/Avalonia.Controls/TabItem.cs

@ -39,6 +39,7 @@ namespace Avalonia.Controls
FocusableProperty.OverrideDefaultValue(typeof(TabItem), true);
DataContextProperty.Changed.AddClassHandler<TabItem>((x, e) => x.UpdateHeader(e));
AutomationProperties.ControlTypeOverrideProperty.OverrideDefaultValue<TabItem>(AutomationControlType.TabItem);
AutomationProperties.IsOffscreenBehaviorProperty.OverrideDefaultValue<TabItem>(IsOffscreenBehavior.FromClip);
AccessKeyHandler.AccessKeyPressedEvent.AddClassHandler<TabItem>((tabItem, args) => tabItem.TabItemActivated(args));
}

1
src/Avalonia.Controls/TextBlock.cs

@ -684,6 +684,7 @@ namespace Avalonia.Controls
/// </summary>
protected void InvalidateTextLayout()
{
InvalidateVisual();
InvalidateMeasure();
}

21
src/Avalonia.Controls/TextBox.cs

@ -406,6 +406,8 @@ namespace Avalonia.Controls
if (IsUndoEnabled && _undoRedoHelper.TryGetLastState(out state) && state.Text == Text)
_undoRedoHelper.UpdateLastState();
using var _ = _imClient.BeginChange();
var newValue = e.GetNewValue<int>();
SetCurrentValue(SelectionStartProperty, newValue);
SetCurrentValue(SelectionEndProperty, newValue);
@ -1216,6 +1218,8 @@ namespace Avalonia.Controls
var keymap = Application.Current!.PlatformSettings!.HotkeyConfiguration;
using var _ = _imClient.BeginChange();
bool Match(List<KeyGesture> gestures) => gestures.Any(g => g.Matches(e));
bool DetectSelection() => e.KeyModifiers.HasAllFlags(keymap.SelectionModifiers);
@ -1547,6 +1551,8 @@ namespace Avalonia.Controls
var text = Text;
var clickInfo = e.GetCurrentPoint(this);
using var _ = _imClient.BeginChange();
if (text != null && (e.Pointer.Type == PointerType.Mouse || e.ClickCount >= 2) && clickInfo.Properties.IsLeftButtonPressed &&
!(clickInfo.Pointer?.Captured is Border))
{
@ -1631,6 +1637,7 @@ namespace Avalonia.Controls
{
return;
}
using var _ = _imClient.BeginChange();
// selection should not change during pointer move if the user right clicks
if (e.Pointer.Captured == _presenter && e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
@ -1713,8 +1720,12 @@ namespace Avalonia.Controls
return;
}
using var _ = _imClient.BeginChange();
if (e.Pointer.Type != PointerType.Mouse && !_isDoubleTapped)
{
_imClient.ShowInputPanel();
var text = Text;
var clickInfo = e.GetCurrentPoint(this);
if (text != null && !(clickInfo.Pointer?.Captured is Border))
@ -1857,6 +1868,8 @@ namespace Avalonia.Controls
return;
}
using var _ = _imClient.BeginChange();
var text = Text ?? string.Empty;
var selectionStart = SelectionStart;
var selectionEnd = SelectionEnd;
@ -2017,6 +2030,8 @@ namespace Avalonia.Controls
/// </summary>
public void SelectAll()
{
using var _ = _imClient.BeginChange();
SetCurrentValue(SelectionStartProperty, 0);
SetCurrentValue(SelectionEndProperty, Text?.Length ?? 0);
}
@ -2034,6 +2049,8 @@ namespace Avalonia.Controls
if (IsReadOnly)
return true;
using var _ = _imClient.BeginChange();
var (start, end) = GetSelectionRange();
if (start != end)
@ -2141,6 +2158,8 @@ namespace Avalonia.Controls
var text = Text ?? string.Empty;
var selectionStart = CaretIndex;
using var _ = _imClient.BeginChange();
MoveHorizontal(-1, true, false, false);
if (SelectionEnd > 0 &&
@ -2160,6 +2179,8 @@ namespace Avalonia.Controls
return;
}
using var _ = _imClient.BeginChange();
SetCurrentValue(SelectionStartProperty, CaretIndex);
MoveHorizontal(1, true, true, false);

71
src/Avalonia.Controls/TextBoxTextInputMethodClient.cs

@ -2,6 +2,7 @@ using System;
using Avalonia.Controls.Presenters;
using Avalonia.Input.TextInput;
using Avalonia.Media.TextFormatting;
using Avalonia.Reactive;
using Avalonia.Utilities;
namespace Avalonia.Controls
@ -10,6 +11,9 @@ namespace Avalonia.Controls
{
private TextBox? _parent;
private TextPresenter? _presenter;
private bool _selectionChanged;
private bool _isInChange;
private ITextInputMethodImpl? _im;
public override Visual TextViewVisual => _presenter!;
@ -21,7 +25,7 @@ namespace Avalonia.Controls
{
return "";
}
if (_parent.CaretIndex != _presenter.CaretIndex)
{
_presenter.SetCurrentValue(TextPresenter.CaretIndexProperty, _parent.CaretIndex);
@ -31,7 +35,7 @@ namespace Avalonia.Controls
{
_presenter.SetCurrentValue(TextPresenter.TextProperty, _parent.Text);
}
var lineIndex = _presenter.TextLayout.GetLineIndexFromCharacterIndex(_presenter.CaretIndex, false);
var textLine = _presenter.TextLayout.TextLines[lineIndex];
@ -122,6 +126,11 @@ namespace Avalonia.Controls
if (_parent != null)
{
_parent.PropertyChanged += OnParentPropertyChanged;
_im = (_parent.VisualRoot as ITextInputMethodRoot)?.InputMethod;
}
else
{
_im = null;
}
var oldPresenter = _presenter;
@ -130,7 +139,7 @@ namespace Avalonia.Controls
{
oldPresenter.ClearValue(TextPresenter.PreeditTextProperty);
oldPresenter.CaretBoundsChanged -= (s,e) => RaiseCursorRectangleChanged();
oldPresenter.CaretBoundsChanged -= (s, e) => RaiseCursorRectangleChanged();
}
_presenter = presenter;
@ -158,6 +167,17 @@ namespace Avalonia.Controls
_presenter.SetCurrentValue(TextPresenter.PreeditTextCursorPositionProperty, cursorPos);
}
public override void ShowInputPanel()
{
base.ShowInputPanel();
if (_parent is { } && _im is { })
{
_im.SetOptions(TextInputOptions.FromStyledElement(_parent));
_im.SetClient(this);
}
}
private static string GetTextLineText(TextLine textLine)
{
var builder = StringBuilderCache.Acquire(textLine.Length);
@ -181,6 +201,27 @@ namespace Avalonia.Controls
return lineText;
}
public override void ExecuteContextMenuAction(ContextMenuAction action)
{
base.ExecuteContextMenuAction(action);
switch (action)
{
case ContextMenuAction.Copy:
_parent?.Copy();
break;
case ContextMenuAction.Cut:
_parent?.Cut();
break;
case ContextMenuAction.Paste:
_parent?.Paste();
break;
case ContextMenuAction.SelectAll:
_parent?.SelectAll();
break;
}
}
private void OnParentPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if (e.Property == TextBox.TextProperty)
@ -190,8 +231,30 @@ namespace Avalonia.Controls
if (e.Property == TextBox.SelectionStartProperty || e.Property == TextBox.SelectionEndProperty)
{
RaiseSelectionChanged();
if (_isInChange)
_selectionChanged = true;
else
RaiseSelectionChanged();
}
}
internal IDisposable BeginChange()
{
if (_isInChange)
return Disposable.Empty;
_isInChange = true;
return Disposable.Create(RaiseEvents);
}
private void RaiseEvents()
{
_isInChange = false;
if (_selectionChanged)
RaiseSelectionChanged();
_selectionChanged = false;
}
}
}

2
src/Avalonia.Controls/ToolTipService.cs

@ -79,7 +79,7 @@ namespace Avalonia.Controls
{
var currentToolTip = _tipControl?.GetValue(ToolTip.ToolTipProperty);
if (root == currentToolTip?.VisualRoot)
if (root == currentToolTip?.PopupHost?.HostedVisualTreeRoot)
{
// Don't update while the pointer is over a tooltip
return;

3
src/Avalonia.Controls/TreeViewItem.cs

@ -2,6 +2,8 @@ using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using Avalonia.Automation;
using Avalonia.Automation.Peers;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Mixins;
using Avalonia.Controls.Primitives;
@ -61,6 +63,7 @@ namespace Avalonia.Controls
PressedMixin.Attach<TreeViewItem>();
FocusableProperty.OverrideDefaultValue<TreeViewItem>(true);
ItemsPanelProperty.OverrideDefaultValue<TreeViewItem>(DefaultPanel);
AutomationProperties.IsOffscreenBehaviorProperty.OverrideDefaultValue<TreeViewItem>(IsOffscreenBehavior.FromClip);
RequestBringIntoViewEvent.AddClassHandler<TreeViewItem>((x, e) => x.OnRequestBringIntoView(e));
}

3
src/Avalonia.Dialogs/Avalonia.Dialogs.csproj

@ -16,7 +16,8 @@
<ItemGroup>
<!-- For managed dialogs dev testing -->
<InternalsVisibleTo Include="ControlCatalog, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="ControlCatalog, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.X11, PublicKey=$(AvaloniaPublicKey)" />
</ItemGroup>
<Import Project="..\..\build\DevAnalyzers.props" />

2
src/Avalonia.FreeDesktop/DBusIme/X11DBusImeHelper.cs

@ -12,6 +12,8 @@ namespace Avalonia.FreeDesktop.DBusIme
{
["fcitx"] = static conn =>
new DBusInputMethodFactory<FcitxX11TextInputMethod>(_ => new FcitxX11TextInputMethod(conn)),
["fcitx5"] = static conn =>
new DBusInputMethodFactory<FcitxX11TextInputMethod>(_ => new FcitxX11TextInputMethod(conn)),
["ibus"] = static conn =>
new DBusInputMethodFactory<IBusX11TextInputMethod>(_ => new IBusX11TextInputMethod(conn))
};

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

Loading…
Cancel
Save