diff --git a/Avalonia.Desktop.slnf b/Avalonia.Desktop.slnf index b021c9f4a5..67ca3c2bf1 100644 --- a/Avalonia.Desktop.slnf +++ b/Avalonia.Desktop.slnf @@ -10,7 +10,6 @@ "samples\\IntegrationTestApp\\IntegrationTestApp.csproj", "samples\\TextTestApp\\TextTestApp.csproj", "samples\\MiniMvvm\\MiniMvvm.csproj", - "samples\\ReactiveUIDemo\\ReactiveUIDemo.csproj", "samples\\RenderDemo\\RenderDemo.csproj", "samples\\SampleControls\\ControlSamples.csproj", "samples\\Sandbox\\Sandbox.csproj", @@ -32,7 +31,6 @@ "src\\Avalonia.Native\\Avalonia.Native.csproj", "src\\Avalonia.OpenGL\\Avalonia.OpenGL.csproj", "src\\Avalonia.Vulkan\\Avalonia.Vulkan.csproj", - "src\\Avalonia.ReactiveUI\\Avalonia.ReactiveUI.csproj", "src\\Avalonia.Remote.Protocol\\Avalonia.Remote.Protocol.csproj", "src\\Avalonia.Themes.Fluent\\Avalonia.Themes.Fluent.csproj", "src\\Avalonia.Themes.Simple\\Avalonia.Themes.Simple.csproj", @@ -65,7 +63,6 @@ "tests\\Avalonia.LeakTests\\Avalonia.LeakTests.csproj", "tests\\Avalonia.Markup.UnitTests\\Avalonia.Markup.UnitTests.csproj", "tests\\Avalonia.Markup.Xaml.UnitTests\\Avalonia.Markup.Xaml.UnitTests.csproj", - "tests\\Avalonia.ReactiveUI.UnitTests\\Avalonia.ReactiveUI.UnitTests.csproj", "tests\\Avalonia.RenderTests.WpfCompare\\Avalonia.RenderTests.WpfCompare.csproj", "tests\\Avalonia.Skia.RenderTests\\Avalonia.Skia.RenderTests.csproj", "tests\\Avalonia.Skia.UnitTests\\Avalonia.Skia.UnitTests.csproj", diff --git a/Avalonia.sln b/Avalonia.sln index 8413f571c5..b7625ed1dd 100644 --- a/Avalonia.sln +++ b/Avalonia.sln @@ -9,8 +9,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Windows", "Windows", "{B39A EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Win32", "src\Windows\Avalonia.Win32\Avalonia.Win32.csproj", "{811A76CF-1CF6-440F-963B-BBE31BD72A82}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Direct2D1", "src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj", "{3E908F67-5543-4879-A1DC-08EACE79B3CD}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls", "src\Avalonia.Controls\Avalonia.Controls.csproj", "{D2221C82-4A25-4583-9B43-D791E3F6820C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Themes.Simple", "src\Avalonia.Themes.Simple\Avalonia.Themes.Simple.csproj", "{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}" @@ -23,10 +21,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls.UnitTests EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Base.UnitTests", "tests\Avalonia.Base.UnitTests\Avalonia.Base.UnitTests.csproj", "{2905FF23-53FB-45E6-AA49-6AF47A172056}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Direct2D1.RenderTests", "tests\Avalonia.Direct2D1.RenderTests\Avalonia.Direct2D1.RenderTests.csproj", "{DABFD304-D6A4-4752-8123-C2CCF7AC7831}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Direct2D1.UnitTests", "tests\Avalonia.Direct2D1.UnitTests\Avalonia.Direct2D1.UnitTests.csproj", "{EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup.Xaml.UnitTests", "tests\Avalonia.Markup.Xaml.UnitTests\Avalonia.Markup.Xaml.UnitTests.csproj", "{99135EAB-653D-47E4-A378-C96E1278CA44}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Markup", "Markup", "{8B6A8209-894F-4BA1-B880-965FD453982C}" @@ -46,8 +40,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{A689DE src\Shared\StreamCompatibilityExtensions.cs = src\Shared\StreamCompatibilityExtensions.cs EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI", "src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj", "{6417B24E-49C2-4985-8DB2-3AB9D898EC91}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup", "src\Markup\Avalonia.Markup\Avalonia.Markup.csproj", "{6417E941-21BC-467B-A771-0DE389353CE6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup.UnitTests", "tests\Avalonia.Markup.UnitTests\Avalonia.Markup.UnitTests.csproj", "{8EF392D5-1416-45AA-9956-7CBBC3229E8A}" @@ -88,8 +80,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Android", "s EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia", "src\Skia\Avalonia.Skia\Avalonia.Skia.csproj", "{7D2D3083-71DD-4CC9-8907-39A0D86FB322}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.NetCore", "samples\ControlCatalog.NetCore\ControlCatalog.NetCore.csproj", "{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1-27F5-4255-9AFC-04ABFD11683A}" ProjectSection(SolutionItems) = preProject build\AvaloniaPublicKey.props = build\AvaloniaPublicKey.props @@ -108,12 +98,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1 build\NetCore.props = build\NetCore.props build\NetFX.props = build\NetFX.props build\NullableEnable.props = build\NullableEnable.props - build\ReactiveUI.props = build\ReactiveUI.props build\ReferenceCoreLibraries.props = build\ReferenceCoreLibraries.props build\Rx.props = build\Rx.props build\SampleApp.props = build\SampleApp.props build\SharedVersion.props = build\SharedVersion.props - build\SharpDX.props = build\SharpDX.props build\SkiaSharp.props = build\SkiaSharp.props build\SourceGenerators.props = build\SourceGenerators.props build\SourceLink.props = build\SourceLink.props @@ -171,8 +159,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.X11", "src\Avaloni EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlatformSanityChecks", "samples\PlatformSanityChecks\PlatformSanityChecks.csproj", "{D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI.UnitTests", "tests\Avalonia.ReactiveUI.UnitTests\Avalonia.ReactiveUI.UnitTests.csproj", "{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Dialogs", "src\Avalonia.Dialogs\Avalonia.Dialogs.csproj", "{4D55985A-1EE2-4F25-AD39-6EA8BC04F8FB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.FreeDesktop", "src\Avalonia.FreeDesktop\Avalonia.FreeDesktop.csproj", "{4D36CEC8-53F2-40A5-9A37-79AAE356E2DA}" @@ -217,14 +203,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SingleProjectSandbox", "sam EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Browser", "src\Browser\Avalonia.Browser\Avalonia.Browser.csproj", "{4A39637C-9338-4925-A4DB-D072E292EC78}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Browser.Blazor", "src\Browser\Avalonia.Browser.Blazor\Avalonia.Browser.Blazor.csproj", "{47F8530C-F19B-4B1A-B4D6-EB231522AE5D}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Browser", "samples\ControlCatalog.Browser\ControlCatalog.Browser.csproj", "{15B93A4C-1B46-43F6-B534-7B25B6E99932}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Browser.Blazor", "samples\ControlCatalog.Browser.Blazor\ControlCatalog.Browser.Blazor.csproj", "{90B08091-9BBD-4362-B712-E9F2CC62B218}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUIDemo", "samples\ReactiveUIDemo\ReactiveUIDemo.csproj", "{75C47156-C5D8-44BC-A5A7-E8657C2248D6}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GpuInterop", "samples\GpuInterop\GpuInterop.csproj", "{C810060E-3809-4B74-A125-F11533AF9C1B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Analyzers", "src\tools\Avalonia.Analyzers\Avalonia.Analyzers.csproj", "{C692FE73-43DB-49CE-87FC-F03ED61F25C9}" @@ -320,10 +300,6 @@ Global {811A76CF-1CF6-440F-963B-BBE31BD72A82}.Debug|Any CPU.Build.0 = Debug|Any CPU {811A76CF-1CF6-440F-963B-BBE31BD72A82}.Release|Any CPU.ActiveCfg = Release|Any CPU {811A76CF-1CF6-440F-963B-BBE31BD72A82}.Release|Any CPU.Build.0 = Release|Any CPU - {3E908F67-5543-4879-A1DC-08EACE79B3CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3E908F67-5543-4879-A1DC-08EACE79B3CD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3E908F67-5543-4879-A1DC-08EACE79B3CD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3E908F67-5543-4879-A1DC-08EACE79B3CD}.Release|Any CPU.Build.0 = Release|Any CPU {D2221C82-4A25-4583-9B43-D791E3F6820C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D2221C82-4A25-4583-9B43-D791E3F6820C}.Debug|Any CPU.Build.0 = Debug|Any CPU {D2221C82-4A25-4583-9B43-D791E3F6820C}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -344,14 +320,6 @@ Global {2905FF23-53FB-45E6-AA49-6AF47A172056}.Debug|Any CPU.Build.0 = Debug|Any CPU {2905FF23-53FB-45E6-AA49-6AF47A172056}.Release|Any CPU.ActiveCfg = Release|Any CPU {2905FF23-53FB-45E6-AA49-6AF47A172056}.Release|Any CPU.Build.0 = Release|Any CPU - {DABFD304-D6A4-4752-8123-C2CCF7AC7831}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DABFD304-D6A4-4752-8123-C2CCF7AC7831}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DABFD304-D6A4-4752-8123-C2CCF7AC7831}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DABFD304-D6A4-4752-8123-C2CCF7AC7831}.Release|Any CPU.Build.0 = Release|Any CPU - {EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}.Release|Any CPU.Build.0 = Release|Any CPU {99135EAB-653D-47E4-A378-C96E1278CA44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {99135EAB-653D-47E4-A378-C96E1278CA44}.Debug|Any CPU.Build.0 = Debug|Any CPU {99135EAB-653D-47E4-A378-C96E1278CA44}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -360,10 +328,6 @@ Global {3E53A01A-B331-47F3-B828-4A5717E77A24}.Debug|Any CPU.Build.0 = Debug|Any CPU {3E53A01A-B331-47F3-B828-4A5717E77A24}.Release|Any CPU.ActiveCfg = Release|Any CPU {3E53A01A-B331-47F3-B828-4A5717E77A24}.Release|Any CPU.Build.0 = Release|Any CPU - {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Release|Any CPU.Build.0 = Release|Any CPU {6417E941-21BC-467B-A771-0DE389353CE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6417E941-21BC-467B-A771-0DE389353CE6}.Debug|Any CPU.Build.0 = Debug|Any CPU {6417E941-21BC-467B-A771-0DE389353CE6}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -430,10 +394,6 @@ Global {7D2D3083-71DD-4CC9-8907-39A0D86FB322}.Debug|Any CPU.Build.0 = Debug|Any CPU {7D2D3083-71DD-4CC9-8907-39A0D86FB322}.Release|Any CPU.ActiveCfg = Release|Any CPU {7D2D3083-71DD-4CC9-8907-39A0D86FB322}.Release|Any CPU.Build.0 = Release|Any CPU - {39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Release|Any CPU.Build.0 = Release|Any CPU {854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|Any CPU.Build.0 = Debug|Any CPU {854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -496,10 +456,6 @@ Global {D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B}.Debug|Any CPU.Build.0 = Debug|Any CPU {D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B}.Release|Any CPU.ActiveCfg = Release|Any CPU {D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B}.Release|Any CPU.Build.0 = Release|Any CPU - {AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Release|Any CPU.Build.0 = Release|Any CPU {4D55985A-1EE2-4F25-AD39-6EA8BC04F8FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4D55985A-1EE2-4F25-AD39-6EA8BC04F8FB}.Debug|Any CPU.Build.0 = Debug|Any CPU {4D55985A-1EE2-4F25-AD39-6EA8BC04F8FB}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -584,22 +540,10 @@ Global {4A39637C-9338-4925-A4DB-D072E292EC78}.Debug|Any CPU.Build.0 = Debug|Any CPU {4A39637C-9338-4925-A4DB-D072E292EC78}.Release|Any CPU.ActiveCfg = Release|Any CPU {4A39637C-9338-4925-A4DB-D072E292EC78}.Release|Any CPU.Build.0 = Release|Any CPU - {47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Release|Any CPU.Build.0 = Release|Any CPU {15B93A4C-1B46-43F6-B534-7B25B6E99932}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {15B93A4C-1B46-43F6-B534-7B25B6E99932}.Debug|Any CPU.Build.0 = Debug|Any CPU {15B93A4C-1B46-43F6-B534-7B25B6E99932}.Release|Any CPU.ActiveCfg = Release|Any CPU {15B93A4C-1B46-43F6-B534-7B25B6E99932}.Release|Any CPU.Build.0 = Release|Any CPU - {90B08091-9BBD-4362-B712-E9F2CC62B218}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {90B08091-9BBD-4362-B712-E9F2CC62B218}.Debug|Any CPU.Build.0 = Debug|Any CPU - {90B08091-9BBD-4362-B712-E9F2CC62B218}.Release|Any CPU.ActiveCfg = Release|Any CPU - {90B08091-9BBD-4362-B712-E9F2CC62B218}.Release|Any CPU.Build.0 = Release|Any CPU - {75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Release|Any CPU.Build.0 = Release|Any CPU {C810060E-3809-4B74-A125-F11533AF9C1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C810060E-3809-4B74-A125-F11533AF9C1B}.Debug|Any CPU.Build.0 = Debug|Any CPU {C810060E-3809-4B74-A125-F11533AF9C1B}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -722,11 +666,8 @@ Global EndGlobalSection GlobalSection(NestedProjects) = preSolution {811A76CF-1CF6-440F-963B-BBE31BD72A82} = {B39A8919-9F95-48FE-AD7B-76E08B509888} - {3E908F67-5543-4879-A1DC-08EACE79B3CD} = {B39A8919-9F95-48FE-AD7B-76E08B509888} {5CCB5571-7C30-4E7D-967D-0E2158EBD91F} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {2905FF23-53FB-45E6-AA49-6AF47A172056} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} - {DABFD304-D6A4-4752-8123-C2CCF7AC7831} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} - {EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {99135EAB-653D-47E4-A378-C96E1278CA44} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {3E53A01A-B331-47F3-B828-4A5717E77A24} = {8B6A8209-894F-4BA1-B880-965FD453982C} {6417E941-21BC-467B-A771-0DE389353CE6} = {8B6A8209-894F-4BA1-B880-965FD453982C} @@ -745,7 +686,6 @@ Global {F1FDC5B0-4654-416F-AE69-E3E9BBD87801} = {9B9E3891-2366-4253-A952-D08BCEB71098} {29132311-1848-4FD6-AE0C-4FF841151BD3} = {9B9E3891-2366-4253-A952-D08BCEB71098} {7D2D3083-71DD-4CC9-8907-39A0D86FB322} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E} - {39D7B147-1A5B-47C2-9D01-21FB7C47C4B3} = {9B9E3891-2366-4253-A952-D08BCEB71098} {854568D5-13D1-4B4F-B50D-534DC7EFD3C9} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B} {CBC4FF2F-92D4-420B-BE21-9FE0B930B04E} = {B39A8919-9F95-48FE-AD7B-76E08B509888} {E1582370-37B3-403C-917F-8209551B1634} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} @@ -757,7 +697,6 @@ Global {3C471044-3640-45E3-B1B2-16D2FF8399EE} = {E870DCD7-F46A-498D-83FC-D0FD13E0A11C} {41B02319-965D-4945-8005-C1A3D1224165} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B} {D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B} = {9B9E3891-2366-4253-A952-D08BCEB71098} - {AF915D5C-AB00-4EA0-B5E6-001F4AE84E68} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {4D36CEC8-53F2-40A5-9A37-79AAE356E2DA} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B} {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC} = {FF237916-7150-496B-89ED-6CA3292896E7} {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E} = {FF237916-7150-496B-89ED-6CA3292896E7} @@ -775,10 +714,7 @@ Global {1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637} {3B8519C1-2F51-4F12-A348-120AB91D4532} = {9B9E3891-2366-4253-A952-D08BCEB71098} {4A39637C-9338-4925-A4DB-D072E292EC78} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268} - {47F8530C-F19B-4B1A-B4D6-EB231522AE5D} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268} {15B93A4C-1B46-43F6-B534-7B25B6E99932} = {9B9E3891-2366-4253-A952-D08BCEB71098} - {90B08091-9BBD-4362-B712-E9F2CC62B218} = {9B9E3891-2366-4253-A952-D08BCEB71098} - {75C47156-C5D8-44BC-A5A7-E8657C2248D6} = {9B9E3891-2366-4253-A952-D08BCEB71098} {C810060E-3809-4B74-A125-F11533AF9C1B} = {9B9E3891-2366-4253-A952-D08BCEB71098} {C692FE73-43DB-49CE-87FC-F03ED61F25C9} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637} {DDA28789-C21A-4654-86CE-D01E81F095C5} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d3ed95005d..8351fc2ea6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,7 @@ A bug fix will ideally be accompanied by tests. There are a few types of tests: - Unit tests are for issues that aren't related to platform features. These tests are located in the `tests` directly, categorised by the assembly which they're testing. - Integration tests are for issues that are related to platform features (for example fixing a bug with Window resizing). These tests are located in the `tests/Avalonia.IntegrationTests.Appium` directory. Integration tests should be run on Windows and macOS. See the readme in that directory for more information -- Render tests are for issues with rendering. These tests are located in `tests/Avalonia.RenderTests` with separate project files for Skia and Direct2D. The Direct2D backend is currently mostly unmaintained so render tests that just run on Skia are acceptable +- Render tests are for issues with rendering. These tests are located in `tests/Avalonia.RenderTests` and are imported in the `Avalonia.Skia.RenderTests` project. It's not always feasible to accompany a bug fix with a test, but doing so will speed up the review process. @@ -88,4 +88,4 @@ Render tests should describe what the produced image is: ## Code of Conduct This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community. -For more information see the [Contributor Covenant Code of Conduct](https://dotnetfoundation.org/code-of-conduct) \ No newline at end of file +For more information see the [Contributor Covenant Code of Conduct](https://dotnetfoundation.org/code-of-conduct) diff --git a/Directory.Build.props b/Directory.Build.props index f124456eab..4498f87dab 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,11 +4,11 @@ $(MSBuildThisFileDirectory)build-intermediate/nuget - $(MSBuildThisFileDirectory)\src\tools\Avalonia.Designer.HostApp\bin\$(Configuration)\netstandard2.0\Avalonia.Designer.HostApp.dll + $(MSBuildThisFileDirectory)\src\tools\Avalonia.Designer.HostApp\bin\$(Configuration)\$(AvsCurrentTargetFramework)\Avalonia.Designer.HostApp.dll false False - 12 + 14.0 true true true diff --git a/api/Avalonia.Win32.Interoperability.nupkg.xml b/api/Avalonia.Win32.Interoperability.nupkg.xml new file mode 100644 index 0000000000..3672bb9b99 --- /dev/null +++ b/api/Avalonia.Win32.Interoperability.nupkg.xml @@ -0,0 +1,40 @@ + + + + + CP0002 + M:Avalonia.Win32.Interoperability.WinFormsAvaloniaControlHost.PreFilterMessage(System.Windows.Forms.Message@) + baseline/Avalonia.Win32.Interoperability/lib/net461/Avalonia.Win32.Interoperability.dll + current/Avalonia.Win32.Interoperability/lib/net461/Avalonia.Win32.Interoperability.dll + + + CP0002 + M:Avalonia.Win32.Interoperability.WinFormsAvaloniaControlHost.PreFilterMessage(System.Windows.Forms.Message@) + baseline/Avalonia.Win32.Interoperability/lib/net6.0-windows7.0/Avalonia.Win32.Interoperability.dll + current/Avalonia.Win32.Interoperability/lib/net6.0-windows7.0/Avalonia.Win32.Interoperability.dll + + + CP0002 + M:Avalonia.Win32.Interoperability.WinFormsAvaloniaControlHost.PreFilterMessage(System.Windows.Forms.Message@) + baseline/Avalonia.Win32.Interoperability/lib/net8.0-windows7.0/Avalonia.Win32.Interoperability.dll + current/Avalonia.Win32.Interoperability/lib/net8.0-windows7.0/Avalonia.Win32.Interoperability.dll + + + CP0008 + T:Avalonia.Win32.Interoperability.WinFormsAvaloniaControlHost + baseline/Avalonia.Win32.Interoperability/lib/net461/Avalonia.Win32.Interoperability.dll + current/Avalonia.Win32.Interoperability/lib/net461/Avalonia.Win32.Interoperability.dll + + + CP0008 + T:Avalonia.Win32.Interoperability.WinFormsAvaloniaControlHost + baseline/Avalonia.Win32.Interoperability/lib/net6.0-windows7.0/Avalonia.Win32.Interoperability.dll + current/Avalonia.Win32.Interoperability/lib/net6.0-windows7.0/Avalonia.Win32.Interoperability.dll + + + CP0008 + T:Avalonia.Win32.Interoperability.WinFormsAvaloniaControlHost + baseline/Avalonia.Win32.Interoperability/lib/net8.0-windows7.0/Avalonia.Win32.Interoperability.dll + current/Avalonia.Win32.Interoperability/lib/net8.0-windows7.0/Avalonia.Win32.Interoperability.dll + + diff --git a/api/Avalonia.nupkg.xml b/api/Avalonia.nupkg.xml index fbf22358ed..af46d2fb2e 100644 --- a/api/Avalonia.nupkg.xml +++ b/api/Avalonia.nupkg.xml @@ -1,24 +1,150 @@ - + + + CP0001 + T:Avalonia.Media.Fonts.FontFamilyLoader + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + + + CP0001 + T:Avalonia.Media.Fonts.FontFamilyLoader + baseline/Avalonia/lib/net6.0/Avalonia.Base.dll + current/Avalonia/lib/net6.0/Avalonia.Base.dll + + + CP0001 + T:Avalonia.Media.Fonts.FontFamilyLoader + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + + + CP0001 + T:Avalonia.Media.Fonts.FontFamilyLoader + baseline/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + current/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + + + CP0002 + F:Avalonia.Media.Fonts.FontCollectionBase._glyphTypefaceCache + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Media.Fonts.FontCollectionBase.Initialize(Avalonia.Platform.IFontManagerImpl) + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Media.Fonts.IFontCollection.Initialize(Avalonia.Platform.IFontManagerImpl) + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,System.Globalization.CultureInfo,Avalonia.Media.Typeface@) + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + + + CP0002 + F:Avalonia.Media.Fonts.FontCollectionBase._glyphTypefaceCache + baseline/Avalonia/lib/net6.0/Avalonia.Base.dll + current/Avalonia/lib/net6.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Media.Fonts.FontCollectionBase.Initialize(Avalonia.Platform.IFontManagerImpl) + baseline/Avalonia/lib/net6.0/Avalonia.Base.dll + current/Avalonia/lib/net6.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Media.Fonts.IFontCollection.Initialize(Avalonia.Platform.IFontManagerImpl) + baseline/Avalonia/lib/net6.0/Avalonia.Base.dll + current/Avalonia/lib/net6.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,System.Globalization.CultureInfo,Avalonia.Media.Typeface@) + baseline/Avalonia/lib/net6.0/Avalonia.Base.dll + current/Avalonia/lib/net6.0/Avalonia.Base.dll + CP0002 M:Avalonia.Dialogs.Internal.ManagedFileChooserFilterViewModel.#ctor(Avalonia.Platform.Storage.FilePickerFileType) baseline/Avalonia/lib/net6.0/Avalonia.Dialogs.dll current/Avalonia/lib/net6.0/Avalonia.Dialogs.dll + + CP0002 + F:Avalonia.Media.Fonts.FontCollectionBase._glyphTypefaceCache + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Media.Fonts.FontCollectionBase.Initialize(Avalonia.Platform.IFontManagerImpl) + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Media.Fonts.IFontCollection.Initialize(Avalonia.Platform.IFontManagerImpl) + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,System.Globalization.CultureInfo,Avalonia.Media.Typeface@) + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + CP0002 M:Avalonia.Dialogs.Internal.ManagedFileChooserFilterViewModel.#ctor(Avalonia.Platform.Storage.FilePickerFileType) baseline/Avalonia/lib/net8.0/Avalonia.Dialogs.dll current/Avalonia/lib/net8.0/Avalonia.Dialogs.dll + + CP0002 + F:Avalonia.Media.Fonts.FontCollectionBase._glyphTypefaceCache + baseline/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + current/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Media.Fonts.FontCollectionBase.Initialize(Avalonia.Platform.IFontManagerImpl) + baseline/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + current/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Media.Fonts.IFontCollection.Initialize(Avalonia.Platform.IFontManagerImpl) + baseline/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + current/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,System.Globalization.CultureInfo,Avalonia.Media.Typeface@) + baseline/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + current/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + CP0002 M:Avalonia.Dialogs.Internal.ManagedFileChooserFilterViewModel.#ctor(Avalonia.Platform.Storage.FilePickerFileType) baseline/Avalonia/lib/netstandard2.0/Avalonia.Dialogs.dll current/Avalonia/lib/netstandard2.0/Avalonia.Dialogs.dll + + CP0006 + M:Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,System.String,System.Globalization.CultureInfo,Avalonia.Media.Typeface@) + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + CP0006 M:Avalonia.Input.Platform.IClipboard.SetDataAsync(Avalonia.Input.IAsyncDataTransfer) @@ -43,6 +169,12 @@ baseline/Avalonia/lib/net6.0/Avalonia.Base.dll current/Avalonia/lib/net6.0/Avalonia.Base.dll + + CP0006 + M:Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,System.String,System.Globalization.CultureInfo,Avalonia.Media.Typeface@) + baseline/Avalonia/lib/net6.0/Avalonia.Base.dll + current/Avalonia/lib/net6.0/Avalonia.Base.dll + CP0006 M:Avalonia.Platform.IPlatformRenderInterfaceImportedImage.SnapshotWithTimelineSemaphores(Avalonia.Platform.IPlatformRenderInterfaceImportedSemaphore,System.UInt64,Avalonia.Platform.IPlatformRenderInterfaceImportedSemaphore,System.UInt64) @@ -97,6 +229,12 @@ baseline/Avalonia/lib/net8.0/Avalonia.Base.dll current/Avalonia/lib/net8.0/Avalonia.Base.dll + + CP0006 + M:Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,System.String,System.Globalization.CultureInfo,Avalonia.Media.Typeface@) + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + CP0006 M:Avalonia.Platform.IPlatformRenderInterfaceImportedImage.SnapshotWithTimelineSemaphores(Avalonia.Platform.IPlatformRenderInterfaceImportedSemaphore,System.UInt64,Avalonia.Platform.IPlatformRenderInterfaceImportedSemaphore,System.UInt64) @@ -151,6 +289,12 @@ baseline/Avalonia/lib/netstandard2.0/Avalonia.Base.dll current/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + + CP0006 + M:Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,System.String,System.Globalization.CultureInfo,Avalonia.Media.Typeface@) + baseline/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + current/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + CP0006 M:Avalonia.Platform.IPlatformRenderInterfaceImportedImage.SnapshotWithTimelineSemaphores(Avalonia.Platform.IPlatformRenderInterfaceImportedSemaphore,System.UInt64,Avalonia.Platform.IPlatformRenderInterfaceImportedSemaphore,System.UInt64) @@ -181,4 +325,124 @@ baseline/Avalonia/lib/netstandard2.0/Avalonia.OpenGL.dll current/Avalonia/lib/netstandard2.0/Avalonia.OpenGL.dll - \ No newline at end of file + + CP0012 + M:Avalonia.Media.Fonts.FontCollectionBase.get_Count + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + + + CP0012 + M:Avalonia.Media.Fonts.FontCollectionBase.get_Item(System.Int32) + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + + + CP0012 + M:Avalonia.Media.Fonts.FontCollectionBase.GetEnumerator + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + + + CP0012 + P:Avalonia.Media.Fonts.FontCollectionBase.Count + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + + + CP0012 + P:Avalonia.Media.Fonts.FontCollectionBase.Item(System.Int32) + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + + + CP0012 + M:Avalonia.Media.Fonts.FontCollectionBase.get_Count + baseline/Avalonia/lib/net6.0/Avalonia.Base.dll + current/Avalonia/lib/net6.0/Avalonia.Base.dll + + + CP0012 + M:Avalonia.Media.Fonts.FontCollectionBase.get_Item(System.Int32) + baseline/Avalonia/lib/net6.0/Avalonia.Base.dll + current/Avalonia/lib/net6.0/Avalonia.Base.dll + + + CP0012 + M:Avalonia.Media.Fonts.FontCollectionBase.GetEnumerator + baseline/Avalonia/lib/net6.0/Avalonia.Base.dll + current/Avalonia/lib/net6.0/Avalonia.Base.dll + + + CP0012 + P:Avalonia.Media.Fonts.FontCollectionBase.Count + baseline/Avalonia/lib/net6.0/Avalonia.Base.dll + current/Avalonia/lib/net6.0/Avalonia.Base.dll + + + CP0012 + P:Avalonia.Media.Fonts.FontCollectionBase.Item(System.Int32) + baseline/Avalonia/lib/net6.0/Avalonia.Base.dll + current/Avalonia/lib/net6.0/Avalonia.Base.dll + + + CP0012 + M:Avalonia.Media.Fonts.FontCollectionBase.get_Count + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + + + CP0012 + M:Avalonia.Media.Fonts.FontCollectionBase.get_Item(System.Int32) + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + + + CP0012 + M:Avalonia.Media.Fonts.FontCollectionBase.GetEnumerator + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + + + CP0012 + P:Avalonia.Media.Fonts.FontCollectionBase.Count + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + + + CP0012 + P:Avalonia.Media.Fonts.FontCollectionBase.Item(System.Int32) + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + + + CP0012 + M:Avalonia.Media.Fonts.FontCollectionBase.get_Count + baseline/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + current/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + + + CP0012 + M:Avalonia.Media.Fonts.FontCollectionBase.get_Item(System.Int32) + baseline/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + current/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + + + CP0012 + M:Avalonia.Media.Fonts.FontCollectionBase.GetEnumerator + baseline/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + current/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + + + CP0012 + P:Avalonia.Media.Fonts.FontCollectionBase.Count + baseline/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + current/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + + + CP0012 + P:Avalonia.Media.Fonts.FontCollectionBase.Item(System.Int32) + baseline/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + current/Avalonia/lib/netstandard2.0/Avalonia.Base.dll + + diff --git a/azure-pipelines-integrationtests.yml b/azure-pipelines-integrationtests.yml index b34def779f..89b6a3ac53 100644 --- a/azure-pipelines-integrationtests.yml +++ b/azure-pipelines-integrationtests.yml @@ -5,13 +5,13 @@ jobs: steps: - task: UseDotNet@2 - displayName: 'Use .NET 6.0 Runtime' + displayName: 'Use .NET 8.0 Runtime' inputs: packageType: runtime - version: 6.0.x + version: 8.0.x - task: UseDotNet@2 - displayName: 'Use .NET 8.0 SDK' + displayName: 'Use .NET 10.0 SDK' inputs: packageType: sdk useGlobalJson: true @@ -31,11 +31,10 @@ jobs: pkill IntegrationTestApp sudo xcode-select -s /Applications/Xcode_15.2.app/Contents/Developer ./build.sh CompileNative - sudo xcode-select -s /Applications/Xcode_14.3.app/Contents/Developer rm -rf $(osascript -e "POSIX path of (path to application id \"net.avaloniaui.avalonia.integrationtestapp\")") pkill IntegrationTestApp ./samples/IntegrationTestApp/bundle.sh - open -n ./samples/IntegrationTestApp/bin/Debug/net8.0/osx-$arch/publish/IntegrationTestApp.app + open -n ./samples/IntegrationTestApp/bin/Debug/net10.0/osx-$arch/publish/IntegrationTestApp.app pkill IntegrationTestApp displayName: 'Build IntegrationTestApp' @@ -57,17 +56,17 @@ jobs: - job: Windows pool: - vmImage: 'windows-2022' + vmImage: 'windows-2025' steps: - task: UseDotNet@2 - displayName: 'Use .NET 6.0 Runtime' + displayName: 'Use .NET 8.0 Runtime' inputs: packageType: runtime - version: 6.0.x + version: 8.0.x - task: UseDotNet@2 - displayName: 'Use .NET 8.0 SDK' + displayName: 'Use .NET 10.0 SDK' inputs: packageType: sdk useGlobalJson: true diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 956bcde6d7..06da4bcd2b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -2,12 +2,12 @@ jobs: - job: GetPRNumber pool: - vmImage: 'ubuntu-22.04' + vmImage: 'ubuntu-24.04' variables: SolutionDir: '$(Build.SourcesDirectory)' steps: - task: UseDotNet@2 - displayName: 'Use .NET 8.0 SDK' + displayName: 'Use .NET 10.0 SDK' inputs: packageType: sdk useGlobalJson: true @@ -23,16 +23,16 @@ jobs: - job: Linux pool: - vmImage: 'ubuntu-22.04' + vmImage: 'ubuntu-24.04' steps: - task: UseDotNet@2 - displayName: 'Use .NET 6.0 Runtime' + displayName: 'Use .NET 8.0 Runtime' inputs: packageType: runtime - version: 6.0.x + version: 8.0.x - task: UseDotNet@2 - displayName: 'Use .NET 8.0 SDK' + displayName: 'Use .NET 10.0 SDK' inputs: packageType: sdk useGlobalJson: true @@ -62,16 +62,16 @@ jobs: variables: SolutionDir: '$(Build.SourcesDirectory)' pool: - vmImage: 'macos-13' + vmImage: 'macos-15' steps: - task: UseDotNet@2 - displayName: 'Use .NET 6.0 Runtime' + displayName: 'Use .NET 8.0 Runtime' inputs: packageType: runtime - version: 6.0.x + version: 8.0.x - task: UseDotNet@2 - displayName: 'Use .NET 8.0 SDK' + displayName: 'Use .NET 10.0 SDK' inputs: packageType: sdk useGlobalJson: true @@ -95,11 +95,11 @@ jobs: inputs: actions: 'build' scheme: '' - sdk: 'macosx14.2' + sdk: 'macosx26.0' configuration: 'Release' xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace' xcodeVersion: 'specifyPath' # Options: 8, 9, default, specifyPath - xcodeDeveloperDir: '/Applications/Xcode_15.2.app/Contents/Developer' + xcodeDeveloperDir: '/Applications/Xcode_26.0.app/Contents/Developer' args: '-derivedDataPath ./' - task: CmdLine@2 @@ -134,18 +134,18 @@ jobs: - job: Windows pool: - vmImage: 'windows-2022' + vmImage: 'windows-2025' variables: SolutionDir: '$(Build.SourcesDirectory)' steps: - task: UseDotNet@2 - displayName: 'Use .NET 6.0 Runtime' + displayName: 'Use .NET 8.0 Runtime' inputs: packageType: runtime - version: 6.0.x + version: 8.0.x - task: UseDotNet@2 - displayName: 'Use .NET 8.0 SDK' + displayName: 'Use .NET 10.0 SDK' inputs: packageType: sdk useGlobalJson: true @@ -160,7 +160,7 @@ jobs: displayName: 'Install Nuke' inputs: script: | - dotnet tool install --global Nuke.GlobalTool --version 6.2.1 + dotnet tool install --global Nuke.GlobalTool --version 9.0.4 - task: CmdLine@2 displayName: 'Run Nuke' diff --git a/build/Base.props b/build/Base.props index 0e667f105b..ab5853fcfa 100644 --- a/build/Base.props +++ b/build/Base.props @@ -1,12 +1,8 @@  - - - - - - - + - + + + diff --git a/build/Moq.props b/build/Moq.props index 357f0c9a5f..fc659f7f5f 100644 --- a/build/Moq.props +++ b/build/Moq.props @@ -1,5 +1,5 @@  - + diff --git a/build/ReactiveUI.props b/build/ReactiveUI.props deleted file mode 100644 index 299a91953c..0000000000 --- a/build/ReactiveUI.props +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/build/TargetFrameworks.props b/build/TargetFrameworks.props index f14a3876ff..96541e7ecf 100644 --- a/build/TargetFrameworks.props +++ b/build/TargetFrameworks.props @@ -1,17 +1,17 @@ - net8.0 + net10.0 $(AvsCurrentTargetFramework)-windows $(AvsCurrentTargetFramework)-macos - $(AvsCurrentTargetFramework)-android34.0 - $(AvsCurrentTargetFramework)-maccatalyst17.0 - $(AvsCurrentTargetFramework)-ios17.0 - $(AvsCurrentTargetFramework)-tvos17.0 + $(AvsCurrentTargetFramework)-android36.0 + $(AvsCurrentTargetFramework)-maccatalyst26.0 + $(AvsCurrentTargetFramework)-ios26.0 + $(AvsCurrentTargetFramework)-tvos26.0 $(AvsCurrentTargetFramework)-browser - net6.0 - net6.0-windows + net8.0 + net8.0-windows @@ -20,7 +20,7 @@ 13.0 13.0 13.1 - 21.0 + 24.0 10.15 diff --git a/build/UnitTests.NetCore.targets b/build/UnitTests.NetCore.targets index 42da8e4ab1..19b2253f4f 100644 --- a/build/UnitTests.NetCore.targets +++ b/build/UnitTests.NetCore.targets @@ -3,7 +3,4 @@ false true - - - - \ No newline at end of file + diff --git a/build/XUnit.props b/build/XUnit.props index b4e9708ecd..4b00869d5b 100644 --- a/build/XUnit.props +++ b/build/XUnit.props @@ -8,7 +8,7 @@ - + $(MSBuildThisFileDirectory)\avalonia.snk diff --git a/dirs.proj b/dirs.proj index 43de2e0b55..084fd30475 100644 --- a/dirs.proj +++ b/dirs.proj @@ -13,9 +13,7 @@ - - diff --git a/docs/build.md b/docs/build.md index 8f0cfafaca..2edf5a8178 100644 --- a/docs/build.md +++ b/docs/build.md @@ -71,6 +71,9 @@ And run tests: Or if you need to create nuget packages as well (it will compile and run tests automatically): `nuke --target Package --configuration Release` +Alternatively, you can run nuke build direclty without installing Nuke global tool: +`dotnet run --project nukebuild/_build.csproj -- --configuration Debug` + # Linux/macOS It's *not* possible to build the *whole* project on Linux/macOS. You can only build the subset targeting .NET Standard and .NET Core (which is, however, sufficient to get UI working on Linux/macOS). If you want to something that involves changing platform-specific APIs you'll need a Windows machine. diff --git a/external/XamlX b/external/XamlX index 83567b8a50..c32d3040e5 160000 --- a/external/XamlX +++ b/external/XamlX @@ -1 +1 @@ -Subproject commit 83567b8a50bbf612a0b1420a3dc6d8e8ebee2399 +Subproject commit c32d3040e536ae9768233ea5a445697632578bd0 diff --git a/global.json b/global.json index f496cffc50..60d847ac0c 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.411", + "version": "10.0.100", "rollForward": "latestFeature" }, "msbuild-sdks": { diff --git a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj index 70bcfc500a..e82c150961 100644 --- a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj +++ b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj @@ -485,6 +485,7 @@ DYLIB_CURRENT_VERSION = 1; EXECUTABLE_PREFIX = lib; HEADER_SEARCH_PATHS = ../../inc; + MACOSX_DEPLOYMENT_TARGET = 10.13; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -496,6 +497,7 @@ DYLIB_CURRENT_VERSION = 1; EXECUTABLE_PREFIX = lib; HEADER_SEARCH_PATHS = ../../inc; + MACOSX_DEPLOYMENT_TARGET = 10.13; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; diff --git a/native/Avalonia.Native/src/OSX/automation.mm b/native/Avalonia.Native/src/OSX/automation.mm index 93a67a64e0..fccb53b7aa 100644 --- a/native/Avalonia.Native/src/OSX/automation.mm +++ b/native/Avalonia.Native/src/OSX/automation.mm @@ -133,6 +133,38 @@ } } +- (NSAccessibilitySubrole)accessibilitySubrole +{ + auto landmarkType = _peer->GetLandmarkType(); + switch (landmarkType) { + case LandmarkBanner: return @"AXLandmarkBanner"; + case LandmarkComplementary: return @"AXLandmarkComplementary"; + case LandmarkContentInfo: return @"AXLandmarkContentInfo"; + case LandmarkRegion: return @"AXLandmarkRegion"; + case LandmarkForm: return @"AXLandmarkForm"; + case LandmarkMain: return @"AXLandmarkMain"; + case LandmarkNavigation: return @"AXLandmarkNavigation"; + case LandmarkSearch: return @"AXLandmarkSearch"; + default: return NSAccessibilityUnknownSubrole; + } +} + +- (NSString *)accessibilityRoleDescription +{ + auto landmarkType = _peer->GetLandmarkType(); + switch (landmarkType) { + case LandmarkBanner: return @"banner"; + case LandmarkComplementary: return @"complementary"; + case LandmarkContentInfo: return @"content"; + case LandmarkRegion: return @"region"; + case LandmarkForm: return @"form"; + case LandmarkMain: return @"main"; + case LandmarkNavigation: return @"navigation"; + case LandmarkSearch: return @"search"; + } + return NSAccessibilityRoleDescription([self accessibilityRole], [self accessibilitySubrole]); +} + - (NSString *)accessibilityIdentifier { return GetNSStringAndRelease(_peer->GetAutomationId()); diff --git a/native/Avalonia.Native/src/OSX/clipboard.mm b/native/Avalonia.Native/src/OSX/clipboard.mm index 45770f8c1e..9786a64b27 100644 --- a/native/Avalonia.Native/src/OSX/clipboard.mm +++ b/native/Avalonia.Native/src/OSX/clipboard.mm @@ -27,12 +27,11 @@ public: if (changeCount != [_pasteboard changeCount]) return COR_E_OBJECTDISPOSED; - - auto types = [_pasteboard types]; - *ret = types == nil ? nullptr : CreateAvnStringArray(types); + + *ret = ConvertPasteboardTypes([_pasteboard types]); return S_OK; } - + virtual HRESULT GetItemCount(int64_t changeCount, int* ret) override { START_COM_ARP_CALL; @@ -57,13 +56,36 @@ public: if (changeCount != [_pasteboard changeCount]) return COR_E_OBJECTDISPOSED; - + auto item = [[_pasteboard pasteboardItems] objectAtIndex:index]; - auto types = [item types]; - *ret = types == nil ? nullptr : CreateAvnStringArray(types); + + *ret = ConvertPasteboardTypes([item types]); return S_OK; } - + + static IAvnStringArray* ConvertPasteboardTypes(NSArray *types) + { + if (types != nil) + { + NSMutableArray *mutableTypes = [types mutableCopy]; + + // Add png if format list doesn't have PNG, + // but has any other image type that can be converter into PNG + if (![mutableTypes containsObject:NSPasteboardTypePNG]) + { + if ([mutableTypes containsObject:NSPasteboardTypeTIFF] + || [mutableTypes containsObject:@"public.jpeg"]) + { + [mutableTypes addObject: NSPasteboardTypePNG]; + } + } + + return CreateAvnStringArray(mutableTypes); + } + + return nil; + } + virtual HRESULT GetItemValueAsString(int index, int64_t changeCount, const char* format, IAvnString** ret) override { START_COM_ARP_CALL; @@ -91,8 +113,45 @@ public: return COR_E_OBJECTDISPOSED; auto item = [[_pasteboard pasteboardItems] objectAtIndex:index]; - auto value = [item dataForType:[NSString stringWithUTF8String:format]]; + auto formatStr = [NSString stringWithUTF8String:format]; + auto value = [item dataForType: formatStr]; + + // If PNG wasn't found, try to convert TIFF or JPEG to PNG + if (value == nil && [formatStr isEqualToString: NSPasteboardTypePNG]) + { + NSData *imageData = nil; + + // Try TIFF first + imageData = [item dataForType:NSPasteboardTypeTIFF]; + + // If no TIFF, try JPEG + if (imageData == nil) { + imageData = [item dataForType:@"public.jpeg"]; + } + + if (imageData != nil) + { + auto image = [[NSImage alloc] initWithData:imageData]; + + NSBitmapImageRep *bitmapRep = nil; + for (NSImageRep *rep in image.representations) { + if ([rep isKindOfClass:[NSBitmapImageRep class]]) { + bitmapRep = (NSBitmapImageRep *)rep; + break; + } + } + + if (!bitmapRep) { + [image lockFocus]; + bitmapRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect(0, 0, image.size.width, image.size.height)]; + [image unlockFocus]; + } + + value = [bitmapRep representationUsingType:NSBitmapImageFileTypePNG properties:@{}]; + } + } + *ret = value == nil || [value length] == 0 ? nullptr : CreateByteArray((void*)[value bytes], (int)[value length]); diff --git a/nukebuild/ApiDiffHelper.cs b/nukebuild/ApiDiffHelper.cs index 1d1f1b1b32..4a51630557 100644 --- a/nukebuild/ApiDiffHelper.cs +++ b/nukebuild/ApiDiffHelper.cs @@ -326,25 +326,11 @@ public static class ApiDiffHelper var frameworkDiffs = new List(); - // Handle frameworks that exist only in the current package. - foreach (var framework in currentFolderNames.Keys.Except(baselineFolderNames.Keys)) - { - var folderName = currentFolderNames[framework]; - Directory.CreateDirectory(baselineFolderPath / folderName); - baselineFolderNames.Add(framework, folderName); - } - - // Handle frameworks that exist only for the baseline package. - foreach (var framework in baselineFolderNames.Keys.Except(currentFolderNames.Keys)) - { - var folderName = baselineFolderNames[framework]; - Directory.CreateDirectory(currentFolderPath / folderName); - currentFolderNames.Add(framework, folderName); - } - foreach (var (framework, currentFolderName) in currentFolderNames) { - var baselineFolderName = baselineFolderNames[framework]; + // Ignore new frameworks that didn't exist in the baseline package. Empty folders make the ApiDiff tool crash. + if (!baselineFolderNames.TryGetValue(framework, out var baselineFolderName)) + continue; frameworkDiffs.Add(new FrameworkDiffInfo( framework, diff --git a/nukebuild/Build.cs b/nukebuild/Build.cs index a63fb1664b..d3c2cb1d01 100644 --- a/nukebuild/Build.cs +++ b/nukebuild/Build.cs @@ -240,11 +240,11 @@ partial class Build : NukeBuild var tfm = fw; if (tfm == "$(AvsCurrentTargetFramework)") { - tfm = "net8.0"; + tfm = "net10.0"; } if (tfm == "$(AvsLegacyTargetFrameworks)") { - tfm = "net6.0"; + tfm = "net8.0"; } if (tfm.StartsWith("net4") @@ -296,7 +296,6 @@ partial class Build : NukeBuild RunCoreTest("Avalonia.Markup.UnitTests"); RunCoreTest("Avalonia.Markup.Xaml.UnitTests"); RunCoreTest("Avalonia.Skia.UnitTests"); - RunCoreTest("Avalonia.ReactiveUI.UnitTests"); RunCoreTest("Avalonia.Headless.NUnit.PerAssembly.UnitTests"); RunCoreTest("Avalonia.Headless.NUnit.PerTest.UnitTests"); RunCoreTest("Avalonia.Headless.XUnit.PerAssembly.UnitTests"); @@ -309,8 +308,6 @@ partial class Build : NukeBuild .Executes(() => { RunCoreTest("Avalonia.Skia.RenderTests"); - if (Parameters.IsRunningOnWindows) - RunCoreTest("Avalonia.Direct2D1.RenderTests"); }); Target RunToolsTests => _ => _ @@ -416,13 +413,13 @@ partial class Build : NukeBuild ApiDiffHelper.MergePackageMarkdownDiffFiles(outputFolderPath, baselineDisplay, currentDisplay); }); - + Target RunTests => _ => _ .DependsOn(RunCoreLibsTests) .DependsOn(RunRenderTests) .DependsOn(RunToolsTests) - .DependsOn(RunHtmlPreviewerTests) - .DependsOn(RunLeakTests); + .DependsOn(RunHtmlPreviewerTests); + //.DependsOn(RunLeakTests); // dotMemory Unit doesn't support modern .NET versions, see https://youtrack.jetbrains.com/issue/DMU-300/ Target Package => _ => _ .DependsOn(RunTests) diff --git a/nukebuild/_build.csproj b/nukebuild/_build.csproj index 2ea83ead71..5890e65259 100644 --- a/nukebuild/_build.csproj +++ b/nukebuild/_build.csproj @@ -21,8 +21,8 @@ - - + + diff --git a/packages/Avalonia/Avalonia.csproj b/packages/Avalonia/Avalonia.csproj index 8fd3fa84c3..1cd1245d3f 100644 --- a/packages/Avalonia/Avalonia.csproj +++ b/packages/Avalonia/Avalonia.csproj @@ -1,11 +1,11 @@  - $(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0 + $(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks) Avalonia - + @@ -27,13 +27,13 @@ - <_PackageFiles Include="$(DesignerHostAppPath)/Avalonia.Designer.HostApp/bin/$(Configuration)/netstandard2.0/Avalonia.Designer.HostApp.dll"> - tools/netstandard2.0/designer + <_PackageFiles Include="$(DesignerHostAppPath)/Avalonia.Designer.HostApp/bin/$(Configuration)/$(AvsCurrentTargetFramework)/Avalonia.Designer.HostApp.dll"> + tools/$(AvsCurrentTargetFramework)/designer false None - <_PackageFiles Include="$(DesignerHostAppPath)/Avalonia.Designer.HostApp/bin/$(Configuration)/net461/Avalonia.Designer.HostApp.exe"> - tools/net461/designer + <_PackageFiles Include="$(DesignerHostAppPath)/Avalonia.Designer.HostApp/bin/$(Configuration)/$(AvsLegacyTargetFrameworks)/Avalonia.Designer.HostApp.dll"> + tools/$(AvsLegacyTargetFrameworks)/designer false None diff --git a/packages/Avalonia/Avalonia.props b/packages/Avalonia/Avalonia.props index 50071bb01a..78656a1726 100644 --- a/packages/Avalonia/Avalonia.props +++ b/packages/Avalonia/Avalonia.props @@ -1,7 +1,6 @@ - $(MSBuildThisFileDirectory)\..\tools\netstandard2.0\designer\Avalonia.Designer.HostApp.dll - $(MSBuildThisFileDirectory)\..\tools\net461\designer\Avalonia.Designer.HostApp.exe + $(MSBuildThisFileDirectory)\..\tools\$(AvsCurrentTargetFramework)\designer\Avalonia.Designer.HostApp.dll $(MSBuildThisFileDirectory)\..\tools\netstandard2.0\Avalonia.Build.Tasks.dll $(UsedAvaloniaProducts);AvaloniaUI true diff --git a/packages/Avalonia/AvaloniaPrivateApis.targets b/packages/Avalonia/AvaloniaPrivateApis.targets index 5f69187d92..47219535cc 100644 --- a/packages/Avalonia/AvaloniaPrivateApis.targets +++ b/packages/Avalonia/AvaloniaPrivateApis.targets @@ -13,7 +13,7 @@ - net6.0 + net8.0 netstandard2.0 diff --git a/packages/Avalonia/AvaloniaSingleProject.targets b/packages/Avalonia/AvaloniaSingleProject.targets index a776f12a7d..25125b26e4 100644 --- a/packages/Avalonia/AvaloniaSingleProject.targets +++ b/packages/Avalonia/AvaloniaSingleProject.targets @@ -98,7 +98,7 @@ 13.0 10.15 13.1 - 21.0 + 24.0 6.5 diff --git a/samples/ControlCatalog.Android/ControlCatalog.Android.csproj b/samples/ControlCatalog.Android/ControlCatalog.Android.csproj index 958725eed5..f60ba69395 100644 --- a/samples/ControlCatalog.Android/ControlCatalog.Android.csproj +++ b/samples/ControlCatalog.Android/ControlCatalog.Android.csproj @@ -26,7 +26,7 @@ - + diff --git a/samples/ControlCatalog.Browser.Blazor/App.razor b/samples/ControlCatalog.Browser.Blazor/App.razor deleted file mode 100644 index b941644e29..0000000000 --- a/samples/ControlCatalog.Browser.Blazor/App.razor +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - -

Sorry, there's nothing at this address.

-
-
-
diff --git a/samples/ControlCatalog.Browser.Blazor/App.razor.cs b/samples/ControlCatalog.Browser.Blazor/App.razor.cs deleted file mode 100644 index c331625664..0000000000 --- a/samples/ControlCatalog.Browser.Blazor/App.razor.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Threading.Tasks; -using Avalonia; -using Avalonia.Browser.Blazor; - -namespace ControlCatalog.Browser.Blazor; - -public partial class App -{ -} diff --git a/samples/ControlCatalog.Browser.Blazor/ControlCatalog.Browser.Blazor.csproj b/samples/ControlCatalog.Browser.Blazor/ControlCatalog.Browser.Blazor.csproj deleted file mode 100644 index 2950028e68..0000000000 --- a/samples/ControlCatalog.Browser.Blazor/ControlCatalog.Browser.Blazor.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - $(AvsCurrentBrowserTargetFramework) - browser-wasm - enable - 16777216 - false - false - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/ControlCatalog.Browser.Blazor/Pages/Index.razor b/samples/ControlCatalog.Browser.Blazor/Pages/Index.razor deleted file mode 100644 index 7480e4c5e9..0000000000 --- a/samples/ControlCatalog.Browser.Blazor/Pages/Index.razor +++ /dev/null @@ -1,5 +0,0 @@ -@page "/" - -@using Avalonia.Browser.Blazor - - diff --git a/samples/ControlCatalog.Browser.Blazor/Program.cs b/samples/ControlCatalog.Browser.Blazor/Program.cs deleted file mode 100644 index e68e9b14d9..0000000000 --- a/samples/ControlCatalog.Browser.Blazor/Program.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Net.Http; -using System.Threading.Tasks; -using Avalonia; -using Avalonia.Browser.Blazor; -using Microsoft.AspNetCore.Components.WebAssembly.Hosting; -using Microsoft.Extensions.DependencyInjection; -using ControlCatalog.Browser.Blazor; - -public class Program -{ - public static async Task Main(string[] args) - { - var host = CreateHostBuilder(args).Build(); - await StartAvaloniaApp(); - await host.RunAsync(); - } - - public static async Task StartAvaloniaApp() - { - await AppBuilder.Configure() - .StartBlazorAppAsync(); - } - - public static WebAssemblyHostBuilder CreateHostBuilder(string[] args) - { - var builder = WebAssemblyHostBuilder.CreateDefault(args); - - builder.RootComponents.Add("#app"); - - builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); - - return builder; - } -} - - - - diff --git a/samples/ControlCatalog.Browser.Blazor/Properties/launchSettings.json b/samples/ControlCatalog.Browser.Blazor/Properties/launchSettings.json deleted file mode 100644 index ad2b1e30f6..0000000000 --- a/samples/ControlCatalog.Browser.Blazor/Properties/launchSettings.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:13961", - "sslPort": 44319 - } - }, - "profiles": { - "ControlCatalog.Web": { - "commandName": "Project", - "dotnetRunMessages": "true", - "launchBrowser": true, - "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", - "applicationUrl": "https://localhost:5001;http://localhost:5000", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/samples/ControlCatalog.Browser.Blazor/Shared/MainLayout.razor b/samples/ControlCatalog.Browser.Blazor/Shared/MainLayout.razor deleted file mode 100644 index 63fb17716c..0000000000 --- a/samples/ControlCatalog.Browser.Blazor/Shared/MainLayout.razor +++ /dev/null @@ -1,7 +0,0 @@ -@inherits LayoutComponentBase - -
-
- @Body -
-
diff --git a/samples/ControlCatalog.Browser.Blazor/_Imports.razor b/samples/ControlCatalog.Browser.Blazor/_Imports.razor deleted file mode 100644 index dc4f778352..0000000000 --- a/samples/ControlCatalog.Browser.Blazor/_Imports.razor +++ /dev/null @@ -1,10 +0,0 @@ -@using System.Net.Http -@using System.Net.Http.Json -@using Microsoft.AspNetCore.Components.Forms -@using Microsoft.AspNetCore.Components.Routing -@using Microsoft.AspNetCore.Components.Web -@using Microsoft.AspNetCore.Components.Web.Virtualization -@using Microsoft.AspNetCore.Components.WebAssembly.Http -@using Microsoft.JSInterop -@using ControlCatalog.Browser.Blazor.Shared -@using SkiaSharp diff --git a/samples/ControlCatalog.Browser.Blazor/wwwroot/css/app.css b/samples/ControlCatalog.Browser.Blazor/wwwroot/css/app.css deleted file mode 100644 index 49ca14e162..0000000000 --- a/samples/ControlCatalog.Browser.Blazor/wwwroot/css/app.css +++ /dev/null @@ -1,56 +0,0 @@ -html, body { - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; - margin: 0; - height: 100vh; - overflow: hidden; - touch-action: none; -} - -a, .btn-link { - color: #0366d6; -} - -.btn-primary { - color: #fff; - background-color: #1b6ec2; - border-color: #1861ac; -} - -.content { - padding-top: 1.1rem; -} - -.valid.modified:not([type=checkbox]) { - outline: 1px solid #26b050; -} - -.invalid { - outline: 1px solid red; -} - -.validation-message { - color: red; -} - -#blazor-error-ui { - background: lightyellow; - bottom: 0; - box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); - display: none; - left: 0; - padding: 0.6rem 1.25rem 0.7rem 1.25rem; - position: fixed; - width: 100%; - z-index: 1000; -} - -#blazor-error-ui .dismiss { - cursor: pointer; - position: absolute; - right: 0.75rem; - top: 0.5rem; -} - -#app, .page { - height: 100%; -} diff --git a/samples/ControlCatalog.Browser.Blazor/wwwroot/favicon.ico b/samples/ControlCatalog.Browser.Blazor/wwwroot/favicon.ico deleted file mode 100644 index da8d49ff9b..0000000000 Binary files a/samples/ControlCatalog.Browser.Blazor/wwwroot/favicon.ico and /dev/null differ diff --git a/samples/ControlCatalog.Browser.Blazor/wwwroot/index.html b/samples/ControlCatalog.Browser.Blazor/wwwroot/index.html deleted file mode 100644 index cad9123836..0000000000 --- a/samples/ControlCatalog.Browser.Blazor/wwwroot/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - Avalonia Sample - - - - - -
Powered by Avalonia
- -
- An unhandled error has occurred. - Reload - 🗙 -
- - - diff --git a/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj b/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj index 2c47effa38..9398987837 100644 --- a/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj +++ b/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj @@ -1,22 +1,41 @@  - Exe - net461 - x64 + WinExe + $(AvsCurrentTargetFramework) + true true - ../ControlCatalog.NetCore/app.manifest - - + + + + + + + + PreserveNewest + - + + + + + + + + + + + en + app.manifest + + - + diff --git a/samples/ControlCatalog.NetCore/NativeControls/Gtk/EmbedSample.Gtk.cs b/samples/ControlCatalog.Desktop/NativeControls/Gtk/EmbedSample.Gtk.cs similarity index 96% rename from samples/ControlCatalog.NetCore/NativeControls/Gtk/EmbedSample.Gtk.cs rename to samples/ControlCatalog.Desktop/NativeControls/Gtk/EmbedSample.Gtk.cs index 81a5ba536f..c42ac73b88 100644 --- a/samples/ControlCatalog.NetCore/NativeControls/Gtk/EmbedSample.Gtk.cs +++ b/samples/ControlCatalog.Desktop/NativeControls/Gtk/EmbedSample.Gtk.cs @@ -5,7 +5,7 @@ using Avalonia.Controls.Platform; using System; using ControlCatalog.Pages; -namespace ControlCatalog.NetCore; +namespace ControlCatalog.Desktop; public class EmbedSampleGtk : INativeDemoControl { diff --git a/samples/ControlCatalog.NetCore/NativeControls/Gtk/GtkHelper.cs b/samples/ControlCatalog.Desktop/NativeControls/Gtk/GtkHelper.cs similarity index 97% rename from samples/ControlCatalog.NetCore/NativeControls/Gtk/GtkHelper.cs rename to samples/ControlCatalog.Desktop/NativeControls/Gtk/GtkHelper.cs index 9d698716ee..78d7a45154 100644 --- a/samples/ControlCatalog.NetCore/NativeControls/Gtk/GtkHelper.cs +++ b/samples/ControlCatalog.Desktop/NativeControls/Gtk/GtkHelper.cs @@ -7,7 +7,7 @@ using Avalonia.X11.NativeDialogs; using static Avalonia.X11.NativeDialogs.Gtk; using static Avalonia.X11.Interop.Glib; -namespace ControlCatalog.NetCore; +namespace ControlCatalog.Desktop; internal class GtkHelper { diff --git a/samples/ControlCatalog.NetCore/NativeControls/Gtk/nodes-license.md b/samples/ControlCatalog.Desktop/NativeControls/Gtk/nodes-license.md similarity index 100% rename from samples/ControlCatalog.NetCore/NativeControls/Gtk/nodes-license.md rename to samples/ControlCatalog.Desktop/NativeControls/Gtk/nodes-license.md diff --git a/samples/ControlCatalog.NetCore/NativeControls/Gtk/nodes.mp4 b/samples/ControlCatalog.Desktop/NativeControls/Gtk/nodes.mp4 similarity index 100% rename from samples/ControlCatalog.NetCore/NativeControls/Gtk/nodes.mp4 rename to samples/ControlCatalog.Desktop/NativeControls/Gtk/nodes.mp4 diff --git a/samples/ControlCatalog.NetCore/NativeControls/Mac/EmbedSample.Mac.cs b/samples/ControlCatalog.Desktop/NativeControls/Mac/EmbedSample.Mac.cs similarity index 95% rename from samples/ControlCatalog.NetCore/NativeControls/Mac/EmbedSample.Mac.cs rename to samples/ControlCatalog.Desktop/NativeControls/Mac/EmbedSample.Mac.cs index 7967c9c073..b761ce0972 100644 --- a/samples/ControlCatalog.NetCore/NativeControls/Mac/EmbedSample.Mac.cs +++ b/samples/ControlCatalog.Desktop/NativeControls/Mac/EmbedSample.Mac.cs @@ -8,7 +8,7 @@ using ControlCatalog.Pages; using MonoMac.Foundation; using MonoMac.WebKit; -namespace ControlCatalog.NetCore; +namespace ControlCatalog.Desktop; public class EmbedSampleMac : INativeDemoControl { diff --git a/samples/ControlCatalog.NetCore/NativeControls/Mac/MacHelper.cs b/samples/ControlCatalog.Desktop/NativeControls/Mac/MacHelper.cs similarity index 95% rename from samples/ControlCatalog.NetCore/NativeControls/Mac/MacHelper.cs rename to samples/ControlCatalog.Desktop/NativeControls/Mac/MacHelper.cs index 5b3bc9abf1..154878e4ff 100644 --- a/samples/ControlCatalog.NetCore/NativeControls/Mac/MacHelper.cs +++ b/samples/ControlCatalog.Desktop/NativeControls/Mac/MacHelper.cs @@ -3,7 +3,7 @@ using System; using Avalonia.Controls.Platform; using MonoMac.AppKit; -namespace ControlCatalog.NetCore; +namespace ControlCatalog.Desktop; internal class MacHelper { diff --git a/samples/ControlCatalog.NetCore/NativeControls/Win/EmbedSample.Win.cs b/samples/ControlCatalog.Desktop/NativeControls/Win/EmbedSample.Win.cs similarity index 98% rename from samples/ControlCatalog.NetCore/NativeControls/Win/EmbedSample.Win.cs rename to samples/ControlCatalog.Desktop/NativeControls/Win/EmbedSample.Win.cs index 77982db0ca..c529c093f6 100644 --- a/samples/ControlCatalog.NetCore/NativeControls/Win/EmbedSample.Win.cs +++ b/samples/ControlCatalog.Desktop/NativeControls/Win/EmbedSample.Win.cs @@ -6,7 +6,7 @@ using Avalonia.Platform; using ControlCatalog.Pages; -namespace ControlCatalog.NetCore; +namespace ControlCatalog.Desktop; public class EmbedSampleWin : INativeDemoControl { diff --git a/samples/ControlCatalog.NetCore/NativeControls/Win/WinApi.cs b/samples/ControlCatalog.Desktop/NativeControls/Win/WinApi.cs similarity index 98% rename from samples/ControlCatalog.NetCore/NativeControls/Win/WinApi.cs rename to samples/ControlCatalog.Desktop/NativeControls/Win/WinApi.cs index bd0c1bf98e..1bb3879ac3 100644 --- a/samples/ControlCatalog.NetCore/NativeControls/Win/WinApi.cs +++ b/samples/ControlCatalog.Desktop/NativeControls/Win/WinApi.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; -namespace ControlCatalog.NetCore; +namespace ControlCatalog.Desktop; internal unsafe class WinApi { diff --git a/samples/ControlCatalog.Desktop/Program.cs b/samples/ControlCatalog.Desktop/Program.cs index 533ee8308a..707ead5f1d 100644 --- a/samples/ControlCatalog.Desktop/Program.cs +++ b/samples/ControlCatalog.Desktop/Program.cs @@ -1,38 +1,180 @@ using System; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Avalonia; -using Avalonia.Platform; -using ControlCatalog.NetCore; +using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Fonts.Inter; +using Avalonia.Headless; +using Avalonia.LinuxFramebuffer.Output; +using Avalonia.LogicalTree; +using Avalonia.Rendering.Composition; +using Avalonia.Threading; +using Avalonia.Vulkan; using ControlCatalog.Pages; -namespace ControlCatalog +namespace ControlCatalog.Desktop { - internal class Program + static class Program { + private static bool s_useFramebuffer; + [STAThread] - public static int Main(string[] args) - => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); + static int Main(string[] args) + { + if (args.Contains("--fbdev")) + { + s_useFramebuffer = true; + } + + if (args.Contains("--wait-for-attach")) + { + Console.WriteLine("Attach debugger and use 'Set next statement'"); + while (true) + { + Thread.Sleep(100); + if (Debugger.IsAttached) + break; + } + } + + var builder = BuildAvaloniaApp(); + + double GetScaling() + { + var idx = Array.IndexOf(args, "--scaling"); + if (idx != 0 && args.Length > idx + 1 && + double.TryParse(args[idx + 1], NumberStyles.Any, CultureInfo.InvariantCulture, out var scaling)) + return scaling; + return 1; + } + if (s_useFramebuffer) + { + SilenceConsole(); + return builder.StartLinuxFbDev(args, new FbDevOutputOptions() + { + Scaling = GetScaling() + }); + } + else if (args.Contains("--vnc")) + { + return builder.StartWithHeadlessVncPlatform(null, 5901, args, ShutdownMode.OnMainWindowClose); + } + else if (args.Contains("--full-headless")) + { + return builder + .UseHeadless(new AvaloniaHeadlessPlatformOptions + { + UseHeadlessDrawing = true + }) + .AfterSetup(_ => + { + DispatcherTimer.RunOnce(async () => + { + var window = ((IClassicDesktopStyleApplicationLifetime)Application.Current.ApplicationLifetime) + .MainWindow; + var tc = window.GetLogicalDescendants().OfType().First(); + foreach (var page in tc.Items.Cast().ToList()) + { + if (page.Header.ToString() == "DatePicker" || page.Header.ToString() == "TreeView") + continue; + Console.WriteLine("Selecting " + page.Header); + tc.SelectedItem = page; + await Task.Delay(50); + } + Console.WriteLine("Selecting the first page"); + tc.SelectedItem = tc.Items.OfType().First(); + await Task.Delay(500); + Console.WriteLine("Clicked through all pages, triggering GC"); + for (var c = 0; c < 3; c++) + { + GC.Collect(2, GCCollectionMode.Forced); + await Task.Delay(50); + } + + void FormatMem(string metric, long bytes) + { + Console.WriteLine(metric + ": " + bytes / 1024 / 1024 + "MB"); + } + + FormatMem("GC allocated bytes", GC.GetTotalMemory(true)); + FormatMem("WorkingSet64", Process.GetCurrentProcess().WorkingSet64); + }, TimeSpan.FromSeconds(1)); + }) + .StartWithClassicDesktopLifetime(args); + } + else if (args.Contains("--drm")) + { + SilenceConsole(); + return builder.StartLinuxDrm(args, scaling: GetScaling()); + } + else if (args.Contains("--dxgi")) + { + builder.With(new Win32PlatformOptions() + { + CompositionMode = new [] { Win32CompositionMode.LowLatencyDxgiSwapChain } + }); + return builder.StartWithClassicDesktopLifetime(args); + } + else + return builder.StartWithClassicDesktopLifetime(args); + } /// /// This method is needed for IDE previewer infrastructure /// public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure() - .LogToTrace() + .UsePlatformDetect() + .With(new X11PlatformOptions + { + EnableMultiTouch = true, + UseDBusMenu = true, + EnableIme = true, + }) + + .With(new VulkanOptions + { + VulkanInstanceCreationOptions = new () + { + UseDebug = true + } + }) + .With(new CompositionOptions() + { + UseRegionDirtyRectClipping = true + }) + .UseSkia() + .WithInterFont() .AfterSetup(builder => { - builder.Instance!.AttachDevTools(new Avalonia.Diagnostics.DevToolsOptions() + if (!s_useFramebuffer) { - StartupScreenIndex = 1, - }); + builder.Instance!.AttachDevTools(new Avalonia.Diagnostics.DevToolsOptions() + { + StartupScreenIndex = 1, + }); + } - EmbedSample.Implementation = new EmbedSampleWin(); + EmbedSample.Implementation = OperatingSystem.IsWindows() ? (INativeDemoControl)new EmbedSampleWin() + : OperatingSystem.IsMacOS() ? new EmbedSampleMac() + : OperatingSystem.IsLinux() ? new EmbedSampleGtk() + : null; }) - .UseWin32() - .UseSkia(); + .LogToTrace(); - private static void ConfigureAssetAssembly(AppBuilder builder) + static void SilenceConsole() { - AssetLoader.SetDefaultAssembly(typeof(App).Assembly); + new Thread(() => + { + Console.CursorVisible = false; + while (true) + Console.ReadKey(true); + }) + { IsBackground = true }.Start(); } } } diff --git a/samples/ControlCatalog.NetCore/Properties/launchSettings.json b/samples/ControlCatalog.Desktop/Properties/launchSettings.json similarity index 87% rename from samples/ControlCatalog.NetCore/Properties/launchSettings.json rename to samples/ControlCatalog.Desktop/Properties/launchSettings.json index 11feb94bb3..d57a2680e4 100644 --- a/samples/ControlCatalog.NetCore/Properties/launchSettings.json +++ b/samples/ControlCatalog.Desktop/Properties/launchSettings.json @@ -1,6 +1,6 @@ { "profiles": { - "ControlCatalog.NetCore": { + "ControlCatalog.Desktop": { "commandName": "Project" }, "Dxgi": { diff --git a/samples/ControlCatalog.NetCore/app.manifest b/samples/ControlCatalog.Desktop/app.manifest similarity index 100% rename from samples/ControlCatalog.NetCore/app.manifest rename to samples/ControlCatalog.Desktop/app.manifest diff --git a/samples/ControlCatalog.MacCatalyst/ControlCatalog.MacCatalyst.csproj b/samples/ControlCatalog.MacCatalyst/ControlCatalog.MacCatalyst.csproj index 0a1329e2e3..954ed20d99 100644 --- a/samples/ControlCatalog.MacCatalyst/ControlCatalog.MacCatalyst.csproj +++ b/samples/ControlCatalog.MacCatalyst/ControlCatalog.MacCatalyst.csproj @@ -5,7 +5,7 @@ manual $(AvsCurrentMacCatalystTargetFramework) - 14.0 + 15.0 true diff --git a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj deleted file mode 100644 index 9398987837..0000000000 --- a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj +++ /dev/null @@ -1,41 +0,0 @@ - - - - WinExe - $(AvsCurrentTargetFramework) - true - true - - - - - - - - - - - PreserveNewest - - - - - - - - - - - - - - - - - en - app.manifest - - - - - diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs deleted file mode 100644 index 036dd13f7a..0000000000 --- a/samples/ControlCatalog.NetCore/Program.cs +++ /dev/null @@ -1,180 +0,0 @@ -using System; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Controls.ApplicationLifetimes; -using Avalonia.Fonts.Inter; -using Avalonia.Headless; -using Avalonia.LinuxFramebuffer.Output; -using Avalonia.LogicalTree; -using Avalonia.Rendering.Composition; -using Avalonia.Threading; -using Avalonia.Vulkan; -using ControlCatalog.Pages; - -namespace ControlCatalog.NetCore -{ - static class Program - { - private static bool s_useFramebuffer; - - [STAThread] - static int Main(string[] args) - { - if (args.Contains("--fbdev")) - { - s_useFramebuffer = true; - } - - if (args.Contains("--wait-for-attach")) - { - Console.WriteLine("Attach debugger and use 'Set next statement'"); - while (true) - { - Thread.Sleep(100); - if (Debugger.IsAttached) - break; - } - } - - var builder = BuildAvaloniaApp(); - - double GetScaling() - { - var idx = Array.IndexOf(args, "--scaling"); - if (idx != 0 && args.Length > idx + 1 && - double.TryParse(args[idx + 1], NumberStyles.Any, CultureInfo.InvariantCulture, out var scaling)) - return scaling; - return 1; - } - if (s_useFramebuffer) - { - SilenceConsole(); - return builder.StartLinuxFbDev(args, new FbDevOutputOptions() - { - Scaling = GetScaling() - }); - } - else if (args.Contains("--vnc")) - { - return builder.StartWithHeadlessVncPlatform(null, 5901, args, ShutdownMode.OnMainWindowClose); - } - else if (args.Contains("--full-headless")) - { - return builder - .UseHeadless(new AvaloniaHeadlessPlatformOptions - { - UseHeadlessDrawing = true - }) - .AfterSetup(_ => - { - DispatcherTimer.RunOnce(async () => - { - var window = ((IClassicDesktopStyleApplicationLifetime)Application.Current.ApplicationLifetime) - .MainWindow; - var tc = window.GetLogicalDescendants().OfType().First(); - foreach (var page in tc.Items.Cast().ToList()) - { - if (page.Header.ToString() == "DatePicker" || page.Header.ToString() == "TreeView") - continue; - Console.WriteLine("Selecting " + page.Header); - tc.SelectedItem = page; - await Task.Delay(50); - } - Console.WriteLine("Selecting the first page"); - tc.SelectedItem = tc.Items.OfType().First(); - await Task.Delay(500); - Console.WriteLine("Clicked through all pages, triggering GC"); - for (var c = 0; c < 3; c++) - { - GC.Collect(2, GCCollectionMode.Forced); - await Task.Delay(50); - } - - void FormatMem(string metric, long bytes) - { - Console.WriteLine(metric + ": " + bytes / 1024 / 1024 + "MB"); - } - - FormatMem("GC allocated bytes", GC.GetTotalMemory(true)); - FormatMem("WorkingSet64", Process.GetCurrentProcess().WorkingSet64); - }, TimeSpan.FromSeconds(1)); - }) - .StartWithClassicDesktopLifetime(args); - } - else if (args.Contains("--drm")) - { - SilenceConsole(); - return builder.StartLinuxDrm(args, scaling: GetScaling()); - } - else if (args.Contains("--dxgi")) - { - builder.With(new Win32PlatformOptions() - { - CompositionMode = new [] { Win32CompositionMode.LowLatencyDxgiSwapChain } - }); - return builder.StartWithClassicDesktopLifetime(args); - } - else - return builder.StartWithClassicDesktopLifetime(args); - } - - /// - /// This method is needed for IDE previewer infrastructure - /// - public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure() - .UsePlatformDetect() - .With(new X11PlatformOptions - { - EnableMultiTouch = true, - UseDBusMenu = true, - EnableIme = true, - }) - - .With(new VulkanOptions - { - VulkanInstanceCreationOptions = new () - { - UseDebug = true - } - }) - .With(new CompositionOptions() - { - UseRegionDirtyRectClipping = true - }) - .UseSkia() - .WithInterFont() - .AfterSetup(builder => - { - if (!s_useFramebuffer) - { - builder.Instance!.AttachDevTools(new Avalonia.Diagnostics.DevToolsOptions() - { - StartupScreenIndex = 1, - }); - } - - EmbedSample.Implementation = OperatingSystem.IsWindows() ? (INativeDemoControl)new EmbedSampleWin() - : OperatingSystem.IsMacOS() ? new EmbedSampleMac() - : OperatingSystem.IsLinux() ? new EmbedSampleGtk() - : null; - }) - .LogToTrace(); - - static void SilenceConsole() - { - new Thread(() => - { - Console.CursorVisible = false; - while (true) - Console.ReadKey(true); - }) - { IsBackground = true }.Start(); - } - } -} diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj index 7bbff55907..81caa6b2e4 100644 --- a/samples/ControlCatalog/ControlCatalog.csproj +++ b/samples/ControlCatalog/ControlCatalog.csproj @@ -1,6 +1,6 @@  - netstandard2.0;$(AvsCurrentTargetFramework) + $(AvsCurrentTargetFramework) true enable true diff --git a/samples/ControlCatalog/Pages/ClipboardPage.xaml b/samples/ControlCatalog/Pages/ClipboardPage.xaml index 2c22348f6f..80b3f4d1ed 100644 --- a/samples/ControlCatalog/Pages/ClipboardPage.xaml +++ b/samples/ControlCatalog/Pages/ClipboardPage.xaml @@ -6,6 +6,8 @@ - - - - - - - diff --git a/samples/ReactiveUIDemo/MainWindow.axaml.cs b/samples/ReactiveUIDemo/MainWindow.axaml.cs deleted file mode 100644 index 5bf2d476fd..0000000000 --- a/samples/ReactiveUIDemo/MainWindow.axaml.cs +++ /dev/null @@ -1,22 +0,0 @@ -using ReactiveUIDemo.ViewModels; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Markup.Xaml; - -namespace ReactiveUIDemo -{ - public class MainWindow : Window - { - public MainWindow() - { - this.InitializeComponent(); - this.DataContext = new MainWindowViewModel(); - this.AttachDevTools(); - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - } -} diff --git a/samples/ReactiveUIDemo/ReactiveUIDemo.csproj b/samples/ReactiveUIDemo/ReactiveUIDemo.csproj deleted file mode 100644 index 00f470fd79..0000000000 --- a/samples/ReactiveUIDemo/ReactiveUIDemo.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - Exe - $(AvsCurrentTargetFramework) - enable - - - - - - - - - - - - BarView.axaml - - - FooView.axaml - - - - - - - - diff --git a/samples/ReactiveUIDemo/ViewModels/BarViewModel.cs b/samples/ReactiveUIDemo/ViewModels/BarViewModel.cs deleted file mode 100644 index 3448453d81..0000000000 --- a/samples/ReactiveUIDemo/ViewModels/BarViewModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -using ReactiveUI; - -namespace ReactiveUIDemo.ViewModels -{ - internal class BarViewModel : ReactiveObject, IRoutableViewModel - { - public BarViewModel(IScreen screen) => HostScreen = screen; - public string UrlPathSegment => "Bar"; - public IScreen HostScreen { get; } - } -} diff --git a/samples/ReactiveUIDemo/ViewModels/FooViewModel.cs b/samples/ReactiveUIDemo/ViewModels/FooViewModel.cs deleted file mode 100644 index 1a363e18dc..0000000000 --- a/samples/ReactiveUIDemo/ViewModels/FooViewModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -using ReactiveUI; - -namespace ReactiveUIDemo.ViewModels -{ - internal class FooViewModel : ReactiveObject, IRoutableViewModel - { - public FooViewModel(IScreen screen) => HostScreen = screen; - public string UrlPathSegment => "Foo"; - public IScreen HostScreen { get; } - } -} diff --git a/samples/ReactiveUIDemo/ViewModels/MainWindowViewModel.cs b/samples/ReactiveUIDemo/ViewModels/MainWindowViewModel.cs deleted file mode 100644 index 2222137d38..0000000000 --- a/samples/ReactiveUIDemo/ViewModels/MainWindowViewModel.cs +++ /dev/null @@ -1,9 +0,0 @@ -using ReactiveUI; - -namespace ReactiveUIDemo.ViewModels -{ - internal class MainWindowViewModel : ReactiveObject - { - public RoutedViewHostPageViewModel RoutedViewHost { get; } = new(); - } -} diff --git a/samples/ReactiveUIDemo/ViewModels/RoutedViewHostPageViewModel.cs b/samples/ReactiveUIDemo/ViewModels/RoutedViewHostPageViewModel.cs deleted file mode 100644 index 701447cfe8..0000000000 --- a/samples/ReactiveUIDemo/ViewModels/RoutedViewHostPageViewModel.cs +++ /dev/null @@ -1,21 +0,0 @@ -using ReactiveUI; - -namespace ReactiveUIDemo.ViewModels -{ - internal class RoutedViewHostPageViewModel : ReactiveObject, IScreen - { - public RoutedViewHostPageViewModel() - { - Foo = new(this); - Bar = new(this); - Router.Navigate.Execute(Foo); - } - - public RoutingState Router { get; } = new(); - public FooViewModel Foo { get; } - public BarViewModel Bar { get; } - - public void ShowFoo() => Router.Navigate.Execute(Foo); - public void ShowBar() => Router.Navigate.Execute(Bar); - } -} diff --git a/samples/ReactiveUIDemo/Views/BarView.axaml b/samples/ReactiveUIDemo/Views/BarView.axaml deleted file mode 100644 index 2622245997..0000000000 --- a/samples/ReactiveUIDemo/Views/BarView.axaml +++ /dev/null @@ -1,16 +0,0 @@ - - - - Bar! - - - diff --git a/samples/ReactiveUIDemo/Views/BarView.axaml.cs b/samples/ReactiveUIDemo/Views/BarView.axaml.cs deleted file mode 100644 index 2fbea6de91..0000000000 --- a/samples/ReactiveUIDemo/Views/BarView.axaml.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Markup.Xaml; -using ReactiveUI; -using ReactiveUIDemo.ViewModels; - -namespace ReactiveUIDemo.Views -{ - internal partial class BarView : UserControl, IViewFor - { - public BarView() - { - InitializeComponent(); - } - - public BarViewModel? ViewModel { get; set; } - - object? IViewFor.ViewModel - { - get => ViewModel; - set => ViewModel = (BarViewModel?)value; - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - } -} diff --git a/samples/ReactiveUIDemo/Views/FooView.axaml b/samples/ReactiveUIDemo/Views/FooView.axaml deleted file mode 100644 index 8f73250d3b..0000000000 --- a/samples/ReactiveUIDemo/Views/FooView.axaml +++ /dev/null @@ -1,16 +0,0 @@ - - - - Foo! - - - diff --git a/samples/ReactiveUIDemo/Views/FooView.axaml.cs b/samples/ReactiveUIDemo/Views/FooView.axaml.cs deleted file mode 100644 index 313a71044c..0000000000 --- a/samples/ReactiveUIDemo/Views/FooView.axaml.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Markup.Xaml; -using ReactiveUI; -using ReactiveUIDemo.ViewModels; - -namespace ReactiveUIDemo.Views -{ - internal partial class FooView : UserControl, IViewFor - { - public FooView() - { - InitializeComponent(); - } - - public FooViewModel? ViewModel { get; set; } - - object? IViewFor.ViewModel - { - get => ViewModel; - set => ViewModel = (FooViewModel?)value; - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - } -} diff --git a/samples/SampleControls/ControlSamples.csproj b/samples/SampleControls/ControlSamples.csproj index 99ac655584..405175d01c 100644 --- a/samples/SampleControls/ControlSamples.csproj +++ b/samples/SampleControls/ControlSamples.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + $(AvsCurrentTargetFramework) enable diff --git a/samples/UnloadableAssemblyLoadContext/UnloadableAssemblyLoadContextPlug/UnloadableAssemblyLoadContextPlug.csproj b/samples/UnloadableAssemblyLoadContext/UnloadableAssemblyLoadContextPlug/UnloadableAssemblyLoadContextPlug.csproj index 4dd79dee1b..5d43f20cc4 100644 --- a/samples/UnloadableAssemblyLoadContext/UnloadableAssemblyLoadContextPlug/UnloadableAssemblyLoadContextPlug.csproj +++ b/samples/UnloadableAssemblyLoadContext/UnloadableAssemblyLoadContextPlug/UnloadableAssemblyLoadContextPlug.csproj @@ -35,7 +35,6 @@ - diff --git a/samples/XEmbedSample/XEmbedSample.csproj b/samples/XEmbedSample/XEmbedSample.csproj index 01ea7432db..89bbf13273 100644 --- a/samples/XEmbedSample/XEmbedSample.csproj +++ b/samples/XEmbedSample/XEmbedSample.csproj @@ -1,20 +1,27 @@ + + Exe + $(AvsCurrentTargetFramework) + enable + enable + true + Exe - net6.0 + $(AvsCurrentTargetFramework) enable enable true - - - + + + - - - - + + + + diff --git a/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj b/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj index 533aacf382..5cb227f9cb 100644 --- a/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj +++ b/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj @@ -1,7 +1,7 @@  WinExe - net461;$(AvsCurrentWindowsTargetFramework) + $(AvsCurrentWindowsTargetFramework) true true true diff --git a/src/Android/Avalonia.Android/Automation/ToggleNodeInfoProvider.cs b/src/Android/Avalonia.Android/Automation/ToggleNodeInfoProvider.cs index cbd64e3b18..24ce3fa120 100644 --- a/src/Android/Avalonia.Android/Automation/ToggleNodeInfoProvider.cs +++ b/src/Android/Avalonia.Android/Automation/ToggleNodeInfoProvider.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using Android.OS; +using Android.OS; using AndroidX.Core.View.Accessibility; using AndroidX.CustomView.Widget; using Avalonia.Automation.Peers; @@ -9,18 +8,11 @@ namespace Avalonia.Android.Automation { internal class ToggleNodeInfoProvider : NodeInfoProvider { - private static PropertyInfo? s_checkedProperty; - public ToggleNodeInfoProvider(ExploreByTouchHelper owner, AutomationPeer peer, int virtualViewId) : base(owner, peer, virtualViewId) { } - static ToggleNodeInfoProvider() - { - s_checkedProperty = typeof(AccessibilityNodeInfoCompat).GetProperty(nameof(AccessibilityNodeInfoCompat.Checked)); - } - public override bool PerformNodeAction(int action, Bundle? arguments) { IToggleProvider provider = GetProvider(); @@ -40,25 +32,12 @@ namespace Avalonia.Android.Automation nodeInfo.Clickable = true; IToggleProvider provider = GetProvider(); - - s_checkedProperty ??= nodeInfo.GetType().GetProperty(nameof(nodeInfo.Checked)); - if (s_checkedProperty?.PropertyType == typeof(int)) + nodeInfo.Checked = provider.ToggleState switch { - // Needed for Xamarin.AndroidX.Core 1.17+ - s_checkedProperty.SetValue(this, - provider.ToggleState switch - { - ToggleState.On => 1, - ToggleState.Indeterminate => 2, - _ => 0 - }); - } - else if (s_checkedProperty?.PropertyType == typeof(bool)) - { - // Needed for Xamarin.AndroidX.Core < 1.17 - s_checkedProperty.SetValue(this, provider.ToggleState == ToggleState.On); - } - + ToggleState.On => 1, + ToggleState.Indeterminate => 2, + _ => 0 + }; nodeInfo.Checkable = true; } } diff --git a/src/Android/Avalonia.Android/Avalonia.Android.csproj b/src/Android/Avalonia.Android/Avalonia.Android.csproj index 2fb849ee0d..97acf3d012 100644 --- a/src/Android/Avalonia.Android/Avalonia.Android.csproj +++ b/src/Android/Avalonia.Android/Avalonia.Android.csproj @@ -7,8 +7,8 @@ - - + + diff --git a/src/Android/Avalonia.Android/AvaloniaAccessHelper.cs b/src/Android/Avalonia.Android/AvaloniaAccessHelper.cs index 0b5a7e03c4..faacff7554 100644 --- a/src/Android/Avalonia.Android/AvaloniaAccessHelper.cs +++ b/src/Android/Avalonia.Android/AvaloniaAccessHelper.cs @@ -1,7 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using Android.Content.PM; using Android.OS; using AndroidX.Core.View.Accessibility; using AndroidX.CustomView.Widget; @@ -15,20 +13,6 @@ namespace Avalonia.Android { internal class AvaloniaAccessHelper : ExploreByTouchHelper { - private const string AUTOMATION_PROVIDER_NAMESPACE = "Avalonia.Automation.Provider"; - - private static readonly IReadOnlyDictionary - s_providerTypeInitializers = new Dictionary() - { - { typeof(IExpandCollapseProvider).FullName!, (owner, peer, id) => new ExpandCollapseNodeInfoProvider(owner, peer, id) }, - { typeof(IInvokeProvider).FullName!, (owner, peer, id) => new InvokeNodeInfoProvider(owner, peer, id) }, - { typeof(IRangeValueProvider).FullName!, (owner, peer, id) => new RangeValueNodeInfoProvider(owner, peer, id) }, - { typeof(IScrollProvider).FullName!, (owner, peer, id) => new ScrollNodeInfoProvider(owner, peer, id) }, - { typeof(ISelectionItemProvider).FullName!, (owner, peer, id) => new SelectionItemNodeInfoProvider(owner, peer, id) }, - { typeof(IToggleProvider).FullName!, (owner, peer, id) => new ToggleNodeInfoProvider(owner, peer, id) }, - { typeof(IValueProvider).FullName!, (owner, peer, id) => new ValueNodeInfoProvider(owner, peer, id) }, - }; - private readonly Dictionary _peers; private readonly Dictionary _peerIds; @@ -96,17 +80,20 @@ namespace Avalonia.Android } }; - Type peerType = peer.GetType(); - IEnumerable providerTypes = peerType.GetInterfaces() - .Where(x => x.Namespace!.StartsWith(AUTOMATION_PROVIDER_NAMESPACE)); - foreach (Type providerType in providerTypes) - { - if (s_providerTypeInitializers.TryGetValue(providerType.FullName!, out NodeInfoProviderInitializer? ctor)) - { - INodeInfoProvider nodeInfoProvider = ctor(this, peer, peerViewId); - nodeInfoProviders.Add(nodeInfoProvider); - } - } + if (peer is IExpandCollapseProvider) + nodeInfoProviders.Add(new ExpandCollapseNodeInfoProvider(this, peer, peerViewId)); + if (peer is IInvokeProvider) + nodeInfoProviders.Add(new InvokeNodeInfoProvider(this, peer, peerViewId)); + if (peer is IRangeValueProvider) + nodeInfoProviders.Add(new RangeValueNodeInfoProvider(this, peer, peerViewId)); + if (peer is IScrollProvider) + nodeInfoProviders.Add(new ScrollNodeInfoProvider(this, peer, peerViewId)); + if (peer is ISelectionItemProvider) + nodeInfoProviders.Add(new SelectionItemNodeInfoProvider(this, peer, peerViewId)); + if (peer is IToggleProvider) + nodeInfoProviders.Add(new ToggleNodeInfoProvider(this, peer, peerViewId)); + if (peer is IValueProvider) + nodeInfoProviders.Add(new ValueNodeInfoProvider(this, peer, peerViewId)); } virtualViewId = peerViewId; @@ -151,9 +138,9 @@ namespace Avalonia.Android .Aggregate(false, (a, b) => a | b); } - protected override void OnPopulateNodeForVirtualView(int virtualViewId, AccessibilityNodeInfoCompat nodeInfo) + protected override void OnPopulateNodeForVirtualView(int virtualViewId, AccessibilityNodeInfoCompat? nodeInfo) { - if (!_peers.TryGetValue(virtualViewId, out AutomationPeer? peer)) + if (nodeInfo is null || !_peers.TryGetValue(virtualViewId, out AutomationPeer? peer)) { return; // BAIL!! No work to be done } diff --git a/src/Android/Avalonia.Android/AvaloniaActivity.cs b/src/Android/Avalonia.Android/AvaloniaActivity.cs index cf425d279e..8577b54b0e 100644 --- a/src/Android/Avalonia.Android/AvaloniaActivity.cs +++ b/src/Android/Avalonia.Android/AvaloniaActivity.cs @@ -7,6 +7,7 @@ using Android.Content.PM; using Android.OS; using Android.Runtime; using Android.Views; +using Android.Window; using AndroidX.AppCompat.App; using Avalonia.Android.Platform; using Avalonia.Android.Platform.Storage; @@ -17,9 +18,9 @@ namespace Avalonia.Android; /// /// Common implementation of android activity that is integrated with Avalonia views. -/// If you need a base class for main activity of Avalonia app, see or . +/// If you need a base class for main activity of Avalonia app, see . /// -public class AvaloniaActivity : AppCompatActivity, IAvaloniaActivity +public class AvaloniaActivity : AppCompatActivity, IAvaloniaActivity, IOnBackInvokedCallback { private EventHandler? _onActivated, _onDeactivated; private GlobalLayoutListener? _listener; @@ -77,6 +78,9 @@ public class AvaloniaActivity : AppCompatActivity, IAvaloniaActivity [ObsoletedOSPlatform("android33.0")] public override void OnBackPressed() { + if (OperatingSystem.IsAndroidVersionAtLeast(33)) + return; + var eventArgs = new AndroidBackRequestedEventArgs(); BackRequested?.Invoke(this, eventArgs); @@ -120,12 +124,22 @@ public class AvaloniaActivity : AppCompatActivity, IAvaloniaActivity protected override void OnStop() { _onDeactivated?.Invoke(this, new ActivatedEventArgs(ActivationKind.Background)); + + if (OperatingSystem.IsAndroidVersionAtLeast(33)) + { + OnBackInvokedDispatcher.UnregisterOnBackInvokedCallback(this); + } base.OnStop(); } protected override void OnStart() { _onActivated?.Invoke(this, new ActivatedEventArgs(ActivationKind.Background)); + + if (OperatingSystem.IsAndroidVersionAtLeast(33)) + { + OnBackInvokedDispatcher.RegisterOnBackInvokedCallback(IOnBackInvokedDispatcher.PriorityDefault, this); + } base.OnStart(); } @@ -186,6 +200,13 @@ public class AvaloniaActivity : AppCompatActivity, IAvaloniaActivity _view = new AvaloniaView(this) { Content = initialContent }; } + public void OnBackInvoked() + { + var eventArgs = new AndroidBackRequestedEventArgs(); + + BackRequested?.Invoke(this, eventArgs); + } + private class GlobalLayoutListener : Java.Lang.Object, ViewTreeObserver.IOnGlobalLayoutListener { private readonly AvaloniaView _view; diff --git a/src/Android/Avalonia.Android/Platform/AndroidDataFormatHelper.cs b/src/Android/Avalonia.Android/Platform/AndroidDataFormatHelper.cs index 686234aaef..ac6d214224 100644 --- a/src/Android/Avalonia.Android/Platform/AndroidDataFormatHelper.cs +++ b/src/Android/Avalonia.Android/Platform/AndroidDataFormatHelper.cs @@ -7,6 +7,7 @@ namespace Avalonia.Android.Platform; internal static class AndroidDataFormatHelper { private const string AppPrefix = "application/avn-fmt."; + private const string MimeTypeImagePng = "image/png"; public static DataFormat MimeTypeToDataFormat(string mimeType) { @@ -16,6 +17,9 @@ internal static class AndroidDataFormatHelper if (mimeType == ClipDescription.MimetypeTextUrilist) return DataFormat.File; + if (mimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) + return DataFormat.Bitmap; + if (mimeType.StartsWith("text/", StringComparison.OrdinalIgnoreCase)) return DataFormat.FromSystemName(mimeType, AppPrefix); @@ -30,6 +34,9 @@ internal static class AndroidDataFormatHelper if (DataFormat.File.Equals(format)) return ClipDescription.MimetypeTextUrilist; + if (DataFormat.Bitmap.Equals(format)) + return MimeTypeImagePng; + return format.ToSystemName(AppPrefix); } diff --git a/src/Android/Avalonia.Android/Platform/AndroidInsetsManager.cs b/src/Android/Avalonia.Android/Platform/AndroidInsetsManager.cs index 8a3685b65e..45345f9da7 100644 --- a/src/Android/Avalonia.Android/Platform/AndroidInsetsManager.cs +++ b/src/Android/Avalonia.Android/Platform/AndroidInsetsManager.cs @@ -127,10 +127,13 @@ namespace Avalonia.Android.Platform WindowInsetsCompat.Type.StatusBars() | WindowInsetsCompat.Type.NavigationBars() | WindowInsetsCompat.Type.DisplayCutout() : 0); - return new Thickness(inset.Left / renderScaling, - inset.Top / renderScaling, - inset.Right / renderScaling, - inset.Bottom / renderScaling); + if (inset is not null) + { + return new Thickness(inset.Left / renderScaling, + inset.Top / renderScaling, + inset.Right / renderScaling, + inset.Bottom / renderScaling); + } } return default; @@ -145,9 +148,10 @@ namespace Avalonia.Android.Platform if (insets != null) { - var navbarInset = insets.GetInsets(WindowInsetsCompat.Type.NavigationBars()).Bottom; + var navbarInset = insets.GetInsets(WindowInsetsCompat.Type.NavigationBars())?.Bottom ?? 0; + var imeInset = insets.GetInsets(WindowInsetsCompat.Type.Ime())?.Bottom ?? 0; - var height = Math.Max((float)((insets.GetInsets(WindowInsetsCompat.Type.Ime()).Bottom - navbarInset) / _topLevel.RenderScaling), 0); + var height = Math.Max((float)((imeInset - navbarInset) / _topLevel.RenderScaling), 0); return new Rect(0, _topLevel.ClientSize.Height - SafeAreaPadding.Bottom - height, _topLevel.ClientSize.Width, height); } @@ -156,7 +160,7 @@ namespace Avalonia.Android.Platform } } - public WindowInsetsCompat OnApplyWindowInsets(View v, WindowInsetsCompat insets) + public WindowInsetsCompat? OnApplyWindowInsets(View? v, WindowInsetsCompat? insets) { insets = ViewCompat.OnApplyWindowInsets(v, insets); NotifySafeAreaChanged(SafeAreaPadding); @@ -166,15 +170,14 @@ namespace Avalonia.Android.Platform _previousRect = OccludedRect; } - State = insets.IsVisible(WindowInsetsCompat.Type.Ime()) ? InputPaneState.Open : InputPaneState.Closed; + State = insets is not null && insets.IsVisible(WindowInsetsCompat.Type.Ime()) ? InputPaneState.Open : InputPaneState.Closed; // Workaround for weird inset values for android 11 if(Build.VERSION.SdkInt == BuildVersionCodes.R) { - var imeInset = insets.GetInsets(WindowInsetsCompat.Type.Ime()); - if(_previousImeInset == default) - _previousImeInset = imeInset; - if(imeInset.Bottom != _previousImeInset.Bottom) + var imeInset = insets?.GetInsets(WindowInsetsCompat.Type.Ime()); + _previousImeInset ??= imeInset; + if ((imeInset?.Bottom ?? 0) != (_previousImeInset?.Bottom ?? 0)) { NotifyStateChanged(State, _previousRect, OccludedRect, TimeSpan.Zero, null); } @@ -285,7 +288,9 @@ namespace Avalonia.Android.Platform if (_isDisplayEdgeToEdgeForced) { // Allow having fully transparent navbars when on api level 35 - if (OperatingSystem.IsAndroidVersionAtLeast(35)) + if (OperatingSystem.IsAndroidVersionAtLeast(36)) + Window.NavigationBarContrastEnforced = false; + else if (OperatingSystem.IsAndroidVersionAtLeast(35)) Window.NavigationBarContrastEnforced = _systemBarColor != Colors.Transparent; return; } @@ -319,18 +324,18 @@ namespace Avalonia.Android.Platform SystemBarColor = _systemBarColor; } - public override WindowInsetsAnimationCompat.BoundsCompat OnStart(WindowInsetsAnimationCompat animation, WindowInsetsAnimationCompat.BoundsCompat bounds) + public override WindowInsetsAnimationCompat.BoundsCompat? OnStart(WindowInsetsAnimationCompat? animation, WindowInsetsAnimationCompat.BoundsCompat? bounds) { - if ((animation.TypeMask & WindowInsetsCompat.Type.Ime()) != 0) + if (animation is not null && bounds is not null && (animation.TypeMask & WindowInsetsCompat.Type.Ime()) != 0) { var insets = ViewCompat.GetRootWindowInsets(Window.DecorView); if (insets != null) { - var navbarInset = insets.GetInsets(WindowInsetsCompat.Type.NavigationBars()).Bottom; - var height = Math.Max(0, (float)((bounds.LowerBound.Bottom - navbarInset) / _topLevel.RenderScaling)); + var navbarInset = insets.GetInsets(WindowInsetsCompat.Type.NavigationBars())?.Bottom ?? 0; + var height = Math.Max(0, (float)(((bounds.LowerBound?.Bottom ?? 0) - navbarInset) / _topLevel.RenderScaling)); var upperRect = new Rect(0, _topLevel.ClientSize.Height - SafeAreaPadding.Bottom - height, _topLevel.ClientSize.Width, height); - height = Math.Max(0, (float)((bounds.UpperBound.Bottom - navbarInset) / _topLevel.RenderScaling)); + height = Math.Max(0, (float)(((bounds.UpperBound?.Bottom ?? 0) - navbarInset) / _topLevel.RenderScaling)); var lowerRect = new Rect(0, _topLevel.ClientSize.Height - SafeAreaPadding.Bottom - height, _topLevel.ClientSize.Width, height); var duration = TimeSpan.FromMilliseconds(animation.DurationMillis); @@ -344,7 +349,7 @@ namespace Avalonia.Android.Platform return base.OnStart(animation, bounds); } - public override WindowInsetsCompat OnProgress(WindowInsetsCompat insets, IList runningAnimations) + public override WindowInsetsCompat? OnProgress(WindowInsetsCompat? insets, IList? runningAnimations) { return insets; } diff --git a/src/Android/Avalonia.Android/Platform/AndroidScreens.cs b/src/Android/Avalonia.Android/Platform/AndroidScreens.cs index 95d2530edc..3f1f9bf44e 100644 --- a/src/Android/Avalonia.Android/Platform/AndroidScreens.cs +++ b/src/Android/Avalonia.Android/Platform/AndroidScreens.cs @@ -32,11 +32,18 @@ internal class AndroidScreen(Display display) : PlatformScreen(new PlatformHandl var metrics = metricsCalc.ComputeMaximumWindowMetrics(displayContext); Bounds = new(metrics.Bounds.Left, metrics.Bounds.Top, metrics.Bounds.Width(), metrics.Bounds.Height()); - var inset = metrics.WindowInsets.GetInsets(WindowInsetsCompat.Type.SystemBars()); - WorkingArea = new(Bounds.X + inset.Left, - Bounds.Y + inset.Top, - Bounds.Width - (inset.Left + inset.Right), - Bounds.Height - (inset.Top + inset.Bottom)); + var windowInsets = new WindowInsetsCompat.Builder().Build(); + if (windowInsets?.GetInsets(WindowInsetsCompat.Type.SystemBars()) is { } inset) + { + WorkingArea = new(Bounds.X + inset.Left, + Bounds.Y + inset.Top, + Bounds.Width - (inset.Left + inset.Right), + Bounds.Height - (inset.Top + inset.Bottom)); + } + else + { + WorkingArea = Bounds; + } if (context.Resources?.Configuration is { } config) { diff --git a/src/Android/Avalonia.Android/Platform/ClipDataItemToDataTransferItemWrapper.cs b/src/Android/Avalonia.Android/Platform/ClipDataItemToDataTransferItemWrapper.cs index 479e5e2001..840b95188e 100644 --- a/src/Android/Avalonia.Android/Platform/ClipDataItemToDataTransferItemWrapper.cs +++ b/src/Android/Avalonia.Android/Platform/ClipDataItemToDataTransferItemWrapper.cs @@ -1,9 +1,13 @@ using System; +using System.IO; using Android.App; using Android.Content; using Avalonia.Android.Platform.Storage; using Avalonia.Input; using Avalonia.Input.Platform; +using Avalonia.Logging; +using Avalonia.Media.Imaging; +using Avalonia.Platform.Storage; namespace Avalonia.Android.Platform; @@ -15,44 +19,90 @@ namespace Avalonia.Android.Platform; internal sealed class ClipDataItemToDataTransferItemWrapper(ClipData.Item item, ClipDataToDataTransferWrapper owner) : PlatformDataTransferItem { - private readonly ClipData.Item _item = item; - private readonly ClipDataToDataTransferWrapper _owner = owner; - protected override DataFormat[] ProvideFormats() - => _owner.Formats; // There's no "format per item", assume each item handle all formats + => owner.Formats; // There's no "format per item", assume each item handle all formats protected override object? TryGetRawCore(DataFormat format) { if (DataFormat.Text.Equals(format)) - return _item.CoerceToText(_owner.Context); + return item.CoerceToText(owner.Context); + + if (format is DataFormat) + return TryGetString(); if (DataFormat.File.Equals(format)) - { - return _item.Uri is { Scheme: "file" or "content" } fileUri && _owner.Context is Activity activity ? - AndroidStorageItem.CreateItem(activity, fileUri) : - null; - } + return TryGetStorageItem(); - if (format is DataFormat) - return TryGetAsString(); + if (DataFormat.Bitmap.Equals(format)) + return TryGetBitmap(); + + if (format is DataFormat) + return TryGetBytes(); return null; } - private string? TryGetAsString() + private string? TryGetString() { - if (_item.Text is { } text) + if (item.Text is { } text) return text; - if (_item.HtmlText is { } htmlText) + if (item.HtmlText is { } htmlText) return htmlText; - if (_item.Uri is { } uri) + if (item.Uri is { } uri) return uri.ToString(); - if (_item.Intent is { } intent) + if (item.Intent is { } intent) return intent.ToUri(IntentUriType.Scheme); return null; } + + private IStorageItem? TryGetStorageItem() + => item.Uri is { Scheme: "file" or "content" } fileUri && owner.Context is Activity activity ? + AndroidStorageItem.CreateItem(activity, fileUri) : + null; + + private object? TryGetBitmap() + { + try + { + if (TryGetStorageItem() is AndroidStorageFile storageFile) + { + using var stream = storageFile.OpenRead(); + + return new Bitmap(stream); + } + } + catch (Exception ex) + { + Logger.TryGet(LogEventLevel.Warning, LogArea.AndroidPlatform) + ?.Log(this, "Could not get bitmap from clipboard: {Error}", ex.Message); + } + + return null; + } + + private object? TryGetBytes() + { + try + { + if (TryGetStorageItem() is AndroidStorageFile storageFile) + { + using var stream = storageFile.OpenRead(); + + using var mem = new MemoryStream(); + stream.CopyTo(mem); + return mem.ToArray(); + } + } + catch (Exception ex) + { + Logger.TryGet(LogEventLevel.Warning, LogArea.AndroidPlatform) + ?.Log(this, "Could not get bytes from clipboard: {Error}", ex.Message); + } + + return null; + } } diff --git a/src/Android/Avalonia.Android/Platform/ClipDataToDataTransferWrapper.cs b/src/Android/Avalonia.Android/Platform/ClipDataToDataTransferWrapper.cs index 8bd9079142..d5e8c55ede 100644 --- a/src/Android/Avalonia.Android/Platform/ClipDataToDataTransferWrapper.cs +++ b/src/Android/Avalonia.Android/Platform/ClipDataToDataTransferWrapper.cs @@ -1,4 +1,5 @@ -using Android.Content; +using System.Linq; +using Android.Content; using Avalonia.Input; using Avalonia.Input.Platform; @@ -23,9 +24,20 @@ internal sealed class ClipDataToDataTransferWrapper(ClipData clipData, Context? var formats = new DataFormat[count]; + bool hasImage = false; for (var i = 0; i < count; ++i) + { formats[i] = AndroidDataFormatHelper.MimeTypeToDataFormat(clipDescription.GetMimeType(i)!); + if (!hasImage) + hasImage = formats[i].Identifier.StartsWith("image/", System.StringComparison.OrdinalIgnoreCase); + } + + if (hasImage) + { + formats = [.. formats, DataFormat.Bitmap]; + } + return formats; } diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs index 7bfcf92593..7a0d9793a3 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs @@ -1,8 +1,6 @@ using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; -using Android.Runtime; -using Android.Views; using Avalonia.Platform; namespace Avalonia.Android.Platform.SkiaPlatform @@ -11,11 +9,11 @@ namespace Avalonia.Android.Platform.SkiaPlatform { private IntPtr _window; - public AndroidFramebuffer(Surface surface, double scaling) + public AndroidFramebuffer(InvalidationAwareSurfaceView surface, double scaling) { if(surface == null) throw new ArgumentNullException(nameof(surface)); - _window = ANativeWindow_fromSurface(JNIEnv.Handle, surface.Handle); + _window = (surface as IPlatformHandle).Handle; if (_window == IntPtr.Zero) throw new Exception("Unable to obtain ANativeWindow"); ANativeWindow_Buffer buffer; @@ -39,7 +37,6 @@ namespace Avalonia.Android.Platform.SkiaPlatform public void Dispose() { ANativeWindow_unlockAndPost(_window); - ANativeWindow_release(_window); _window = IntPtr.Zero; Address = IntPtr.Zero; } diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs index 31dae74b1f..e096d32f48 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs @@ -14,7 +14,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform } public ILockedFramebuffer Lock() => new AndroidFramebuffer( - _topLevel.InternalView.Holder?.Surface ?? throw new InvalidOperationException("TopLevel.InternalView.Holder.Surface was not expected to be null."), + _topLevel.InternalView ?? throw new InvalidOperationException("TopLevel.InternalView was not expected to be null."), _topLevel.RenderScaling); public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock); diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs index f15322a6a7..7a495c4221 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs @@ -42,26 +42,26 @@ namespace Avalonia.Android public virtual void SurfaceChanged(ISurfaceHolder holder, Format format, int width, int height) { - CacheSurfaceProperties(holder); Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)? - .Log(this, "InvalidationAwareSurfaceView Changed"); + .Log(this, $"InvalidationAwareSurfaceView Changed. Format:{format} Size:{width} x {height}"); + CacheSurfaceProperties(holder); } public void SurfaceCreated(ISurfaceHolder holder) { - CacheSurfaceProperties(holder); Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)? .Log(this, "InvalidationAwareSurfaceView Created"); + CacheSurfaceProperties(holder); SurfaceWindowCreated?.Invoke(this, EventArgs.Empty); } public void SurfaceDestroyed(ISurfaceHolder holder) { + Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)? + .Log(this, "InvalidationAwareSurfaceView Destroyed"); ReleaseNativeWindowHandle(); _size = new PixelSize(1, 1); _scaling = 1; - Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)? - .Log(this, "InvalidationAwareSurfaceView Destroyed"); } public virtual void SurfaceRedrawNeeded(ISurfaceHolder holder) diff --git a/src/Android/Avalonia.Android/Platform/Storage/AndroidStorageItem.cs b/src/Android/Avalonia.Android/Platform/Storage/AndroidStorageItem.cs index cdbab13701..d8cd173183 100644 --- a/src/Android/Avalonia.Android/Platform/Storage/AndroidStorageItem.cs +++ b/src/Android/Avalonia.Android/Platform/Storage/AndroidStorageItem.cs @@ -389,8 +389,10 @@ internal sealed class AndroidStorageFile : AndroidStorageItem, IStorageBookmarkF { } - public Task OpenReadAsync() => Task.FromResult(OpenContentStream(Activity, Uri, false) - ?? throw new InvalidOperationException("Failed to open content stream")); + public Task OpenReadAsync() => Task.FromResult(OpenRead()); + + public Stream OpenRead() => OpenContentStream(Activity, Uri, false) + ?? throw new InvalidOperationException("Failed to open content stream"); public Task OpenWriteAsync() => Task.FromResult(OpenContentStream(Activity, Uri, true) ?? throw new InvalidOperationException("Failed to open content stream")); diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj index 485a825017..ea1dfd766b 100644 --- a/src/Avalonia.Base/Avalonia.Base.csproj +++ b/src/Avalonia.Base/Avalonia.Base.csproj @@ -1,6 +1,6 @@  - $(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0 + $(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks) Avalonia True true @@ -29,7 +29,6 @@ - @@ -45,12 +44,10 @@ - - diff --git a/src/Avalonia.Base/Data/Core/BindingExpression.cs b/src/Avalonia.Base/Data/Core/BindingExpression.cs index ca29dd6ffa..a51ee5bf8a 100644 --- a/src/Avalonia.Base/Data/Core/BindingExpression.cs +++ b/src/Avalonia.Base/Data/Core/BindingExpression.cs @@ -190,6 +190,9 @@ internal partial class BindingExpression : UntypedBindingExpressionBase, IDescri /// The null target value. /// Whether to allow reflection for target type conversion. [RequiresUnreferencedCode(TrimmingMessages.ExpressionNodeRequiresUnreferencedCodeMessage)] +#if NET8_0_OR_GREATER + [RequiresDynamicCode(TrimmingMessages.ExpressionNodeRequiresDynamicCodeMessage)] +#endif internal static BindingExpression Create( TIn source, Expression> expression, diff --git a/src/Avalonia.Base/Data/Core/ExpressionNodes/Reflection/DynamicPluginStreamNode.cs b/src/Avalonia.Base/Data/Core/ExpressionNodes/Reflection/DynamicPluginStreamNode.cs index f6c692e685..dd8c0e1a63 100644 --- a/src/Avalonia.Base/Data/Core/ExpressionNodes/Reflection/DynamicPluginStreamNode.cs +++ b/src/Avalonia.Base/Data/Core/ExpressionNodes/Reflection/DynamicPluginStreamNode.cs @@ -7,6 +7,9 @@ using Avalonia.Reactive; namespace Avalonia.Data.Core.ExpressionNodes.Reflection; [RequiresUnreferencedCode(TrimmingMessages.ExpressionNodeRequiresUnreferencedCodeMessage)] +#if NET8_0_OR_GREATER +[RequiresDynamicCode(TrimmingMessages.ExpressionNodeRequiresDynamicCodeMessage)] +#endif internal sealed class DynamicPluginStreamNode : ExpressionNode { private IDisposable? _subscription; diff --git a/src/Avalonia.Base/Data/Core/ExpressionNodes/Reflection/ExpressionTreeIndexerNode.cs b/src/Avalonia.Base/Data/Core/ExpressionNodes/Reflection/ExpressionTreeIndexerNode.cs index e720aa6e69..dfb83fb10d 100644 --- a/src/Avalonia.Base/Data/Core/ExpressionNodes/Reflection/ExpressionTreeIndexerNode.cs +++ b/src/Avalonia.Base/Data/Core/ExpressionNodes/Reflection/ExpressionTreeIndexerNode.cs @@ -16,6 +16,9 @@ internal sealed class ExpressionTreeIndexerNode : CollectionNodeBase, ISettableN private readonly Delegate _getDelegate; private readonly Delegate _firstArgumentDelegate; +#if NET8_0_OR_GREATER + [RequiresDynamicCode(TrimmingMessages.ExpressionNodeRequiresDynamicCodeMessage)] +#endif public ExpressionTreeIndexerNode(IndexExpression expression) { var valueParameter = Expression.Parameter(expression.Type); diff --git a/src/Avalonia.Base/Data/Core/Parsers/BindingExpressionVisitor.cs b/src/Avalonia.Base/Data/Core/Parsers/BindingExpressionVisitor.cs index 39d6ffcab6..1981732145 100644 --- a/src/Avalonia.Base/Data/Core/Parsers/BindingExpressionVisitor.cs +++ b/src/Avalonia.Base/Data/Core/Parsers/BindingExpressionVisitor.cs @@ -11,6 +11,9 @@ using Avalonia.Data.Core.ExpressionNodes.Reflection; namespace Avalonia.Data.Core.Parsers; [RequiresUnreferencedCode(TrimmingMessages.ExpressionNodeRequiresUnreferencedCodeMessage)] +#if NET8_0_OR_GREATER +[RequiresDynamicCode(TrimmingMessages.ExpressionNodeRequiresDynamicCodeMessage)] +#endif internal class BindingExpressionVisitor : ExpressionVisitor { private static readonly PropertyInfo AvaloniaObjectIndexer; diff --git a/src/Avalonia.Base/Data/Core/Plugins/BindingPlugins.cs b/src/Avalonia.Base/Data/Core/Plugins/BindingPlugins.cs index 5c2d9aaddf..520c345ad5 100644 --- a/src/Avalonia.Base/Data/Core/Plugins/BindingPlugins.cs +++ b/src/Avalonia.Base/Data/Core/Plugins/BindingPlugins.cs @@ -28,6 +28,7 @@ namespace Avalonia.Data.Core.Plugins new ObservableStreamPlugin(), }; + [UnconditionalSuppressMessage("AOT", "IL3050", Justification = "We're checking if dynamic code is supported.")] static BindingPlugins() { // When building with AOT, don't create ReflectionMethodAccessorPlugin instance. diff --git a/src/Avalonia.Base/Data/Core/Plugins/ReflectionMethodAccessorPlugin.cs b/src/Avalonia.Base/Data/Core/Plugins/ReflectionMethodAccessorPlugin.cs index e295fc6066..f9a4587ca6 100644 --- a/src/Avalonia.Base/Data/Core/Plugins/ReflectionMethodAccessorPlugin.cs +++ b/src/Avalonia.Base/Data/Core/Plugins/ReflectionMethodAccessorPlugin.cs @@ -7,6 +7,9 @@ using System.Reflection; namespace Avalonia.Data.Core.Plugins { [RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)] +#if NET8_0_OR_GREATER + [RequiresDynamicCode(TrimmingMessages.ExpressionNodeRequiresDynamicCodeMessage)] +#endif internal class ReflectionMethodAccessorPlugin : IPropertyAccessorPlugin { private readonly Dictionary<(Type, string), MethodInfo?> _methodLookup = @@ -81,6 +84,9 @@ namespace Avalonia.Data.Core.Plugins return found; } +#if NET8_0_OR_GREATER + [RequiresDynamicCode(TrimmingMessages.ExpressionNodeRequiresDynamicCodeMessage)] +#endif private sealed class Accessor : PropertyAccessorBase { public Accessor(WeakReference reference, MethodInfo method) diff --git a/src/Avalonia.Base/Diagnostics/TrimmingMessages.cs b/src/Avalonia.Base/Diagnostics/TrimmingMessages.cs index ce9c9e187b..930ff4202b 100644 --- a/src/Avalonia.Base/Diagnostics/TrimmingMessages.cs +++ b/src/Avalonia.Base/Diagnostics/TrimmingMessages.cs @@ -9,11 +9,13 @@ internal static class TrimmingMessages public const string TypeConversionRequiresUnreferencedCodeMessage = "Conversion methods are required for type conversion, including op_Implicit, op_Explicit, Parse and TypeConverter."; public const string ReflectionBindingRequiresUnreferencedCodeMessage = "BindingExpression and ReflectionBinding heavily use reflection. Consider using CompiledBindings instead."; + public const string ReflectionBindingRequiresDynamicCodeMessage = "BindingExpression and ReflectionBinding require dynamic code. Consider using CompiledBindings instead."; public const string ReflectionBindingSupressWarningMessage = "BindingExpression and ReflectionBinding internal heavily use reflection."; public const string CompiledBindingSafeSupressWarningMessage = "CompiledBinding preserves members used in the expression tree."; public const string ExpressionNodeRequiresUnreferencedCodeMessage = "ExpressionNode might require unreferenced code."; + public const string ExpressionNodeRequiresDynamicCodeMessage = "ExpressionNode requires dynamic code."; public const string ExpressionSafeSupressWarningMessage = "Typed Expressions preserves members used in the expression tree."; public const string SelectorsParseRequiresUnreferencedCodeMessage = "Selectors runtime parser might require unreferenced code. Consider using stronly typed selectors factory with 'new Style(s => s.OfType