Browse Source

Merge branch 'master' into fix/Platform/Windows/WindowsInputPane/Leak

pull/16916/head
workgroupengineering 3 weeks ago
committed by GitHub
parent
commit
c84d85a8f3
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 3
      .gitmodules
  2. 11
      Avalonia.Desktop.slnf
  3. 51
      Avalonia.sln
  4. 76
      Directory.Packages.props
  5. 24
      NOTICE.md
  6. 6
      NuGet.Config
  7. 12
      api/Avalonia.Android.nupkg.xml
  8. 12
      api/Avalonia.Skia.nupkg.xml
  9. 758
      api/Avalonia.nupkg.xml
  10. 2
      build/AnalyzerProject.targets
  11. 6
      build/Base.props
  12. 5
      build/Binding.props
  13. 6
      build/HarfBuzzSharp.props
  14. 5
      build/ImageSharp.props
  15. 3
      build/LegacyProject.targets
  16. 5
      build/Microsoft.CSharp.props
  17. 5
      build/Microsoft.Reactive.Testing.props
  18. 5
      build/Moq.props
  19. 4
      build/NetCore.props
  20. 6
      build/NetFX.props
  21. 5
      build/Rx.props
  22. 2
      build/SampleApp.props
  23. 14
      build/SharpDX.props
  24. 6
      build/SkiaSharp.props
  25. 1
      build/UnitTests.NetFX.props
  26. 2
      build/XUnit.props
  27. 6
      build/readme.md
  28. 3
      dirs.proj
  29. 1
      external/Avalonia.DBus
  30. 2
      external/XamlX
  31. 60
      native/Avalonia.Native/src/OSX/StorageProvider.mm
  32. 12
      native/Avalonia.Native/src/OSX/app.mm
  33. 5
      native/Avalonia.Native/src/OSX/automation.mm
  34. 1
      native/Avalonia.Native/src/OSX/common.h
  35. 19
      native/Avalonia.Native/src/OSX/main.mm
  36. 10
      nukebuild/_build.csproj
  37. 3
      packages/Avalonia/Avalonia.csproj
  38. 5
      samples/BindingDemo/BindingDemo.csproj
  39. 2
      samples/ControlCatalog.Android/ControlCatalog.Android.csproj
  40. 2
      samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
  41. 9
      samples/ControlCatalog/App.xaml
  42. 34
      samples/ControlCatalog/App.xaml.cs
  43. 18
      samples/ControlCatalog/MainView.xaml
  44. 4
      samples/ControlCatalog/MainView.xaml.cs
  45. 36
      samples/ControlCatalog/Pages/AdornerLayerPage.xaml
  46. 4
      samples/ControlCatalog/Pages/GesturePage.cs
  47. 2
      samples/ControlCatalog/ViewModels/ContextPageViewModel.cs
  48. 2
      samples/ControlCatalog/ViewModels/MenuPageViewModel.cs
  49. 2
      samples/Generators.Sandbox/Generators.Sandbox.csproj
  50. 6
      samples/GpuInterop/DrawingSurfaceDemoBase.cs
  51. 12
      samples/GpuInterop/GpuInterop.csproj
  52. 7
      samples/IntegrationTestApp/App.axaml
  53. 25
      samples/IntegrationTestApp/App.axaml.cs
  54. 4
      samples/IntegrationTestApp/IntegrationTestApp.csproj
  55. 2
      samples/IntegrationTestApp/Pages/AutomationPage.axaml
  56. 6
      samples/IntegrationTestApp/Pages/DesktopPage.axaml
  57. 10
      samples/IntegrationTestApp/Pages/DesktopPage.axaml.cs
  58. 4
      samples/PlatformSanityChecks/PlatformSanityChecks.csproj
  59. 5
      samples/Previewer/App.xaml
  60. 22
      samples/Previewer/App.xaml.cs
  61. 19
      samples/Previewer/Center.cs
  62. 12
      samples/Previewer/MainWindow.xaml
  63. 86
      samples/Previewer/MainWindow.xaml.cs
  64. 20
      samples/Previewer/Previewer.csproj
  65. 14
      samples/Previewer/Program.cs
  66. 53
      samples/RemoteDemo/Program.cs
  67. 12
      samples/RemoteDemo/RemoteDemo.csproj
  68. 8
      samples/RenderDemo/App.config
  69. 5
      samples/RenderDemo/RenderDemo.csproj
  70. 2
      samples/XEmbedSample/XEmbedSample.csproj
  71. 18
      samples/interop/WindowsInteropTest/App.config
  72. 4
      src/Android/Avalonia.Android/Avalonia.Android.csproj
  73. 22
      src/Android/Avalonia.Android/AvaloniaAccessHelper.cs
  74. 3
      src/Android/Avalonia.Android/AvaloniaMainActivity.cs
  75. 3
      src/Android/Avalonia.Android/Platform/Input/AvaloniaInputConnection.cs
  76. 5
      src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
  77. 21
      src/Android/Avalonia.Android/Platform/Storage/AndroidStorageItem.cs
  78. 5
      src/Avalonia.Base/Avalonia.Base.csproj
  79. 26
      src/Avalonia.Base/Input/AccessKeyHandler.cs
  80. 4
      src/Avalonia.Base/Input/DragDropDevice.cs
  81. 14
      src/Avalonia.Base/Input/FocusManager.cs
  82. 5
      src/Avalonia.Base/Input/Gestures.cs
  83. 2
      src/Avalonia.Base/Input/IAccessKeyHandler.cs
  84. 38
      src/Avalonia.Base/Input/IInputRoot.cs
  85. 4
      src/Avalonia.Base/Input/IKeyboardNavigationHandler.cs
  86. 4
      src/Avalonia.Base/Input/InputElement.cs
  87. 8
      src/Avalonia.Base/Input/KeyboardDevice.cs
  88. 9
      src/Avalonia.Base/Input/KeyboardNavigationHandler.cs
  89. 20
      src/Avalonia.Base/Input/MouseDevice.cs
  90. 11
      src/Avalonia.Base/Input/Navigation/XYFocus.FindElements.cs
  91. 4
      src/Avalonia.Base/Input/Navigation/XYFocus.Impl.cs
  92. 14
      src/Avalonia.Base/Input/PenDevice.cs
  93. 4
      src/Avalonia.Base/Input/Pointer.cs
  94. 20
      src/Avalonia.Base/Input/PointerOverPreProcessor.cs
  95. 6
      src/Avalonia.Base/Input/TextInput/ITextInputMethodImpl.cs
  96. 4
      src/Avalonia.Base/Input/TextInput/InputMethodManager.cs
  97. 29
      src/Avalonia.Base/Input/TextInput/TransformTrackingHelper.cs
  98. 10
      src/Avalonia.Base/Input/TouchDevice.cs
  99. 10
      src/Avalonia.Base/Layout/IEmbeddedLayoutRoot.cs
  100. 1
      src/Avalonia.Base/Layout/ILayoutManager.cs

3
.gitmodules

@ -4,3 +4,6 @@
[submodule "XamlX"]
path = external/XamlX
url = https://github.com/kekekeks/XamlX.git
[submodule "Avalonia.DBus"]
path = external/Avalonia.DBus
url = https://github.com/AvaloniaUI/Avalonia.DBus.git

11
Avalonia.Desktop.slnf

@ -8,11 +8,11 @@
"samples\\ControlCatalog\\ControlCatalog.csproj",
"samples\\GpuInterop\\GpuInterop.csproj",
"samples\\IntegrationTestApp\\IntegrationTestApp.csproj",
"samples\\TextTestApp\\TextTestApp.csproj",
"samples\\MiniMvvm\\MiniMvvm.csproj",
"samples\\RenderDemo\\RenderDemo.csproj",
"samples\\SampleControls\\ControlSamples.csproj",
"samples\\Sandbox\\Sandbox.csproj",
"samples\\TextTestApp\\TextTestApp.csproj",
"samples\\UnloadableAssemblyLoadContext\\UnloadableAssemblyLoadContextPlug\\UnloadableAssemblyLoadContextPlug.csproj",
"samples\\UnloadableAssemblyLoadContext\\UnloadableAssemblyLoadContext\\UnloadableAssemblyLoadContext.csproj",
"samples\\XEmbedSample\\XEmbedSample.csproj",
@ -24,18 +24,20 @@
"src\\Avalonia.Desktop\\Avalonia.Desktop.csproj",
"src\\Avalonia.Dialogs\\Avalonia.Dialogs.csproj",
"src\\Avalonia.Fonts.Inter\\Avalonia.Fonts.Inter.csproj",
"src\\Avalonia.FreeDesktop.AtSpi\\Avalonia.FreeDesktop.AtSpi.csproj",
"src\\Avalonia.FreeDesktop\\Avalonia.FreeDesktop.csproj",
"src\\Avalonia.Metal\\Avalonia.Metal.csproj",
"src\\Avalonia.MicroCom\\Avalonia.MicroCom.csproj",
"src\\Avalonia.Native\\Avalonia.Native.csproj",
"src\\Avalonia.OpenGL\\Avalonia.OpenGL.csproj",
"src\\Avalonia.Vulkan\\Avalonia.Vulkan.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",
"src\\Avalonia.Vulkan\\Avalonia.Vulkan.csproj",
"src\\Avalonia.X11\\Avalonia.X11.csproj",
"src\\HarfBuzz\\Avalonia.HarfBuzz\\Avalonia.HarfBuzz.csproj",
"src\\Headless\\Avalonia.Headless.Vnc\\Avalonia.Headless.Vnc.csproj",
"src\\Headless\\Avalonia.Headless.XUnit\\Avalonia.Headless.XUnit.csproj",
"src\\Headless\\Avalonia.Headless\\Avalonia.Headless.csproj",
"src\\Linux\\Avalonia.LinuxFramebuffer\\Avalonia.LinuxFramebuffer.csproj",
"src\\Markup\\Avalonia.Markup.Xaml.Loader\\Avalonia.Markup.Xaml.Loader.csproj",
@ -45,6 +47,7 @@
"src\\tools\\Avalonia.Analyzers.CodeFixes.CSharp\\Avalonia.Analyzers.CodeFixes.CSharp.csproj",
"src\\tools\\Avalonia.Analyzers.CSharp\\Avalonia.Analyzers.CSharp.csproj",
"src\\tools\\Avalonia.Analyzers.VisualBasic\\Avalonia.Analyzers.VisualBasic.csproj",
"src\\tools\\Avalonia.DBus.Generators\\Avalonia.DBus.Generators.csproj",
"src\\tools\\Avalonia.Generators\\Avalonia.Generators.csproj",
"src\\tools\\DevAnalyzers\\DevAnalyzers.csproj",
"src\\tools\\DevGenerators\\DevGenerators.csproj",
@ -58,6 +61,8 @@
"tests\\Avalonia.DesignerSupport.TestApp\\Avalonia.DesignerSupport.TestApp.csproj",
"tests\\Avalonia.DesignerSupport.Tests\\Avalonia.DesignerSupport.Tests.csproj",
"tests\\Avalonia.Generators.Tests\\Avalonia.Generators.Tests.csproj",
"tests\\Avalonia.Headless.XUnit.PerAssembly.UnitTests\\Avalonia.Headless.XUnit.PerAssembly.UnitTests.csproj",
"tests\\Avalonia.Headless.XUnit.PerTest.UnitTests\\Avalonia.Headless.XUnit.PerTest.UnitTests.csproj",
"tests\\Avalonia.IntegrationTests.Appium\\Avalonia.IntegrationTests.Appium.csproj",
"tests\\Avalonia.LeakTests\\Avalonia.LeakTests.csproj",
"tests\\Avalonia.Markup.UnitTests\\Avalonia.Markup.UnitTests.csproj",
@ -69,4 +74,4 @@
"tests\\TestFiles\\BuildTasks\\PInvoke\\PInvoke.csproj"
]
}
}
}

51
Avalonia.sln

@ -83,21 +83,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1
build\AnalyzerProject.targets = build\AnalyzerProject.targets
build\AvaloniaPublicKey.props = build\AvaloniaPublicKey.props
build\Base.props = build\Base.props
build\Binding.props = build\Binding.props
build\CoreLibraries.props = build\CoreLibraries.props
build\DevAnalyzers.props = build\DevAnalyzers.props
build\EmbedXaml.props = build\EmbedXaml.props
build\HarfBuzzSharp.props = build\HarfBuzzSharp.props
build\ImageSharp.props = build\ImageSharp.props
build\Microsoft.CSharp.props = build\Microsoft.CSharp.props
build\Microsoft.Reactive.Testing.props = build\Microsoft.Reactive.Testing.props
build\Moq.props = build\Moq.props
build\NetAnalyzers.props = build\NetAnalyzers.props
build\NetCore.props = build\NetCore.props
build\NetFX.props = build\NetFX.props
build\NullableEnable.props = build\NullableEnable.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\SkiaSharp.props = build\SkiaSharp.props
@ -113,7 +105,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{4D6F
ProjectSection(SolutionItems) = preProject
build\BuildTargets.targets = build\BuildTargets.targets
build\DevSingleProject.targets = build\DevSingleProject.targets
build\LegacyProject.targets = build\LegacyProject.targets
build\UnitTests.NetCore.targets = build\UnitTests.NetCore.targets
EndProjectSection
EndProject
@ -127,14 +118,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.RenderTests",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Remote.Protocol", "src\Avalonia.Remote.Protocol\Avalonia.Remote.Protocol.csproj", "{D78A720C-C0C6-478B-8564-F167F9BDD01B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RemoteDemo", "samples\RemoteDemo\RemoteDemo.csproj", "{E2999E4A-9086-401F-898C-AEB0AD38E676}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{4ED8B739-6F4E-4CD4-B993-545E6B5CE637}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Designer.HostApp", "src\tools\Avalonia.Designer.HostApp\Avalonia.Designer.HostApp.csproj", "{050CC912-FF49-4A8B-B534-9544017446DD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Previewer", "samples\Previewer\Previewer.csproj", "{F40FC0A2-1BC3-401C-BFC1-928EC4D4A9CE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.UnitTests", "tests\Avalonia.Skia.UnitTests\Avalonia.Skia.UnitTests.csproj", "{E1240B49-7B4B-4371-A00E-068778C5CF0B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.OpenGL", "src\Avalonia.OpenGL\Avalonia.OpenGL.csproj", "{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}"
@ -292,6 +279,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Analyzers.CodeFixe
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Analyzers.VisualBasic", "src\tools\Avalonia.Analyzers.VisualBasic\Avalonia.Analyzers.VisualBasic.csproj", "{A7644C3B-B843-44F1-9940-560D56CB0936}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.FreeDesktop.AtSpi", "src\Avalonia.FreeDesktop.AtSpi\Avalonia.FreeDesktop.AtSpi.csproj", "{742C3613-514C-4D6B-804A-2A7925F278F3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.DBus.Generators", "src\tools\Avalonia.DBus.Generators\Avalonia.DBus.Generators.csproj", "{98A16FFD-0C99-4665-AC64-DC17E86879A2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -412,18 +403,10 @@ Global
{D78A720C-C0C6-478B-8564-F167F9BDD01B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D78A720C-C0C6-478B-8564-F167F9BDD01B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D78A720C-C0C6-478B-8564-F167F9BDD01B}.Release|Any CPU.Build.0 = Release|Any CPU
{E2999E4A-9086-401F-898C-AEB0AD38E676}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E2999E4A-9086-401F-898C-AEB0AD38E676}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E2999E4A-9086-401F-898C-AEB0AD38E676}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2999E4A-9086-401F-898C-AEB0AD38E676}.Release|Any CPU.Build.0 = Release|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{050CC912-FF49-4A8B-B534-9544017446DD}.Release|Any CPU.Build.0 = Release|Any CPU
{F40FC0A2-1BC3-401C-BFC1-928EC4D4A9CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F40FC0A2-1BC3-401C-BFC1-928EC4D4A9CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F40FC0A2-1BC3-401C-BFC1-928EC4D4A9CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F40FC0A2-1BC3-401C-BFC1-928EC4D4A9CE}.Release|Any CPU.Build.0 = Release|Any CPU
{E1240B49-7B4B-4371-A00E-068778C5CF0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E1240B49-7B4B-4371-A00E-068778C5CF0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1240B49-7B4B-4371-A00E-068778C5CF0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -670,14 +653,22 @@ Global
{11522B0D-BF31-42D5-8FC5-41E58F319AF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11522B0D-BF31-42D5-8FC5-41E58F319AF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11522B0D-BF31-42D5-8FC5-41E58F319AF9}.Release|Any CPU.Build.0 = Release|Any CPU
{A7644C3B-B843-44F1-9940-560D56CB0936}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7644C3B-B843-44F1-9940-560D56CB0936}.Release|Any CPU.Build.0 = Release|Any CPU
{A7644C3B-B843-44F1-9940-560D56CB0936}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{A7644C3B-B843-44F1-9940-560D56CB0936}.Debug|Any CPU.Build.0 = Release|Any CPU
{FDFB9C25-552D-420B-9D4A-DB0BB6472239}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FDFB9C25-552D-420B-9D4A-DB0BB6472239}.Release|Any CPU.Build.0 = Release|Any CPU
{FDFB9C25-552D-420B-9D4A-DB0BB6472239}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{FDFB9C25-552D-420B-9D4A-DB0BB6472239}.Debug|Any CPU.Build.0 = Release|Any CPU
{FDFB9C25-552D-420B-9D4A-DB0BB6472239}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FDFB9C25-552D-420B-9D4A-DB0BB6472239}.Release|Any CPU.Build.0 = Release|Any CPU
{A7644C3B-B843-44F1-9940-560D56CB0936}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{A7644C3B-B843-44F1-9940-560D56CB0936}.Debug|Any CPU.Build.0 = Release|Any CPU
{A7644C3B-B843-44F1-9940-560D56CB0936}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7644C3B-B843-44F1-9940-560D56CB0936}.Release|Any CPU.Build.0 = Release|Any CPU
{742C3613-514C-4D6B-804A-2A7925F278F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{742C3613-514C-4D6B-804A-2A7925F278F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{742C3613-514C-4D6B-804A-2A7925F278F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{742C3613-514C-4D6B-804A-2A7925F278F3}.Release|Any CPU.Build.0 = Release|Any CPU
{98A16FFD-0C99-4665-AC64-DC17E86879A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98A16FFD-0C99-4665-AC64-DC17E86879A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98A16FFD-0C99-4665-AC64-DC17E86879A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98A16FFD-0C99-4665-AC64-DC17E86879A2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -707,9 +698,7 @@ Global
{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}
{E2999E4A-9086-401F-898C-AEB0AD38E676} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{050CC912-FF49-4A8B-B534-9544017446DD} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
{F40FC0A2-1BC3-401C-BFC1-928EC4D4A9CE} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{E1240B49-7B4B-4371-A00E-068778C5CF0B} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{D49233F8-F29C-47DD-9975-C4C9E4502720} = {E870DCD7-F46A-498D-83FC-D0FD13E0A11C}
{3C471044-3640-45E3-B1B2-16D2FF8399EE} = {E870DCD7-F46A-498D-83FC-D0FD13E0A11C}
@ -763,8 +752,10 @@ Global
{342D2657-2F84-493C-B74B-9D2CAE5D9DAB} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{26918642-829D-4FA2-B60A-BE8D83F4E063} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{11522B0D-BF31-42D5-8FC5-41E58F319AF9} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{A7644C3B-B843-44F1-9940-560D56CB0936} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
{FDFB9C25-552D-420B-9D4A-DB0BB6472239} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
{A7644C3B-B843-44F1-9940-560D56CB0936} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
{742C3613-514C-4D6B-804A-2A7925F278F3} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B}
{98A16FFD-0C99-4665-AC64-DC17E86879A2} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}

76
Directory.Packages.props

@ -0,0 +1,76 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Appium.WebDriver" Version="5.2.0" />
<PackageVersion Include="Avalonia.Angle.Windows.Natives" Version="2.1.25547.20250602" />
<PackageVersion Include="Avalonia.BuildServices" Version="11.3.2" />
<PackageVersion Include="AvaloniaUI.DiagnosticsSupport" Version="2.2.0-beta2" />
<PackageVersion Include="BenchmarkDotNet" Version="0.15.6" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageVersion Include="Dotnet.Bundle" Version="0.9.13" />
<PackageVersion Include="GtkSharp" Version="3.24.24.95" />
<PackageVersion Include="HarfBuzzSharp" Version="8.3.1.2" />
<PackageVersion Include="HarfBuzzSharp.NativeAssets.Linux" Version="8.3.1.2" />
<PackageVersion Include="HarfBuzzSharp.NativeAssets.WebAssembly" Version="8.3.1.2" />
<PackageVersion Include="MicroCom.CodeGenerator" Version="0.11.0" />
<PackageVersion Include="MicroCom.CodeGenerator.MSBuild" Version="0.11.0" />
<PackageVersion Include="MicroCom.Runtime" Version="0.11.0" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.10" />
<PackageVersion Include="Microsoft.Build.Framework" Version="18.0.2" />
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="15.1.548" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.5.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.VisualBasic" Version="4.5.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="4.5.0" />
<PackageVersion Include="Microsoft.CSharp" Version="4.5.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageVersion Include="Microsoft.Reactive.Testing" Version="6.1.0" />
<PackageVersion Include="Microsoft.Testing.Extensions.TrxReport" Version="2.0.2" />
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.3.257" />
<PackageVersion Include="Mono.Cecil" Version="0.11.6" />
<PackageVersion Include="MonoMac.NetStandard" Version="0.0.4" />
<PackageVersion Include="Moq" Version="4.20.72" />
<PackageVersion Include="Nito.AsyncEx.Context" Version="5.1.2" />
<PackageVersion Include="NuGet.Protocol" Version="7.0.1" />
<PackageVersion Include="Nuke.Common" Version="10.1.0" />
<PackageVersion Include="NUnit" Version="4.4.0" />
<PackageVersion Include="NUnit3TestAdapter" Version="6.1.0" />
<PackageVersion Include="Quamotion.RemoteViewing" Version="1.1.211" />
<PackageVersion Include="SharpCompress" Version="0.41.0" />
<PackageVersion Include="Silk.NET.Direct3D.Compilers" Version="2.22.0" />
<PackageVersion Include="Silk.NET.Direct3D11" Version="2.22.0" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.22.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.22.0" />
<PackageVersion Include="SixLabors.ImageSharp" Version="2.1.12" />
<PackageVersion Include="SkiaSharp" Version="3.119.1" />
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="3.119.1" />
<PackageVersion Include="SkiaSharp.NativeAssets.WebAssembly" Version="3.119.1" />
<PackageVersion Include="System.ComponentModel.Annotations" Version="4.5.0" />
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="9.0.10" />
<PackageVersion Include="System.Memory" Version="4.5.5" />
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
<PackageVersion Include="System.Numerics.Vectors" Version="4.6.1" />
<PackageVersion Include="System.Reactive" Version="6.1.0" />
<PackageVersion Include="System.Reflection.Emit" Version="4.7.0" />
<PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.1.2" />
<PackageVersion Include="System.Text.Json" Version="10.0.0" />
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageVersion Include="Tmds.DBus.Protocol" Version="0.21.2" />
<PackageVersion Include="Tmds.DBus.SourceGenerator" Version="0.0.22" />
<PackageVersion Include="Xamarin.AndroidX.AppCompat" Version="1.7.1.1" />
<PackageVersion Include="Xamarin.AndroidX.Core.SplashScreen" Version="1.2.0" />
<PackageVersion Include="Xamarin.AndroidX.Window" Version="1.5.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageVersion Include="Xunit.StaFact" Version="3.0.13" />
<PackageVersion Include="xunit.v3.extensibility.core" Version="3.2.1" />
<PackageVersion Include="xunit.v3.mtp-v2" Version="3.2.1" />
</ItemGroup>
<ItemGroup>
<GlobalPackageReference Include="Microsoft.VisualStudio.SlnGen" Version="8.5.17" PrivateAssets="all" />
</ItemGroup>
</Project>

24
NOTICE.md

@ -26,30 +26,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# SharpDX
https://github.com/sharpdx/SharpDX
Copyright (c) 2010-2014 SharpDX - Alexandre Mutel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# Silverlight Toolkit
https://github.com/microsoftarchive/SilverlightToolkit

6
NuGet.Config

@ -8,6 +8,12 @@
</packageSources>
<packageSourceMapping>
<clear />
<packageSource key="api.nuget.org">
<package pattern="*" />
</packageSource>
<packageSource key="azure-dotnet10-transport">
<package pattern="Microsoft.DotNet.ApiDiff.Tool" />
</packageSource>
</packageSourceMapping>
<auditSources>
<clear />

12
api/Avalonia.Android.nupkg.xml

@ -7,6 +7,18 @@
<Left>baseline/Avalonia.Android/lib/net10.0-android36.0/Avalonia.Android.dll</Left>
<Right>current/Avalonia.Android/lib/net10.0-android36.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Android.AvaloniaMainActivity.CreateAppBuilder</Target>
<Left>baseline/Avalonia.Android/lib/net10.0-android36.0/Avalonia.Android.dll</Left>
<Right>current/Avalonia.Android/lib/net10.0-android36.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Android.AvaloniaMainActivity.CustomizeAppBuilder(Avalonia.AppBuilder)</Target>
<Left>baseline/Avalonia.Android/lib/net10.0-android36.0/Avalonia.Android.dll</Left>
<Right>current/Avalonia.Android/lib/net10.0-android36.0/Avalonia.Android.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0008</DiagnosticId>
<Target>T:Avalonia.Android.AvaloniaActivity</Target>

12
api/Avalonia.Skia.nupkg.xml

@ -25,12 +25,24 @@
<Left>baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Skia.Helpers.DrawingContextHelper.WrapSkiaCanvas(SkiaSharp.SKCanvas,Avalonia.Vector)</Target>
<Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession</Target>
<Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Skia.Helpers.DrawingContextHelper.WrapSkiaCanvas(SkiaSharp.SKCanvas,Avalonia.Vector)</Target>
<Left>baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession</Target>

758
api/Avalonia.nupkg.xml

File diff suppressed because it is too large

2
build/AnalyzerProject.targets

@ -8,7 +8,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0" PrivateAssets="all"/>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" PrivateAssets="all"/>
</ItemGroup>
</Project>

6
build/Base.props

@ -1,8 +1,8 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- '!NET8_0_OR_GREATER' equivalent -->
<ItemGroup Condition="!('$(TargetFrameworkIdentifier)' == '.NETCoreApp' AND $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '8.0')))">
<PackageReference Include="System.Memory" Version="4.5.5" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.10" />
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="9.0.10" />
<PackageReference Include="System.Memory" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" />
<PackageReference Include="System.Diagnostics.DiagnosticSource" />
</ItemGroup>
</Project>

5
build/Binding.props

@ -1,5 +0,0 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net6.0'))">
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
</ItemGroup>
</Project>

6
build/HarfBuzzSharp.props

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

5
build/ImageSharp.props

@ -1,5 +0,0 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.12" />
</ItemGroup>
</Project>

3
build/LegacyProject.targets

@ -1,3 +0,0 @@
<Project>
<Target Name="Pack" />
</Project>

5
build/Microsoft.CSharp.props

@ -1,5 +0,0 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
</ItemGroup>
</Project>

5
build/Microsoft.Reactive.Testing.props

@ -1,5 +0,0 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="Microsoft.Reactive.Testing" Version="6.1.0" />
</ItemGroup>
</Project>

5
build/Moq.props

@ -1,5 +0,0 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="Moq" Version="4.20.72" />
</ItemGroup>
</Project>

4
build/NetCore.props

@ -1,4 +0,0 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
</ItemGroup>
</Project>

6
build/NetFX.props

@ -1,6 +0,0 @@
<Project>
<ItemGroup>
</ItemGroup>
</Project>

5
build/Rx.props

@ -1,5 +0,0 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="System.Reactive" Version="6.1.0" />
</ItemGroup>
</Project>

2
build/SampleApp.props

@ -14,7 +14,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="AvaloniaUI.DiagnosticsSupport" Version="2.1.1" />
<PackageReference Include="AvaloniaUI.DiagnosticsSupport" />
</ItemGroup>
<Target Name="GatherReferences" AfterTargets="CoreCompile">

14
build/SharpDX.props

@ -1,14 +0,0 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SharpDXPackageVersion>4.0.1</SharpDXPackageVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SharpDX" Version="$(SharpDXPackageVersion)" />
<PackageReference Include="SharpDX.Direct2D1" Version="$(SharpDXPackageVersion)" />
<PackageReference Include="SharpDX.Direct3D11" Version="$(SharpDXPackageVersion)" />
<PackageReference Include="SharpDX.DXGI" Version="$(SharpDXPackageVersion)" />
<PackageReference Include="SharpDX.Direct3D9" Version="$(SharpDXPackageVersion)" Condition="'$(UseDirect3D9)' == 'true'" />
<PackageReference Include="SharpDX.D3DCompiler" Version="$(SharpDXPackageVersion)" Condition="'$(UseD3DCompiler)' == 'true'" />
<PackageReference Include="SharpDX.Mathematics" Version="$(SharpDXPackageVersion)" Condition="'$(UseSharpDXMathematics)' == 'true'" />
</ItemGroup>
</Project>

6
build/SkiaSharp.props

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

1
build/UnitTests.NetFX.props

@ -1,5 +1,4 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildThisFileDirectory)/NetFX.props" />
<ItemGroup Condition="$(TargetFramework.StartsWith('net4'))">
<Content Include="$(MSBuildThisFileDirectory)/xunit.runner.mono.json" Link="xunit.runner.json" >
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

2
build/XUnit.props

@ -1,7 +1,7 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="xunit.v3.mtp-v2" Version="3.2.1" />
<PackageReference Include="xunit.v3.mtp-v2" />
</ItemGroup>
<PropertyGroup>

6
build/readme.md

@ -4,12 +4,6 @@
<Import Project="..\..\build\JetBrains.Annotations.props" />
<Import Project="..\..\build\JetBrains.dotMemoryUnit.props" />
<Import Project="..\..\build\Magick.NET-Q16-AnyCPU.props" />
<Import Project="..\..\build\Microsoft.CSharp.props" />
<Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
<Import Project="..\..\build\Moq.props" />
<Import Project="..\..\build\NetCore.props" />
<Import Project="..\..\build\Rx.props" />
<Import Project="..\..\build\SharpDX.props" />
<Import Project="..\..\build\SkiaSharp.Desktop.props" />
<Import Project="..\..\build\SkiaSharp.props" />
<Import Project="..\..\build\Splat.props" />

3
dirs.proj

@ -22,7 +22,4 @@
<ProjectReference Remove="src/iOS/**/*.*proj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.SlnGen" Version="8.5.17" PrivateAssets="all" />
</ItemGroup>
</Project>

1
external/Avalonia.DBus

@ -0,0 +1 @@
Subproject commit f91a822c258476f185e51112388775591e6ef9d6

2
external/XamlX

@ -1 +1 @@
Subproject commit c32d3040e536ae9768233ea5a445697632578bd0
Subproject commit 009d4815470cf4bf71d1adbb633a5d81dcb2bb52

60
native/Avalonia.Native/src/OSX/StorageProvider.mm

@ -148,8 +148,23 @@ public:
[fileUri stopAccessingSecurityScopedResource];
}
}
static NSWindow* GetEffectiveNSWindow(IAvnTopLevel* topLevel)
{
auto windowHolder = dynamic_cast<INSWindowHolder*>(topLevel);
if (windowHolder != nullptr)
return windowHolder->GetNSWindow();
auto viewHolder = dynamic_cast<INSViewHolder*>(topLevel);
if (viewHolder != nullptr) {
auto view = (NSView*)viewHolder->GetNSView();
return [view window];
}
return nullptr;
}
virtual void SelectFolderDialog (IAvnWindow* parentWindowHandle,
virtual void SelectFolderDialog (IAvnTopLevel* parentTopLevel,
IAvnSystemDialogEvents* events,
bool allowMultiple,
const char* title,
@ -176,6 +191,8 @@ public:
panel.directoryURL = [NSURL URLWithString:directoryString];
}
auto parentWindow = GetEffectiveNSWindow(parentTopLevel);
auto handler = ^(NSModalResponse result) {
if(result == NSFileHandlingPanelOKButton)
{
@ -188,10 +205,9 @@ public:
[panel orderOut:panel];
if(parentWindowHandle != nullptr)
if (parentWindow != nullptr)
{
auto windowHolder = dynamic_cast<INSWindowHolder*>(parentWindowHandle);
[windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()];
[parentWindow makeKeyAndOrderFront:parentWindow];
}
return;
@ -202,11 +218,9 @@ public:
};
if(parentWindowHandle != nullptr)
if (parentWindow != nullptr)
{
auto windowBase = dynamic_cast<INSWindowHolder*>(parentWindowHandle);
[panel beginSheetModalForWindow:windowBase->GetNSWindow() completionHandler:handler];
[panel beginSheetModalForWindow:parentWindow completionHandler:handler];
}
else
{
@ -215,7 +229,7 @@ public:
}
}
virtual void OpenFileDialog (IAvnWindow* parentWindowHandle,
virtual void OpenFileDialog (IAvnTopLevel* parentTopLevel,
IAvnSystemDialogEvents* events,
bool allowMultiple,
const char* title,
@ -249,6 +263,8 @@ public:
panel.directoryURL = [NSURL URLWithString:directoryString];
}
auto parentWindow = GetEffectiveNSWindow(parentTopLevel);
auto handler = ^(NSModalResponse result) {
if(result == NSFileHandlingPanelOKButton)
{
@ -261,10 +277,9 @@ public:
[panel orderOut:panel];
if(parentWindowHandle != nullptr)
if (parentWindow != nullptr)
{
auto windowHolder = dynamic_cast<INSWindowHolder*>(parentWindowHandle);
[windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()];
[parentWindow makeKeyAndOrderFront:parentWindow];
}
return;
@ -275,11 +290,9 @@ public:
};
if(parentWindowHandle != nullptr)
if (parentWindow != nullptr)
{
auto windowHolder = dynamic_cast<INSWindowHolder*>(parentWindowHandle);
[panel beginSheetModalForWindow:windowHolder->GetNSWindow() completionHandler:handler];
[panel beginSheetModalForWindow:parentWindow completionHandler:handler];
}
else
{
@ -288,7 +301,7 @@ public:
}
}
virtual void SaveFileDialog (IAvnWindow* parentWindowHandle,
virtual void SaveFileDialog (IAvnTopLevel* parentTopLevel,
IAvnSystemDialogEvents* events,
const char* title,
const char* initialDirectory,
@ -319,6 +332,8 @@ public:
panel.directoryURL = [NSURL URLWithString:directoryString];
}
auto parentWindow = GetEffectiveNSWindow(parentTopLevel);
auto handler = ^(NSModalResponse result) {
int selectedIndex = -1;
if (panel.accessoryView != nil)
@ -339,10 +354,9 @@ public:
[panel orderOut:panel];
if(parentWindowHandle != nullptr)
if (parentWindow != nullptr)
{
auto windowHolder = dynamic_cast<INSWindowHolder*>(parentWindowHandle);
[windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()];
[parentWindow makeKeyAndOrderFront:parentWindow];
}
return;
@ -352,11 +366,9 @@ public:
};
if(parentWindowHandle != nullptr)
if (parentWindow != nullptr)
{
auto windowBase = dynamic_cast<INSWindowHolder*>(parentWindowHandle);
[panel beginSheetModalForWindow:windowBase->GetNSWindow() completionHandler:handler];
[panel beginSheetModalForWindow:parentWindow completionHandler:handler];
}
else
{

12
native/Avalonia.Native/src/OSX/app.mm

@ -1,11 +1,13 @@
#include "common.h"
#include "AvnString.h"
#include "menu.h"
@interface AvnAppDelegate : NSObject<NSApplicationDelegate>
-(AvnAppDelegate* _Nonnull) initWithEvents: (IAvnApplicationEvents* _Nonnull) events;
-(void) releaseEvents;
@end
NSApplicationActivationPolicy AvnDesiredActivationPolicy = NSApplicationActivationPolicyRegular;
static NSMenu* s_dockMenu = nil;
@implementation AvnAppDelegate
ComPtr<IAvnApplicationEvents> _events;
@ -86,6 +88,11 @@ ComPtr<IAvnApplicationEvents> _events;
return _events->TryShutdown() ? NSTerminateNow : NSTerminateCancel;
}
- (NSMenu *)applicationDockMenu:(NSApplication *)sender
{
return s_dockMenu;
}
@end
@interface AvnApplication : NSApplication
@ -180,3 +187,8 @@ extern IAvnApplicationCommands* CreateApplicationCommands()
{
return new AvnApplicationCommands();
}
extern void SetDockMenu(NSMenu* menu)
{
s_dockMenu = menu;
}

5
native/Avalonia.Native/src/OSX/automation.mm

@ -220,6 +220,11 @@
return GetNSStringAndRelease(_peer->GetHelpText());
}
- (NSString *)accessibilityPlaceholderValue
{
return GetNSStringAndRelease(_peer->GetPlaceholderText());
}
- (id)accessibilityValue
{
if (_peer->IsRangeValueProvider())

1
native/Avalonia.Native/src/OSX/common.h

@ -38,6 +38,7 @@ extern void SetAppMenu(IAvnMenu *menu);
extern void SetServicesMenu (IAvnMenu* menu);
extern IAvnMenu* GetAppMenu ();
extern NSMenuItem* GetAppMenuItem ();
extern void SetDockMenu(NSMenu* menu);
extern void InitializeAvnApp(IAvnApplicationEvents* events, bool disableAppDelegate);
extern void ReleaseAvnAppEvents();

19
native/Avalonia.Native/src/OSX/main.mm

@ -1,6 +1,7 @@
//This file will contain actual IID structures
#define COM_GUIDS_MATERIALIZE
#include "common.h"
#include "menu.h"
static NSString* s_appTitle = @"Avalonia";
static int disableSetProcessName = 0;
@ -475,14 +476,24 @@ public:
return *ppv != nullptr ? S_OK : E_FAIL;
}
HRESULT CreateMemoryManagementHelper(IAvnNativeObjectsMemoryManagement **ppv) override {
HRESULT CreateMemoryManagementHelper(IAvnNativeObjectsMemoryManagement **ppv) override {
START_COM_CALL;
*ppv = ::CreateMemoryManagementHelper();
return S_OK;
}
virtual HRESULT SetDockMenu(IAvnMenu* dockMenu) override
{
START_COM_CALL;
@autoreleasepool
{
auto nativeMenu = dynamic_cast<AvnAppMenu*>(dockMenu);
::SetDockMenu(nativeMenu != nullptr ? nativeMenu->GetNative() : nil);
return S_OK;
}
}
};
extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative()

10
nukebuild/_build.csproj

@ -10,12 +10,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Nuke.Common" Version="10.1.0" />
<PackageReference Include="MicroCom.CodeGenerator" Version="0.11.0" />
<PackageReference Include="Nuke.Common" />
<PackageReference Include="MicroCom.CodeGenerator" />
<!-- Keep in sync with Avalonia.Build.Tasks -->
<PackageReference Include="Mono.Cecil" Version="0.11.6" />
<PackageReference Include="Microsoft.Build.Framework" Version="18.0.2" PrivateAssets="All" />
<PackageReference Include="NuGet.Protocol" Version="7.0.1" />
<PackageReference Include="Mono.Cecil" />
<PackageReference Include="Microsoft.Build.Framework" PrivateAssets="All" />
<PackageReference Include="NuGet.Protocol" />
<PackageDownload Include="Microsoft.DotNet.ApiCompat.Tool" Version="[10.0.100]" />
<PackageDownload Include="Microsoft.DotNet.ApiDiff.Tool" Version="[10.0.100-rtm.25531.102]" />
<PackageDownload Include="dotnet-ilrepack" Version="[2.0.44]" />

3
packages/Avalonia/Avalonia.csproj

@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia.BuildServices" Version="11.3.2" />
<PackageReference Include="Avalonia.BuildServices" />
<ProjectReference Include="../../src/Avalonia.Remote.Protocol/Avalonia.Remote.Protocol.csproj" />
<ProjectReference Include="../../src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj"
PrivateAssets="all" />
@ -71,7 +71,6 @@
</Content>
</ItemGroup>
<Import Project="..\..\build\SharedVersion.props" />
<Import Project="..\..\build\NetFX.props" />
<Import Project="..\..\build\CoreLibraries.props" />
<Import Project="..\..\build\SourceLink.props" Condition="'$(DisableSourceLink)' == ''" />

5
samples/BindingDemo/BindingDemo.csproj

@ -10,10 +10,11 @@
<ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" />
<ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Reactive" />
</ItemGroup>
<Import Project="..\..\build\SampleApp.props" />
<Import Project="..\..\build\EmbedXaml.props" />
<Import Project="..\..\build\Rx.props" />
<Import Condition="'$(TargetFramework)'=='net461'" Project="..\..\build\NetFX.props" />
<Import Project="..\..\build\ReferenceCoreLibraries.props" />
<Import Project="..\..\build\BuildTargets.targets" />
</Project>

2
samples/ControlCatalog.Android/ControlCatalog.Android.csproj

@ -25,7 +25,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Xamarin.AndroidX.Core.SplashScreen" Version="1.2.0" />
<PackageReference Include="Xamarin.AndroidX.Core.SplashScreen" />
</ItemGroup>
<ItemGroup>

2
samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj

@ -26,7 +26,7 @@
<ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" />
<ProjectReference Include="..\..\src\Avalonia.X11\Avalonia.X11.csproj" />
<!-- For native controls test -->
<PackageReference Include="MonoMac.NetStandard" Version="0.0.4" />
<PackageReference Include="MonoMac.NetStandard" />
</ItemGroup>
<PropertyGroup>

9
samples/ControlCatalog/App.xaml

@ -59,6 +59,15 @@
<Setter Property="FontSize" Value="12" />
</Style>
</Application.Styles>
<NativeDock.Menu>
<NativeMenu>
<NativeMenuItem Header="New Window" Click="OnDockNewWindowClicked"/>
<NativeMenuItemSeparator/>
<NativeMenuItem Header="Show Main Window" Click="OnDockShowMainWindowClicked"/>
<NativeMenuItemSeparator/>
<NativeMenuItem Header="Add Dock Menu Item" Click="OnDockAddItemClicked"/>
</NativeMenu>
</NativeDock.Menu>
<TrayIcon.Icons>
<TrayIcons>
<TrayIcon Icon="/Assets/test_icon.ico" MacOSProperties.IsTemplateIcon="true" ToolTipText="Avalonia Tray Icon ToolTip">

34
samples/ControlCatalog/App.xaml.cs

@ -64,6 +64,40 @@ namespace ControlCatalog
base.OnFrameworkInitializationCompleted();
}
public void OnDockNewWindowClicked(object? sender, EventArgs e)
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime)
{
var window = new MainWindow();
window.Show();
}
}
public void OnDockShowMainWindowClicked(object? sender, EventArgs e)
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktopLifetime)
{
desktopLifetime.MainWindow?.Activate();
}
}
private int _dockMenuItemCount;
public void OnDockAddItemClicked(object? sender, EventArgs e)
{
var dockMenu = NativeDock.GetMenu(this);
if (dockMenu is not null)
{
_dockMenuItemCount++;
var item = new NativeMenuItem($"New item {_dockMenuItemCount}");
item.Click += (_, _) =>
{
dockMenu.Items.Remove(item);
};
dockMenu.Items.Insert(0, item);
}
}
private CatalogTheme _prevTheme;
public static CatalogTheme CurrentTheme => ((App)Current!)._prevTheme;
public static void SetCatalogThemes(CatalogTheme theme)

18
samples/ControlCatalog/MainView.xaml

@ -215,7 +215,8 @@
<ComboBox x:Name="Decorations"
HorizontalAlignment="Stretch"
SelectedIndex="0"
SelectionChanged="Decorations_SelectionChanged">
SelectionChanged="Decorations_SelectionChanged"
ToolTip.Tip="System Decorations">
<ComboBox.Items>
<SystemDecorations>None</SystemDecorations>
<SystemDecorations>BorderOnly</SystemDecorations>
@ -225,7 +226,8 @@
<ComboBox HorizontalAlignment="Stretch"
DisplayMemberBinding="{Binding Key, x:DataType=ThemeVariant}"
SelectedIndex="0"
SelectionChanged="ThemeVariants_SelectionChanged">
SelectionChanged="ThemeVariants_SelectionChanged"
ToolTip.Tip="Theme Variant">
<ComboBox.Items>
<ThemeVariant>Default</ThemeVariant>
<ThemeVariant>Light</ThemeVariant>
@ -234,7 +236,8 @@
</ComboBox>
<ComboBox HorizontalAlignment="Stretch"
SelectedItem="{x:Static local:App.CurrentTheme}"
SelectionChanged="Themes_SelectionChanged">
SelectionChanged="Themes_SelectionChanged"
ToolTip.Tip="Catalog Theme">
<ComboBox.Items>
<models:CatalogTheme>Fluent</models:CatalogTheme>
<models:CatalogTheme>Simple</models:CatalogTheme>
@ -242,7 +245,8 @@
</ComboBox>
<ComboBox HorizontalAlignment="Stretch"
SelectedIndex="0"
SelectionChanged="TransparencyLevels_SelectionChanged">
SelectionChanged="TransparencyLevels_SelectionChanged"
ToolTip.Tip="Window Transparency Level">
<ComboBox.Items>
<WindowTransparencyLevel>None</WindowTransparencyLevel>
<WindowTransparencyLevel>Transparent</WindowTransparencyLevel>
@ -253,7 +257,8 @@
</ComboBox>
<ComboBox HorizontalAlignment="Stretch"
SelectedIndex="0"
SelectionChanged="FlowDirection_SelectionChanged">
SelectionChanged="FlowDirection_SelectionChanged"
ToolTip.Tip="Flow Direction">
<ComboBox.Items>
<FlowDirection>LeftToRight</FlowDirection>
<FlowDirection>RightToLeft</FlowDirection>
@ -261,7 +266,8 @@
</ComboBox>
<ComboBox HorizontalAlignment="Stretch"
ItemsSource="{Binding WindowStates}"
SelectedItem="{Binding WindowState}" />
SelectedItem="{Binding WindowState}"
ToolTip.Tip="Window State"/>
</StackPanel>
</Flyout>
</FlyoutBase.AttachedFlyout>

4
samples/ControlCatalog/MainView.xaml.cs

@ -45,7 +45,7 @@ namespace ControlCatalog
private void Decorations_SelectionChanged(object? sender, SelectionChangedEventArgs e)
{
if (VisualRoot is Window window && e.AddedItems.Count > 0 && e.AddedItems[0] is SystemDecorations systemDecorations)
if (TopLevel.GetTopLevel(this) is Window window && e.AddedItems.Count > 0 && e.AddedItems[0] is SystemDecorations systemDecorations)
{
window.SystemDecorations = systemDecorations;
}
@ -78,7 +78,7 @@ namespace ControlCatalog
{
base.OnAttachedToVisualTree(e);
if (VisualRoot is Window window)
if (TopLevel.GetTopLevel(this) is Window window)
Decorations.SelectedIndex = (int)window.SystemDecorations;
var insets = TopLevel.GetTopLevel(this)!.InsetsManager;

36
samples/ControlCatalog/Pages/AdornerLayerPage.xaml

@ -44,21 +44,31 @@
VerticalContentAlignment="Center" VerticalAlignment="Stretch"
Width="200" Height="42">
<AdornerLayer.Adorner>
<Canvas x:Name="AdornerCanvas"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Cyan"
IsHitTestVisible="False"
Opacity="0.3"
IsVisible="True"
AdornerLayer.IsClipEnabled="False">
<Line StartPoint="-10000,0" EndPoint="10000,0" Stroke="Cyan" StrokeThickness="1" />
<Line StartPoint="-10000,42" EndPoint="10000,42" Stroke="Cyan" StrokeThickness="1" />
<Line StartPoint="0,-10000" EndPoint="0,10000" Stroke="Cyan" StrokeThickness="1" />
<Line StartPoint="200,-10000" EndPoint="200,10000" Stroke="Cyan" StrokeThickness="1" />
</Canvas>
<Border AdornerLayer.IsClipEnabled="False" ClipToBounds="False" Background="Red" Opacity="0.3" Margin="-5" Padding="5"
IsHitTestVisible="False">
<Canvas
x:Name="AdornerCanvas"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Cyan"
IsHitTestVisible="False"
IsVisible="True"
AdornerLayer.IsClipEnabled="False">
<Line StartPoint="-10000,0" EndPoint="10000,0" Stroke="Cyan" StrokeThickness="1" />
<Line StartPoint="-10000,42" EndPoint="10000,42" Stroke="Cyan" StrokeThickness="1" />
<Line StartPoint="0,-10000" EndPoint="0,10000" Stroke="Cyan" StrokeThickness="1" />
<Line StartPoint="200,-10000" EndPoint="200,10000" Stroke="Cyan" StrokeThickness="1" />
</Canvas>
</Border>
</AdornerLayer.Adorner>
<Button.ContextMenu>
<ContextMenu PlacementTarget="{ResolveByName AdornerCanvas}" Placement="TopEdgeAlignedLeft">
<MenuItem Header="Menu 1"/>
<MenuItem Header="Menu 2"/>
</ContextMenu>
</Button.ContextMenu>
</Button>
</LayoutTransformControl>
</Grid>

4
samples/ControlCatalog/Pages/GesturePage.cs

@ -134,8 +134,8 @@ namespace ControlCatalog.Pages
var currentSize = control.Bounds.Size * _currentScale;
currentOffset = new Vector3D(MathUtilities.Clamp(currentOffset.X, 0, currentSize.Width - control.Bounds.Width),
(float)MathUtilities.Clamp(currentOffset.Y, 0, currentSize.Height - control.Bounds.Height),
currentOffset = new Vector3D(Math.Clamp(currentOffset.X, 0, currentSize.Width - control.Bounds.Width),
(float)Math.Clamp(currentOffset.Y, 0, currentSize.Height - control.Bounds.Height),
0);
compositionVisual.Offset = currentOffset * -1;

2
samples/ControlCatalog/ViewModels/ContextPageViewModel.cs

@ -49,7 +49,7 @@ namespace ControlCatalog.ViewModels
public async Task Open()
{
var window = View?.GetVisualRoot() as Window;
var window = TopLevel.GetTopLevel(View) as Window;
if (window == null)
return;

2
samples/ControlCatalog/ViewModels/MenuPageViewModel.cs

@ -69,7 +69,7 @@ namespace ControlCatalog.ViewModels
public async Task Open()
{
var window = View?.GetVisualRoot() as Window;
var window = TopLevel.GetTopLevel(View) as Window;
if (window == null)
return;
var result = await window.StorageProvider.OpenFilePickerAsync(new Avalonia.Platform.Storage.FilePickerOpenOptions() { AllowMultiple = true });

2
samples/Generators.Sandbox/Generators.Sandbox.csproj

@ -20,7 +20,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="CommunityToolkit.Mvvm" />
</ItemGroup>
<Import Project="..\..\build\BuildTargets.targets"/>

6
samples/GpuInterop/DrawingSurfaceDemoBase.cs

@ -71,12 +71,12 @@ public abstract class DrawingSurfaceDemoBase : Control, IGpuDemo
void UpdateFrame()
{
_updateQueued = false;
var root = this.GetVisualRoot();
if (root == null)
var source = this.GetPresentationSource();
if (source == null)
return;
_visual!.Size = new (Bounds.Width, Bounds.Height);
var size = PixelSize.FromSize(Bounds.Size, root.RenderScaling);
var size = PixelSize.FromSize(Bounds.Size, source.RenderScaling);
RenderFrame(size);
if (SupportsDisco && Disco > 0)
QueueNextFrame();

12
samples/GpuInterop/GpuInterop.csproj

@ -27,13 +27,13 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Silk.NET.Direct3D11" Version="2.22.0" />
<PackageReference Include="Silk.NET.Direct3D.Compilers" Version="2.22.0" />
<PackageReference Include="Silk.NET.Vulkan" Version="2.22.0" />
<PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.22.0" />
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.22.0" />
<PackageReference Include="Silk.NET.Direct3D11" />
<PackageReference Include="Silk.NET.Direct3D.Compilers" />
<PackageReference Include="Silk.NET.Vulkan" />
<PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" />
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" />
<!-- Silk.NET 2.22 targets an obsolete System.Text.Json, update to avoid warnings. -->
<PackageReference Include="System.Text.Json" Version="10.0.0" />
<PackageReference Include="System.Text.Json" />
</ItemGroup>
<ItemGroup>

7
samples/IntegrationTestApp/App.axaml

@ -7,6 +7,13 @@
<Application.Styles>
<FluentTheme />
</Application.Styles>
<NativeDock.Menu>
<NativeMenu>
<NativeMenuItem Header="Show Main Window"
Command="{Binding DockMenuCommand}"
CommandParameter="DockMenuShowMainWindow"/>
</NativeMenu>
</NativeDock.Menu>
<TrayIcon.Icons>
<TrayIcons>
<TrayIcon Icon="/Assets/icon.ico"

25
samples/IntegrationTestApp/App.axaml.cs

@ -1,8 +1,10 @@
using System.Linq;
using System.Windows.Input;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.LogicalTree;
using Avalonia.Markup.Xaml;
using MiniMvvm;
@ -18,6 +20,13 @@ namespace IntegrationTestApp
{
_mainWindow!.Get<CheckBox>(name).IsChecked = true;
});
DockMenuCommand = MiniCommand.Create<string>(name =>
{
// This is for the "Show Main Window" dock menu item in the test.
// It doesn't actually show the main window, but sets the checkbox to true in the page.
var checkbox = _mainWindow!.GetLogicalDescendants().OfType<CheckBox>().FirstOrDefault(x => x.Name == name);
if (checkbox != null) checkbox.IsChecked = true;
});
DataContext = this;
}
@ -37,5 +46,21 @@ namespace IntegrationTestApp
}
public ICommand TrayIconCommand { get; }
public ICommand DockMenuCommand { get; }
public void AddDockMenuItem(string header)
{
var dockMenu = NativeDock.GetMenu(this);
if (dockMenu is not null)
{
dockMenu.Items.Insert(0, new NativeMenuItem(header));
}
}
public int GetDockMenuItemCount()
{
var dockMenu = NativeDock.GetMenu(this);
return dockMenu?.Items.Count ?? 0;
}
}
}

4
samples/IntegrationTestApp/IntegrationTestApp.csproj

@ -19,8 +19,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Dotnet.Bundle" Version="0.9.13" />
<PackageReference Include="MonoMac.NetStandard" Version="0.0.4" />
<PackageReference Include="Dotnet.Bundle" />
<PackageReference Include="MonoMac.NetStandard" />
</ItemGroup>
<ItemGroup>

2
samples/IntegrationTestApp/Pages/AutomationPage.axaml

@ -10,7 +10,7 @@
TextBlockWithNameAndAutomationId
</TextBlock>
<TextBlock Name="TextBlockAsLabel">Label for TextBox</TextBlock>
<TextBox Name="LabeledByTextBox" AutomationProperties.LabeledBy="{Binding #TextBlockAsLabel}">
<TextBox Name="LabeledByTextBox" AutomationProperties.LabeledBy="{Binding #TextBlockAsLabel}" PlaceholderText="Placeholder for TextBox">
Foo
</TextBox>
<TextBlock Name="TextBlockWithHeader1" AutomationProperties.ControlTypeOverride="Header" AutomationProperties.HeadingLevel="1">

6
samples/IntegrationTestApp/Pages/DesktopPage.axaml

@ -10,5 +10,11 @@
<Button Name="ToggleTrayIconVisible"
Content="Toggle TrayIcon Visible"
Click="ToggleTrayIconVisible_Click"/>
<Separator Margin="0,8"/>
<CheckBox x:FieldModifier="public" Name="DockMenuShowMainWindow">Dock Menu Show Main Window Clicked</CheckBox>
<Button Name="AddDockMenuItem"
Content="Add Dock Menu Item"
Click="AddDockMenuItem_Click"/>
<TextBlock Name="DockMenuItemCount" Text="0"/>
</StackPanel>
</UserControl>

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

@ -6,6 +6,8 @@ namespace IntegrationTestApp.Pages;
public partial class DesktopPage : UserControl
{
private int _dockMenuItemCount;
public DesktopPage()
{
InitializeComponent();
@ -16,4 +18,12 @@ public partial class DesktopPage : UserControl
var icon = TrayIcon.GetIcons(Application.Current!)!.FirstOrDefault()!;
icon.IsVisible = !icon.IsVisible;
}
private void AddDockMenuItem_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
var app = (App)Application.Current!;
_dockMenuItemCount++;
app.AddDockMenuItem($"Dynamic Item {_dockMenuItemCount}");
DockMenuItemCount.Text = app.GetDockMenuItemCount().ToString();
}
}

4
samples/PlatformSanityChecks/PlatformSanityChecks.csproj

@ -12,5 +12,7 @@
<ProjectReference Include="..\..\src\Avalonia.X11\Avalonia.X11.csproj" />
</ItemGroup>
<Import Project="..\..\build\Rx.props" />
<ItemGroup>
<PackageReference Include="System.Reactive" />
</ItemGroup>
</Project>

5
samples/Previewer/App.xaml

@ -1,5 +0,0 @@
<Application xmlns="https://github.com/avaloniaui">
<Application.Styles>
<SimpleTheme />
</Application.Styles>
</Application>

22
samples/Previewer/App.xaml.cs

@ -1,22 +0,0 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
namespace Previewer
{
public class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
desktop.MainWindow = new MainWindow();
base.OnFrameworkInitializationCompleted();
}
}
}

19
samples/Previewer/Center.cs

@ -1,19 +0,0 @@
using Avalonia;
using Avalonia.Controls;
namespace Previewer
{
public class Center : Decorator
{
protected override Size ArrangeOverride(Size finalSize)
{
if (Child != null)
{
var desired = Child.DesiredSize;
Child.Arrange(new Rect((finalSize.Width - desired.Width) / 2, (finalSize.Height - desired.Height) / 2,
desired.Width, desired.Height));
}
return finalSize;
}
}
}

12
samples/Previewer/MainWindow.xaml

@ -1,12 +0,0 @@
<Window xmlns="https://github.com/avaloniaui" Width="600" Height="500"
Title="Previewer">
<Grid RowDefinitions="0.5*,200">
<ScrollViewer Name="Remote"/>
<ScrollViewer Name="ErrorsContainer" Background="#ffe0e0">
<TextBlock Name="Errors"/>
</ScrollViewer>
<TextBox Grid.Row="1" AcceptsReturn="True" Name="Xaml"/>
</Grid>
</Window>

86
samples/Previewer/MainWindow.xaml.cs

@ -1,86 +0,0 @@
using System;
using System.Net;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Remote;
using Avalonia.Markup.Xaml;
using Avalonia.Remote.Protocol;
using Avalonia.Remote.Protocol.Designer;
using Avalonia.Remote.Protocol.Viewport;
using Avalonia.Threading;
namespace Previewer
{
public class MainWindow : Window
{
private const string InitialXaml = @"<Window xmlns=""https://github.com/avaloniaui"" Width=""600"" Height=""500"">
<TextBlock>Hello world!</TextBlock>
</Window>";
private IAvaloniaRemoteTransportConnection? _connection;
private Control _errorsContainer;
private TextBlock _errors;
private RemoteWidget? _remote;
public MainWindow()
{
this.InitializeComponent();
var tb = this.GetControl<TextBox>("Xaml");
tb.Text = InitialXaml;
var scroll = this.GetControl<ScrollViewer>("Remote");
var rem = new Center();
scroll.Content = rem;
_errorsContainer = this.GetControl<Control>("ErrorsContainer");
_errors = this.GetControl<TextBlock>("Errors");
tb.GetObservable(TextBox.TextProperty).Subscribe(text => _connection?.Send(new UpdateXamlMessage
{
Xaml = text
}));
new BsonTcpTransport().Listen(IPAddress.Loopback, 25000, t =>
{
Dispatcher.UIThread.Post(() =>
{
if (_connection != null)
{
_connection.Dispose();
_connection.OnMessage -= OnMessage;
}
_connection = t;
rem.Child = _remote = new RemoteWidget(t);
t.Send(new UpdateXamlMessage
{
Xaml = tb.Text
});
t.OnMessage += OnMessage;
});
});
Title = "Listening on 127.0.0.1:25000";
}
private void OnMessage(IAvaloniaRemoteTransportConnection transport, object obj)
{
Dispatcher.UIThread.Post(() =>
{
if (transport != _connection)
return;
if (obj is UpdateXamlResultMessage result)
{
_errorsContainer.IsVisible = result.Error != null;
_errors.Text = result.Error ?? "";
}
if (obj is RequestViewportResizeMessage resize && _remote is not null)
{
_remote.Width = Math.Min(4096, Math.Max(resize.Width, 1));
_remote.Height = Math.Min(4096, Math.Max(resize.Height, 1));
}
});
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}

20
samples/Previewer/Previewer.csproj

@ -1,20 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>$(AvsCurrentTargetFramework)</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Update="**\*.xaml.cs">
<DependentUpon>%(Filename)</DependentUpon>
</Compile>
<EmbeddedResource Include="**\*.xaml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Fonts.Inter\Avalonia.Fonts.Inter.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Simple\Avalonia.Themes.Simple.csproj" />
</ItemGroup>
<Import Project="..\..\build\Rx.props" />
<Import Project="..\..\build\SampleApp.props" />
<Import Project="..\..\build\ReferenceCoreLibraries.props" />
</Project>

14
samples/Previewer/Program.cs

@ -1,14 +0,0 @@
using Avalonia;
namespace Previewer
{
class Program
{
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect();
public static int Main(string[] args)
=> BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
}
}

53
samples/RemoteDemo/Program.cs

@ -1,53 +0,0 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Remote;
using Avalonia.Remote.Protocol;
using Avalonia.Threading;
using ControlCatalog;
namespace RemoteDemo
{
class Program
{
static void Main(string[] args)
{
AppBuilder.Configure<App>().UsePlatformDetect().SetupWithoutStarting();
var l = new TcpListener(IPAddress.Loopback, 0);
l.Start();
var port = ((IPEndPoint) l.LocalEndpoint).Port;
l.Stop();
var transport = new BsonTcpTransport();
transport.Listen(IPAddress.Loopback, port, sc =>
{
Dispatcher.UIThread.Post(() =>
{
new RemoteServer(sc).Content = new MainView();
});
});
var cts = new CancellationTokenSource();
transport.Connect(IPAddress.Loopback, port).ContinueWith(t =>
{
Dispatcher.UIThread.Post(() =>
{
var window = new Window()
{
Content = new RemoteWidget(t.Result)
};
window.Closed += delegate { cts.Cancel(); };
window.Show();
});
});
Dispatcher.UIThread.MainLoop(cts.Token);
}
}
}

12
samples/RemoteDemo/RemoteDemo.csproj

@ -1,12 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>$(AvsCurrentTargetFramework)</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" />
</ItemGroup>
<Import Project="..\..\build\SampleApp.props" />
<Import Project="..\..\build\ReferenceCoreLibraries.props" />
<Import Project="..\..\build\BuildTargets.targets" />
</Project>

8
samples/RenderDemo/App.config

@ -9,14 +9,6 @@
<assemblyIdentity name="Mono.Cairo" publicKeyToken="0738eb9f132ed756" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="SharpDX.DXGI" publicKeyToken="b4dcf0f35e5521f1" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

5
samples/RenderDemo/RenderDemo.csproj

@ -17,10 +17,11 @@
<ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />
<ProjectReference Include="..\SampleControls\ControlSamples.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Reactive" />
</ItemGroup>
<Import Project="..\..\build\SampleApp.props" />
<Import Project="..\..\build\EmbedXaml.props" />
<Import Project="..\..\build\Rx.props" />
<Import Condition="'$(TargetFramework)'=='net461'" Project="..\..\build\NetFX.props" />
<Import Project="..\..\build\ReferenceCoreLibraries.props" />
<Import Project="..\..\build\BuildTargets.targets" />
</Project>

2
samples/XEmbedSample/XEmbedSample.csproj

@ -8,7 +8,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GtkSharp" Version="3.24.24.95"/>
<PackageReference Include="GtkSharp"/>
</ItemGroup>
<ItemGroup>

18
samples/interop/WindowsInteropTest/App.config

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="SharpDX.DXGI" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

4
src/Android/Avalonia.Android/Avalonia.Android.csproj

@ -10,8 +10,8 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\packages\Avalonia\Avalonia.csproj" />
<PackageReference Include="Xamarin.AndroidX.AppCompat" Version="1.7.1.1" />
<PackageReference Include="Xamarin.AndroidX.Window" Version="1.5.1" />
<PackageReference Include="Xamarin.AndroidX.AppCompat" />
<PackageReference Include="Xamarin.AndroidX.Window" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Avalonia.Base\Avalonia.Base.csproj" />

22
src/Android/Avalonia.Android/AvaloniaAccessHelper.cs

@ -135,10 +135,30 @@ namespace Avalonia.Android
protected override bool OnPerformActionForVirtualView(int virtualViewId, int action, Bundle? arguments)
{
return (GetNodeInfoProvidersFromVirtualViewId(virtualViewId) ?? [])
.Select(x => x.PerformNodeAction(action, arguments))
.Select(x => TryPerformNodeAction(x, action, arguments))
.Aggregate(false, (a, b) => a | b);
}
private static bool TryPerformNodeAction(INodeInfoProvider nodeInfoProvider, int action, Bundle? arguments)
{
try
{
return nodeInfoProvider.PerformNodeAction(action, arguments);
}
catch (ElementNotEnabledException)
{
return false;
}
catch (InvalidOperationException)
{
return false;
}
catch (NotSupportedException)
{
return false;
}
}
protected override void OnPopulateNodeForVirtualView(int virtualViewId, AccessibilityNodeInfoCompat? nodeInfo)
{
if (nodeInfo is null || !_peers.TryGetValue(virtualViewId, out AutomationPeer? peer))

3
src/Android/Avalonia.Android/AvaloniaMainActivity.cs

@ -44,7 +44,4 @@ public class AvaloniaMainActivity : AvaloniaActivity
activatableLifetime.CurrentMainActivity = null;
}
}
protected virtual AppBuilder CreateAppBuilder() => AppBuilder.Configure<Application>().UseAndroid();
protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder;
}

3
src/Android/Avalonia.Android/Platform/Input/AvaloniaInputConnection.cs

@ -157,8 +157,7 @@ namespace Avalonia.Android.Platform.Input
}
case ImeAction.Next:
{
FocusManager.GetFocusManager(_toplevel.InputRoot)?
.TryMoveFocus(NavigationDirection.Next);
((FocusManager?)_toplevel.InputRoot?.FocusManager)?.TryMoveFocus(NavigationDirection.Next);
break;
}
}

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

@ -8,7 +8,6 @@ using Android.Runtime;
using Android.Views;
using AndroidX.AppCompat.App;
using Avalonia.Android.Platform.Input;
using Avalonia.Android.Platform.Specific;
using Avalonia.Android.Platform.Specific.Helpers;
using Avalonia.Android.Platform.Storage;
using Avalonia.Controls;
@ -254,7 +253,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevels)
{
if (_view.Context is not AvaloniaMainActivity activity)
if (_view.Context is not AvaloniaActivity activity)
return;
foreach (var level in transparencyLevels)
@ -366,7 +365,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
return false;
}
private static void SetBlurBehind(AvaloniaMainActivity activity, int radius)
private static void SetBlurBehind(AvaloniaActivity activity, int radius)
{
if (radius == 0)
activity.Window?.ClearFlags(WindowManagerFlags.BlurBehind);

21
src/Android/Avalonia.Android/Platform/Storage/AndroidStorageItem.cs

@ -159,7 +159,7 @@ internal class AndroidStorageFolder : AndroidStorageItem, IStorageBookmarkFolder
public Task<IStorageFile?> CreateFileAsync(string name)
{
var mimeType = MimeTypeMap.Singleton?.GetMimeTypeFromExtension(MimeTypeMap.GetFileExtensionFromUrl(name)) ?? "application/octet-stream";
var treeUri = DocumentsContract.BuildDocumentUriUsingTree(Uri, DocumentsContract.GetTreeDocumentId(Uri));
var treeUri = GetTreeUri().treeUri;
var newFile = DocumentsContract.CreateDocument(Activity.ContentResolver!, treeUri!, mimeType, name);
if(newFile == null)
{
@ -171,7 +171,7 @@ internal class AndroidStorageFolder : AndroidStorageItem, IStorageBookmarkFolder
public Task<IStorageFolder?> CreateFolderAsync(string name)
{
var treeUri = DocumentsContract.BuildDocumentUriUsingTree(Uri, DocumentsContract.GetTreeDocumentId(Uri));
var treeUri = GetTreeUri().treeUri;
var newFolder = DocumentsContract.CreateDocument(Activity.ContentResolver!, treeUri!, DocumentsContract.Document.MimeTypeDir, name);
if (newFolder == null)
{
@ -207,7 +207,7 @@ internal class AndroidStorageFolder : AndroidStorageItem, IStorageBookmarkFolder
}
}
var treeUri = DocumentsContract.BuildDocumentUriUsingTree(storageFolder.Uri, DocumentsContract.GetTreeDocumentId(storageFolder.Uri));
var treeUri = GetTreeUri().treeUri;
DocumentsContract.DeleteDocument(Activity.ContentResolver!, treeUri!);
}
}
@ -230,9 +230,7 @@ internal class AndroidStorageFolder : AndroidStorageItem, IStorageBookmarkFolder
yield break;
}
var root = PermissionRoot ?? Uri;
var folderId = root != Uri ? DocumentsContract.GetDocumentId(Uri) : DocumentsContract.GetTreeDocumentId(Uri);
var childrenUri = DocumentsContract.BuildChildDocumentsUriUsingTree(root, folderId);
var (root, childrenUri) = GetTreeUri();
var projection = new[]
{
@ -311,9 +309,7 @@ internal class AndroidStorageFolder : AndroidStorageItem, IStorageBookmarkFolder
return null;
}
var root = PermissionRoot ?? Uri;
var folderId = root != Uri ? DocumentsContract.GetDocumentId(Uri) : DocumentsContract.GetTreeDocumentId(Uri);
var childrenUri = DocumentsContract.BuildChildDocumentsUriUsingTree(root, folderId);
var (root, childrenUri) = GetTreeUri();
var projection = new[]
{
@ -370,6 +366,13 @@ internal class AndroidStorageFolder : AndroidStorageItem, IStorageBookmarkFolder
var file = await GetItemAsync(name, false);
return (IStorageFile?)file;
}
private (AndroidUri root, AndroidUri? treeUri) GetTreeUri()
{
var root = PermissionRoot ?? Uri;
var folderId = root != Uri ? DocumentsContract.GetDocumentId(Uri) : DocumentsContract.GetTreeDocumentId(Uri);
return (root, DocumentsContract.BuildChildDocumentsUriUsingTree(root, folderId));
}
}
internal sealed class WellKnownAndroidStorageFolder : AndroidStorageFolder

5
src/Avalonia.Base/Avalonia.Base.csproj

@ -11,7 +11,6 @@
<AdditionalFiles Include="composition-schema.xml" />
</ItemGroup>
<Import Project="..\..\build\Base.props" />
<Import Project="..\..\build\Binding.props" />
<Import Project="..\..\build\NullableEnable.props" />
<Import Project="..\..\build\TrimmingEnable.props" />
<Import Project="..\..\build\DevAnalyzers.props" />
@ -24,6 +23,10 @@
<Compile Include="..\Shared\StreamCompatibilityExtensions.cs" Link="Compatibility\StreamCompatibilityExtensions.cs" />
</ItemGroup>
<ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net6.0'))">
<PackageReference Include="System.ComponentModel.Annotations" />
</ItemGroup>
<ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Base.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Desktop, PublicKey=$(AvaloniaPublicKey)" />

26
src/Avalonia.Base/Input/AccessKeyHandler.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
using Avalonia.LogicalTree;
using Avalonia.VisualTree;
@ -30,6 +31,12 @@ namespace Avalonia.Input
RoutingStrategies.Bubble,
typeof(AccessKeyHandler));
/// <summary>
/// Defines the ShowAccessKey attached property.
/// </summary>
public static readonly AttachedProperty<bool> ShowAccessKeyProperty =
AvaloniaProperty.RegisterAttached<AccessKeyHandler, Visual, bool>("ShowAccessKey", inherits: true);
/// <summary>
/// The registered access keys.
/// </summary>
@ -40,7 +47,7 @@ namespace Avalonia.Input
/// <summary>
/// The window to which the handler belongs.
/// </summary>
private IInputRoot? _owner;
private InputElement? _owner;
/// <summary>
/// Whether access keys are currently being shown;
@ -96,7 +103,7 @@ namespace Avalonia.Input
/// <remarks>
/// This method can only be called once, typically by the owner itself on creation.
/// </remarks>
public void SetOwner(IInputRoot owner)
public void SetOwner(InputElement owner)
{
if (_owner != null)
{
@ -113,7 +120,7 @@ namespace Avalonia.Input
OnSetOwner(owner);
}
protected virtual void OnSetOwner(IInputRoot owner)
protected virtual void OnSetOwner(InputElement owner)
{
}
@ -159,6 +166,9 @@ namespace Avalonia.Input
}
}
static void SetShowAccessKeys(AvaloniaObject target, bool value) =>
target.SetValue(ShowAccessKeyProperty, value);
/// <summary>
/// Called when a key is pressed in the owner window.
/// </summary>
@ -188,7 +198,7 @@ namespace Avalonia.Input
// When Alt is pressed without a main menu, or with a closed main menu, show
// access key markers in the window (i.e. "_File").
_owner!.ShowAccessKeys = _showingAccessKeys = isFocusWithinOwner;
SetShowAccessKeys(_owner!, _showingAccessKeys = isFocusWithinOwner);
}
else
{
@ -265,7 +275,7 @@ namespace Avalonia.Input
{
if (_showingAccessKeys)
{
_owner!.ShowAccessKeys = false;
SetShowAccessKeys(_owner!, false);
}
}
@ -275,12 +285,12 @@ namespace Avalonia.Input
private void CloseMenu()
{
MainMenu!.Close();
_owner!.ShowAccessKeys = _showingAccessKeys = false;
SetShowAccessKeys(_owner!, _showingAccessKeys = false);
}
private void MainMenuClosed(object? sender, EventArgs e)
{
_owner!.ShowAccessKeys = false;
SetShowAccessKeys(_owner!, false);
}
/// <summary>
@ -444,7 +454,7 @@ namespace Avalonia.Input
/// </summary>
/// <param name="owner">The owner to check.</param>
/// <returns>If focused element is decendant of owner <c>true</c>, otherwise <c>false</c>. </returns>
private static bool IsFocusWithinOwner(IInputRoot owner)
private static bool IsFocusWithinOwner(IInputElement owner)
{
var focusedElement = KeyboardDevice.Instance?.FocusedElement;
if (focusedElement is not InputElement inputElement)

4
src/Avalonia.Base/Input/DragDropDevice.cs

@ -16,7 +16,7 @@ namespace Avalonia.Input
private static Interactive? GetTarget(IInputRoot root, Point local)
{
var hit = root.InputHitTest(local) as Visual;
var hit = root.RootElement?.InputHitTest(local) as Visual;
var target = hit?.GetSelfAndVisualAncestors()?.OfType<Interactive>()?.FirstOrDefault();
if (target != null && DragDrop.GetAllowDrop(target))
return target;
@ -35,7 +35,7 @@ namespace Avalonia.Input
if (target == null)
return DragDropEffects.None;
var p = ((Visual)inputRoot).TranslatePoint(point, target);
var p = (inputRoot.RootElement).TranslatePoint(point, target);
if (!p.HasValue)
return DragDropEffects.None;

14
src/Avalonia.Base/Input/FocusManager.cs

@ -51,6 +51,11 @@ namespace Avalonia.Input
{
_contentRoot = contentRoot;
}
internal void SetContentRoot(IInputElement? contentRoot)
{
_contentRoot = contentRoot;
}
private IInputElement? Current => KeyboardDevice.Instance?.FocusedElement;
@ -120,7 +125,7 @@ namespace Avalonia.Input
scope.ClearValue(FocusedElementProperty);
}
if (Current == removedElement)
if (Current == removedElement)
Focus(null);
}
@ -163,9 +168,10 @@ namespace Avalonia.Input
/// </summary>
internal static FocusManager? GetFocusManager(IInputElement? element)
{
// Element might not be a visual, and not attached to the root.
// But IFocusManager is always expected to be a FocusManager.
return (FocusManager?)((element as Visual)?.VisualRoot as IInputRoot)?.FocusManager
return (FocusManager?)(element as Visual)?.GetInputRoot()?.FocusManager
// In our unit tests some elements might not have a root. Remove when we migrate to headless tests.
?? (FocusManager?)AvaloniaLocator.Current.GetService<IFocusManager>();
}
@ -240,10 +246,10 @@ namespace Avalonia.Input
if (scope is not Visual v)
return null;
var root = v.VisualRoot as Visual;
var root = v.PresentationSource?.InputRoot.FocusRoot as Visual;
while (root is IHostedVisualTreeRoot hosted &&
hosted.Host?.VisualRoot is Visual parentRoot)
hosted.Host?.PresentationSource?.InputRoot.FocusRoot is {} parentRoot)
{
root = parentRoot;
}

5
src/Avalonia.Base/Input/Gestures.cs

@ -257,7 +257,7 @@ namespace Avalonia.Input
s_lastPressPoint = e.GetPosition((Visual)source);
s_holdCancellationToken = new CancellationTokenSource();
var token = s_holdCancellationToken.Token;
var settings = ((IInputRoot?)visual.GetVisualRoot())?.PlatformSettings;
var settings = visual.GetPlatformSettings();
if (settings != null)
{
@ -298,7 +298,7 @@ namespace Avalonia.Input
source is Interactive i)
{
var point = e.GetCurrentPoint((Visual)target);
var settings = ((IInputRoot?)i.GetVisualRoot())?.PlatformSettings;
var settings = i.GetPlatformSettings();
var tapSize = settings?.GetTapSize(point.Pointer.Type) ?? new Size(4, 4);
var tapRect = new Rect(s_lastPressPoint, new Size())
.Inflate(new Thickness(tapSize.Width, tapSize.Height));
@ -340,7 +340,6 @@ namespace Avalonia.Input
if (e.Pointer == s_gestureState?.Pointer && source is Interactive i)
{
var point = e.GetCurrentPoint((Visual)target);
var settings = ((IInputRoot?)i.GetVisualRoot())?.PlatformSettings;
var holdSize = new Size(4, 4);
var holdRect = new Rect(s_lastPressPoint, new Size())
.Inflate(new Thickness(holdSize.Width, holdSize.Height));

2
src/Avalonia.Base/Input/IAccessKeyHandler.cs

@ -19,7 +19,7 @@ namespace Avalonia.Input
/// <remarks>
/// This method can only be called once, typically by the owner itself on creation.
/// </remarks>
void SetOwner(IInputRoot owner);
void SetOwner(InputElement owner);
/// <summary>
/// Registers an input element to be associated with an access key.

38
src/Avalonia.Base/Input/IInputRoot.cs

@ -1,3 +1,4 @@
using Avalonia.Input.TextInput;
using Avalonia.Metadata;
using Avalonia.Platform;
@ -6,38 +7,31 @@ namespace Avalonia.Input
/// <summary>
/// Defines the interface for top-level input elements.
/// </summary>
[NotClientImplementable]
public interface IInputRoot : IInputElement
[PrivateApi]
public interface IInputRoot
{
/// <summary>
/// Gets or sets the keyboard navigation handler.
/// </summary>
IKeyboardNavigationHandler? KeyboardNavigationHandler { get; }
/// <summary>
/// Gets focus manager of the root.
/// </summary>
/// <remarks>
/// Focus manager can be null only if window wasn't initialized yet.
/// </remarks>
IFocusManager? FocusManager { get; }
/// <summary>
/// Represents a contract for accessing top-level platform-specific settings.
/// </summary>
/// <remarks>
/// PlatformSettings can be null only if window wasn't initialized yet.
/// </remarks>
IPlatformSettings? PlatformSettings { get; }
public IFocusManager? FocusManager { get; }
/// <summary>
/// Gets or sets the input element that the pointer is currently over.
/// </summary>
IInputElement? PointerOverElement { get; set; }
/// <summary>
/// Gets or sets a value indicating whether access keys are shown in the window.
/// </summary>
bool ShowAccessKeys { get; set; }
internal IInputElement? PointerOverElement { get; set; }
internal ITextInputMethodImpl? InputMethod { get; }
internal InputElement RootElement { get; }
// HACK: This is a temporary hack for "default focus" concept.
// If nothing is focused we send keyboard events to Window. Since for now we always
// control PresentationSource, we simply pass the TopLevel as a separate parameter there.
// It's also currently used by automation since we have special WindowAutomationPeer which needs to target the
// window itself
public InputElement FocusRoot { get; }
}
}

4
src/Avalonia.Base/Input/IKeyboardNavigationHandler.cs

@ -6,7 +6,7 @@ namespace Avalonia.Input
/// Defines the interface for classes that handle keyboard navigation for a window.
/// </summary>
[Unstable]
public interface IKeyboardNavigationHandler
internal interface IKeyboardNavigationHandler
{
/// <summary>
/// Sets the owner of the keyboard navigation handler.
@ -16,7 +16,7 @@ namespace Avalonia.Input
/// This method can only be called once, typically by the owner itself on creation.
/// </remarks>
[PrivateApi]
void SetOwner(IInputRoot owner);
void SetOwner(InputElement owner);
/// <summary>
/// Moves the focus in the specified direction.

4
src/Avalonia.Base/Input/InputElement.cs

@ -583,7 +583,9 @@ namespace Avalonia.Input
if (IsFocused)
{
FocusManager.GetFocusManager(e.Root as IInputElement)?.ClearFocusOnElementRemoved(this, e.Parent);
var root = e.AttachmentPoint ?? e.RootVisual;
((FocusManager?)e.PresentationSource.InputRoot.FocusManager)
?.ClearFocusOnElementRemoved(this, root);
}
IsKeyboardFocusWithin = false;

8
src/Avalonia.Base/Input/KeyboardDevice.cs

@ -191,15 +191,15 @@ namespace Avalonia.Input
// Clear keyboard focus from currently focused element
if (FocusedElement != null &&
(!((Visual)FocusedElement).IsAttachedToVisualTree ||
_focusedRoot != ((Visual?)element)?.VisualRoot as IInputRoot) &&
_focusedRoot != ((Visual?)element)?.GetInputRoot()) &&
_focusedRoot != null)
{
ClearChildrenFocusWithin(_focusedRoot, true);
ClearChildrenFocusWithin(_focusedRoot.RootElement, true);
}
SetIsFocusWithin(FocusedElement, element);
_focusedElement = element;
_focusedRoot = ((Visual?)_focusedElement)?.VisualRoot as IInputRoot;
_focusedRoot = (_focusedElement as Visual)?.GetInputRoot();
interactive?.RaiseEvent(new RoutedEventArgs(InputElement.LostFocusEvent));
@ -225,7 +225,7 @@ namespace Avalonia.Input
if(e.Handled)
return;
var element = FocusedElement ?? e.Root;
var element = FocusedElement ?? e.Root.FocusRoot;
if (e is RawKeyEventArgs keyInput)
{

9
src/Avalonia.Base/Input/KeyboardNavigationHandler.cs

@ -10,13 +10,12 @@ namespace Avalonia.Input
/// <summary>
/// Handles keyboard navigation for a window.
/// </summary>
[Unstable]
public sealed class KeyboardNavigationHandler : IKeyboardNavigationHandler
internal sealed class KeyboardNavigationHandler : IKeyboardNavigationHandler
{
/// <summary>
/// The window to which the handler belongs.
/// </summary>
private IInputRoot? _owner;
private InputElement? _owner;
/// <summary>
/// Sets the owner of the keyboard navigation handler.
@ -26,7 +25,7 @@ namespace Avalonia.Input
/// This method can only be called once, typically by the owner itself on creation.
/// </remarks>
[PrivateApi]
public void SetOwner(IInputRoot owner)
public void SetOwner(InputElement owner)
{
if (_owner != null)
{
@ -56,7 +55,7 @@ namespace Avalonia.Input
private static IInputElement? GetNextPrivate(
IInputElement? element,
IInputRoot? owner,
InputElement? owner,
NavigationDirection direction,
KeyDeviceType? keyDeviceType)
{

20
src/Avalonia.Base/Input/MouseDevice.cs

@ -135,20 +135,20 @@ namespace Avalonia.Input
return new PointerPointProperties(args.InputModifiers, args.Type.ToUpdateKind());
}
private bool MouseDown(IMouseDevice device, ulong timestamp, IInputElement root, Point p,
private bool MouseDown(IMouseDevice device, ulong timestamp, IInputRoot root, Point p,
PointerPointProperties properties,
KeyModifiers inputModifiers, IInputElement? hitTest)
{
device = device ?? throw new ArgumentNullException(nameof(device));
root = root ?? throw new ArgumentNullException(nameof(root));
var source = _pointer.Captured ?? root.InputHitTest(p);
var source = _pointer.Captured ?? root.RootElement.InputHitTest(p);
if (source != null)
{
_pointer.Capture(source, CaptureSource.Implicit);
var settings = ((IInputRoot?)(source as Interactive)?.GetVisualRoot())?.PlatformSettings;
var settings = (source as Interactive)?.GetPlatformSettings();
if (settings is not null)
{
var doubleClickTime = settings.GetDoubleTapTime(PointerType.Mouse).TotalMilliseconds;
@ -166,7 +166,7 @@ namespace Avalonia.Input
}
_lastMouseDownButton = properties.PointerUpdateKind.GetMouseButton();
var e = new PointerPressedEventArgs(source, _pointer, (Visual)root, p, timestamp, properties, inputModifiers, _clickCount);
var e = new PointerPressedEventArgs(source, _pointer, root.RootElement, p, timestamp, properties, inputModifiers, _clickCount);
source.RaiseEvent(e);
return e.Handled;
}
@ -185,7 +185,7 @@ namespace Avalonia.Input
if (source is object)
{
var e = new PointerEventArgs(InputElement.PointerMovedEvent, source, _pointer, (Visual)root,
var e = new PointerEventArgs(InputElement.PointerMovedEvent, source, _pointer, root.RootElement,
p, timestamp, properties, inputModifiers, intermediatePoints);
if (_pointer.CapturedGestureRecognizer is GestureRecognizer gestureRecognizer)
@ -209,7 +209,7 @@ namespace Avalonia.Input
if (source is not null)
{
var e = new PointerReleasedEventArgs(source, _pointer, (Visual)root, p, timestamp, props, inputModifiers,
var e = new PointerReleasedEventArgs(source, _pointer, root.RootElement, p, timestamp, props, inputModifiers,
_lastMouseDownButton);
try
@ -244,7 +244,7 @@ namespace Avalonia.Input
if (source is not null)
{
var e = new PointerWheelEventArgs(source, _pointer, (Visual)root, p, timestamp, props, inputModifiers, delta);
var e = new PointerWheelEventArgs(source, _pointer, root.RootElement, p, timestamp, props, inputModifiers, delta);
source?.RaiseEvent(e);
return e.Handled;
@ -264,7 +264,7 @@ namespace Avalonia.Input
if (source != null)
{
var e = new PointerDeltaEventArgs(Gestures.PointerTouchPadGestureMagnifyEvent, source,
_pointer, (Visual)root, p, timestamp, props, inputModifiers, delta);
_pointer, root.RootElement, p, timestamp, props, inputModifiers, delta);
source?.RaiseEvent(e);
return e.Handled;
@ -284,7 +284,7 @@ namespace Avalonia.Input
if (source != null)
{
var e = new PointerDeltaEventArgs(Gestures.PointerTouchPadGestureRotateEvent, source,
_pointer, (Visual)root, p, timestamp, props, inputModifiers, delta);
_pointer, root.RootElement, p, timestamp, props, inputModifiers, delta);
source?.RaiseEvent(e);
return e.Handled;
@ -304,7 +304,7 @@ namespace Avalonia.Input
if (source != null)
{
var e = new PointerDeltaEventArgs(Gestures.PointerTouchPadGestureSwipeEvent, source,
_pointer, (Visual)root, p, timestamp, props, inputModifiers, delta);
_pointer, root.RootElement, p, timestamp, props, inputModifiers, delta);
source?.RaiseEvent(e);
return e.Handled;

11
src/Avalonia.Base/Input/Navigation/XYFocus.FindElements.cs

@ -105,12 +105,11 @@ public partial class XYFocus
private static bool IsOccluded(InputElement element, Rect elementBounds)
{
// if (element is CHyperlink hyperlink)
// {
// element = hyperlink.GetContainingFrameworkElement();
// }
var root = (InputElement)element.GetVisualRoot()!;
// TODO: The check for bounds is no longer correct
var root = (InputElement?)element.VisualRoot;
if (root == null)
return true;
// Check if the element is within the visible area of the window
var visibleBounds = new Rect(0, 0, root.Bounds.Width, root.Bounds.Height);

4
src/Avalonia.Base/Input/Navigation/XYFocus.Impl.cs

@ -117,7 +117,9 @@ public partial class XYFocus
{
if (element == null) return null;
var root = (InputElement)element.GetVisualRoot()!;
var root = (InputElement?)element.VisualRoot;
if (root == null)
return null;
var isRightToLeft = element.FlowDirection == FlowDirection.RightToLeft;
var mode = GetStrategy(element, direction, xyFocusOptions.NavigationStrategyOverride);

14
src/Avalonia.Base/Input/PenDevice.cs

@ -97,7 +97,7 @@ namespace Avalonia.Input
}
private bool PenDown(Pointer pointer, ulong timestamp,
IInputElement root, Point p, PointerPointProperties properties,
IInputRoot root, Point p, PointerPointProperties properties,
KeyModifiers inputModifiers, IInputElement? hitTest)
{
var source = pointer.Captured ?? hitTest;
@ -105,7 +105,7 @@ namespace Avalonia.Input
if (source != null)
{
pointer.Capture(source);
var settings = ((IInputRoot?)(source as Interactive)?.GetVisualRoot())?.PlatformSettings;
var settings = (source as Interactive)?.GetPlatformSettings();
if (settings is not null)
{
var doubleClickTime = settings.GetDoubleTapTime(PointerType.Pen).TotalMilliseconds;
@ -123,7 +123,7 @@ namespace Avalonia.Input
}
_lastMouseDownButton = properties.PointerUpdateKind.GetMouseButton();
var e = new PointerPressedEventArgs(source, pointer, (Visual)root, p, timestamp, properties, inputModifiers, _clickCount);
var e = new PointerPressedEventArgs(source, pointer, root.RootElement, p, timestamp, properties, inputModifiers, _clickCount);
source.RaiseEvent(e);
return e.Handled;
}
@ -140,7 +140,7 @@ namespace Avalonia.Input
if (source is not null)
{
var e = new PointerEventArgs(InputElement.PointerMovedEvent, source, pointer, (Visual)root,
var e = new PointerEventArgs(InputElement.PointerMovedEvent, source, pointer, root.RootElement,
p, timestamp, properties, inputModifiers, intermediatePoints);
if (pointer.CapturedGestureRecognizer is GestureRecognizer gestureRecognizer)
@ -154,14 +154,14 @@ namespace Avalonia.Input
}
private bool PenUp(Pointer pointer, ulong timestamp,
IInputElement root, Point p, PointerPointProperties properties,
IInputRoot root, Point p, PointerPointProperties properties,
KeyModifiers inputModifiers, IInputElement? hitTest)
{
var source = pointer.CapturedGestureRecognizer?.Target ?? pointer.Captured ?? hitTest;
if (source is not null)
{
var e = new PointerReleasedEventArgs(source, pointer, (Visual)root, p, timestamp, properties, inputModifiers,
var e = new PointerReleasedEventArgs(source, pointer, root.RootElement, p, timestamp, properties, inputModifiers,
_lastMouseDownButton);
try

4
src/Avalonia.Base/Input/Pointer.cs

@ -108,14 +108,14 @@ namespace Avalonia.Input
}
}
static IInputElement? GetNextCapture(Visual parent)
static IInputElement? GetNextCapture(Visual? parent)
{
return parent as IInputElement ?? parent.FindAncestorOfType<IInputElement>();
}
private void OnCaptureDetached(object? sender, VisualTreeAttachmentEventArgs e)
{
Capture(GetNextCapture(e.Parent));
Capture(GetNextCapture(e.AttachmentPoint));
}

20
src/Avalonia.Base/Input/PointerOverPreProcessor.cs

@ -38,7 +38,7 @@ namespace Avalonia.Input
// occurred.
//
// Solve this by updating the last known pointer position when a drag event occurs.
_lastKnownPosition = ((Visual)_inputRoot).PointToScreen(dragArgs.Location);
_lastKnownPosition = _inputRoot.RootElement.PointToScreen(dragArgs.Location);
}
else if (value is RawPointerEventArgs args
@ -64,7 +64,7 @@ namespace Avalonia.Input
args.InputModifiers.ToKeyModifiers());
}
}
else if (args.Type is RawPointerEventType.TouchBegin or RawPointerEventType.TouchUpdate && args.Root is Visual visual)
else if (args.Type is RawPointerEventType.TouchBegin or RawPointerEventType.TouchUpdate && args.Root.RootElement is {} visual)
{
_lastKnownPosition = visual.PointToScreen(args.Position);
}
@ -99,12 +99,12 @@ namespace Avalonia.Input
if (dirtyRect.Contains(clientPoint))
{
var element = GetEffectivePointerOverElement(
_inputRoot.InputHitTest(clientPoint),
_inputRoot.RootElement.InputHitTest(clientPoint),
pointer.Captured);
SetPointerOver(pointer, _inputRoot, element, 0, clientPoint, PointerPointProperties.None, KeyModifiers.None);
}
else if (!((Visual)_inputRoot).Bounds.Contains(clientPoint))
else if (!_inputRoot.RootElement.Bounds.Contains(clientPoint))
{
ClearPointerOver(pointer, _inputRoot, 0, clientPoint, PointerPointProperties.None, KeyModifiers.None);
}
@ -140,16 +140,16 @@ namespace Avalonia.Input
// so GetPosition won't return invalid values.
#pragma warning disable CS0618
var e = new PointerEventArgs(InputElement.PointerExitedEvent, element, pointer,
position.HasValue ? root as Visual : null, position.HasValue ? position.Value : default,
position.HasValue ? root.RootElement : null, position.HasValue ? position.Value : default,
timestamp, properties, inputModifiers);
#pragma warning restore CS0618
if (element is Visual v && !v.IsAttachedToVisualTree)
{
// element has been removed from visual tree so do top down cleanup
if (root.IsPointerOver)
if (root.RootElement.IsPointerOver)
{
ClearChildrenPointerOver(e, root, true);
ClearChildrenPointerOver(e, root.RootElement, true);
}
}
while (element != null)
@ -191,7 +191,7 @@ namespace Avalonia.Input
ulong timestamp, Point position, PointerPointProperties properties, KeyModifiers inputModifiers)
{
var pointerOverElement = root.PointerOverElement;
var screenPosition = ((Visual)root).PointToScreen(position);
var screenPosition = (root.RootElement).PointToScreen(position);
_lastKnownPosition = screenPosition;
if (element != pointerOverElement)
@ -229,7 +229,7 @@ namespace Avalonia.Input
el = root.PointerOverElement;
#pragma warning disable CS0618
var e = new PointerEventArgs(InputElement.PointerExitedEvent, el, pointer, (Visual)root, position,
var e = new PointerEventArgs(InputElement.PointerExitedEvent, el, pointer, root.RootElement, position,
timestamp, properties, inputModifiers);
#pragma warning restore CS0618
if (el is Visual v && branch != null && !v.IsAttachedToVisualTree)
@ -265,7 +265,7 @@ namespace Avalonia.Input
private static Point PointToClient(IInputRoot root, PixelPoint p)
{
return ((Visual)root).PointToClient(p);
return (root.RootElement).PointToClient(p);
}
}
}

6
src/Avalonia.Base/Input/TextInput/ITextInputMethodImpl.cs

@ -10,10 +10,4 @@ namespace Avalonia.Input.TextInput
void SetOptions(TextInputOptions options);
void Reset();
}
[NotClientImplementable]
public interface ITextInputMethodRoot : IInputRoot
{
ITextInputMethodImpl? InputMethod { get; }
}
}

4
src/Avalonia.Base/Input/TextInput/InputMethodManager.cs

@ -10,7 +10,7 @@ namespace Avalonia.Input.TextInput
private IInputElement? _focusedElement;
private Interactive? _visualRoot;
private TextInputMethodClient? _client;
private readonly TransformTrackingHelper _transformTracker = new TransformTrackingHelper();
private readonly TransformTrackingHelper _transformTracker = new TransformTrackingHelper(true);
public TextInputMethodManager()
{
@ -132,7 +132,7 @@ namespace Avalonia.Input.TextInput
InputMethod.AddTextInputMethodClientRequeryRequestedHandler(_visualRoot,
TextInputMethodClientRequeryRequested);
var inputMethod = ((element as Visual)?.VisualRoot as ITextInputMethodRoot)?.InputMethod;
var inputMethod = ((element as Visual)?.GetInputRoot())?.InputMethod;
if (_im != inputMethod)
{

29
src/Avalonia.Base/Input/TextInput/TransformTrackingHelper.cs

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using Avalonia.Media;
using Avalonia.Reactive;
using Avalonia.Threading;
using Avalonia.VisualTree;
@ -7,13 +9,15 @@ namespace Avalonia.Input.TextInput
{
class TransformTrackingHelper : IDisposable
{
private readonly bool _deferAfterRenderPass;
private Visual? _visual;
private bool _queuedForUpdate;
private readonly EventHandler<AvaloniaPropertyChangedEventArgs> _propertyChangedHandler;
private readonly List<Visual> _propertyChangedSubscriptions = new List<Visual>();
public TransformTrackingHelper()
public TransformTrackingHelper(bool deferAfterRenderPass)
{
_deferAfterRenderPass = deferAfterRenderPass;
_propertyChangedHandler = PropertyChangedHandler;
}
@ -24,7 +28,7 @@ namespace Avalonia.Input.TextInput
if (visual != null)
{
visual.AttachedToVisualTree += OnAttachedToVisualTree;
visual.DetachedFromVisualTree -= OnDetachedFromVisualTree;
visual.DetachedFromVisualTree += OnDetachedFromVisualTree;
if (visual.IsAttachedToVisualTree)
SubscribeToParents();
UpdateMatrix();
@ -70,6 +74,7 @@ namespace Avalonia.Input.TextInput
void UpdateMatrix()
{
_queuedForUpdate = false;
Matrix? matrix = null;
if (_visual != null && _visual.VisualRoot != null)
matrix = _visual.TransformToVisual((Visual)_visual.VisualRoot);
@ -91,7 +96,10 @@ namespace Avalonia.Input.TextInput
if(_queuedForUpdate)
return;
_queuedForUpdate = true;
Dispatcher.UIThread.Post(UpdateMatrix, DispatcherPriority.AfterRender);
if (_deferAfterRenderPass)
Dispatcher.UIThread.Post(UpdateMatrix, DispatcherPriority.AfterRender);
else
MediaContext.Instance.BeginInvokeOnRender(UpdateMatrix);
}
private void PropertyChangedHandler(object? sender, AvaloniaPropertyChangedEventArgs e)
@ -106,12 +114,23 @@ namespace Avalonia.Input.TextInput
UpdateMatrix();
}
public static IDisposable Track(Visual visual, Action<Visual, Matrix?> cb)
public static IDisposable Track(Visual visual, bool deferAfterRenderPass, Action<Visual, Matrix?> cb)
{
var rv = new TransformTrackingHelper();
var rv = new TransformTrackingHelper(deferAfterRenderPass);
rv.MatrixChanged += () => cb(visual, rv.Matrix);
rv.SetVisual(visual);
return rv;
}
public static IObservable<Matrix?> Observe(Visual visual, bool deferAfterRenderPass)
{
return Observable.Create<Matrix?>(observer =>
{
var rv = new TransformTrackingHelper(deferAfterRenderPass);
rv.MatrixChanged += () => observer.OnNext(rv.Matrix);
rv.SetVisual(visual);
return rv;
});
}
}
}

10
src/Avalonia.Base/Input/TouchDevice.cs

@ -51,7 +51,7 @@ namespace Avalonia.Input
pointer.Capture(hit);
}
var target = pointer.Captured ?? args.InputHitTestResult.firstEnabledAncestor ?? args.Root;
var target = pointer.Captured ?? args.InputHitTestResult.firstEnabledAncestor ?? args.Root.RootElement;
var gestureTarget = pointer.CapturedGestureRecognizer?.Target;
var updateKind = args.Type.ToUpdateKind();
var keyModifier = args.InputModifiers.ToKeyModifiers();
@ -66,7 +66,7 @@ namespace Avalonia.Input
}
else
{
var settings = ((IInputRoot?)(target as Interactive)?.GetVisualRoot())?.PlatformSettings;
var settings = (target as Interactive)?.GetPlatformSettings();
if (settings is not null)
{
var doubleClickTime = settings.GetDoubleTapTime(PointerType.Touch).TotalMilliseconds;
@ -86,7 +86,7 @@ namespace Avalonia.Input
}
target.RaiseEvent(new PointerPressedEventArgs(target, pointer,
(Visual)args.Root, args.Position, ev.Timestamp,
args.Root.RootElement, args.Position, ev.Timestamp,
new PointerPointProperties(GetModifiers(args.InputModifiers, true), updateKind, args.Point),
keyModifier, _clickCount));
}
@ -98,7 +98,7 @@ namespace Avalonia.Input
{
target = gestureTarget ?? target;
var e = new PointerReleasedEventArgs(target, pointer,
(Visual)args.Root, args.Position, ev.Timestamp,
args.Root.RootElement, args.Position, ev.Timestamp,
new PointerPointProperties(GetModifiers(args.InputModifiers, false), updateKind, args.Point),
keyModifier, MouseButton.Left);
if (gestureTarget != null)
@ -127,7 +127,7 @@ namespace Avalonia.Input
if (args.Type == RawPointerEventType.TouchUpdate)
{
target = gestureTarget ?? target;
var e = new PointerEventArgs(InputElement.PointerMovedEvent, target, pointer!, (Visual)args.Root,
var e = new PointerEventArgs(InputElement.PointerMovedEvent, target, pointer!, args.Root.RootElement,
args.Position, ev.Timestamp,
new PointerPointProperties(GetModifiers(args.InputModifiers, true), updateKind, args.Point),
keyModifier, args.IntermediatePoints);

10
src/Avalonia.Base/Layout/IEmbeddedLayoutRoot.cs

@ -1,10 +0,0 @@
namespace Avalonia.Layout
{
/// <summary>
/// A special layout root with enforced size for Arrange pass
/// </summary>
public interface IEmbeddedLayoutRoot : ILayoutRoot
{
Size AllocatedSize { get; }
}
}

1
src/Avalonia.Base/Layout/ILayoutManager.cs

@ -6,7 +6,6 @@ namespace Avalonia.Layout
/// <summary>
/// Manages measuring and arranging of controls.
/// </summary>
[PrivateApi]
public interface ILayoutManager : IDisposable
{
/// <summary>

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

Loading…
Cancel
Save