Quellcode durchsuchen

Merge branch 'master' into fix/DataGridCopyMulitlineContent

Max Katz vor 2 Jahren
Ursprung
Commit
0eb63c9214
100 geänderte Dateien mit 1821 neuen und 515 gelöschten Zeilen
  1. 59 10
      .editorconfig
  2. 1 0
      .github/FUNDING.yml
  3. 1 1
      .github/PULL_REQUEST_TEMPLATE.md
  4. 7 2
      .gitignore
  5. 3 0
      .gitmodules
  6. 0 0
      .ncrunch/Avalonia.Benchmarks.v3.ncrunchproject
  7. 5 0
      .ncrunch/Avalonia.Browser.Blazor.v3.ncrunchproject
  8. 5 0
      .ncrunch/Avalonia.Browser.v3.ncrunchproject
  9. 5 0
      .ncrunch/Avalonia.Designer.HostApp.v3.ncrunchproject
  10. 5 0
      .ncrunch/Avalonia.Themes.Fluent.net6.0.v3.ncrunchproject
  11. 5 0
      .ncrunch/Avalonia.Themes.Fluent.netstandard2.0.v3.ncrunchproject
  12. 5 0
      .ncrunch/Avalonia.Themes.Simple.net6.0.v3.ncrunchproject
  13. 5 0
      .ncrunch/Avalonia.Themes.Simple.netstandard2.0.v3.ncrunchproject
  14. 5 0
      .ncrunch/Avalonia.UnitTests.v3.ncrunchproject
  15. 1 5
      .ncrunch/Avalonia.Win32.net6.0.v3.ncrunchproject
  16. 1 5
      .ncrunch/Avalonia.Win32.netstandard2.0.v3.ncrunchproject
  17. 5 0
      .ncrunch/ControlCatalog.Browser.Blazor.v3.ncrunchproject
  18. 5 0
      .ncrunch/ControlCatalog.Browser.v3.ncrunchproject
  19. 5 0
      .ncrunch/GpuInterop.v3.ncrunchproject
  20. 5 0
      .ncrunch/MobileSandbox.Android.v3.ncrunchproject
  21. 5 0
      .ncrunch/MobileSandbox.Desktop.v3.ncrunchproject
  22. 5 0
      .ncrunch/MobileSandbox.iOS.v3.ncrunchproject
  23. 5 0
      .ncrunch/MobileSandbox.net6.0.v3.ncrunchproject
  24. 5 0
      .ncrunch/MobileSandbox.netstandard2.0.v3.ncrunchproject
  25. 5 0
      .ncrunch/MobileSandbox.v3.ncrunchproject
  26. 5 0
      .ncrunch/ReactiveUIDemo.v3.ncrunchproject
  27. 5 0
      .ncrunch/_build.v3.ncrunchproject
  28. 0 0
      .nuke
  29. 148 0
      .nuke/build.schema.json
  30. 4 0
      .nuke/parameters.json
  31. 67 0
      Avalonia.Desktop.slnf
  32. 133 28
      Avalonia.sln
  33. 1 0
      Directory.Build.props
  34. 5 0
      Directory.Build.targets
  35. 26 12
      Documentation/build.md
  36. 70 11
      NOTICE.md
  37. 36 12
      azure-pipelines-integrationtests.yml
  38. 27 23
      azure-pipelines.yml
  39. 7 0
      build.cmd
  40. 24 26
      build.ps1
  41. 46 14
      build.sh
  42. 4 1
      build/Base.props
  43. 1 0
      build/BuildTargets.targets
  44. 5 0
      build/DevAnalyzers.props
  45. 3 3
      build/HarfBuzzSharp.props
  46. 1 1
      build/ImageSharp.props
  47. 0 5
      build/JetBrains.Annotations.props
  48. 1 1
      build/Moq.props
  49. 5 0
      build/NetAnalyzers.props
  50. 1 1
      build/ReactiveUI.props
  51. 3 3
      build/SharedVersion.props
  52. 10 5
      build/SharpDX.props
  53. 3 3
      build/SkiaSharp.props
  54. 16 1
      build/SourceGenerators.props
  55. 2 1
      build/System.Memory.props
  56. 16 0
      build/TrimmingEnable.props
  57. 7 8
      build/XUnit.props
  58. 6 6
      dirs.proj
  59. 2 4
      global.json
  60. 20 0
      native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj
  61. 46 0
      native/Avalonia.Native/src/OSX/AvnTextInputMethod.h
  62. 41 0
      native/Avalonia.Native/src/OSX/AvnTextInputMethod.mm
  63. 20 0
      native/Avalonia.Native/src/OSX/AvnTextInputMethodDelegate.h
  64. 2 4
      native/Avalonia.Native/src/OSX/AvnView.h
  65. 74 18
      native/Avalonia.Native/src/OSX/AvnView.mm
  66. 23 13
      native/Avalonia.Native/src/OSX/AvnWindow.mm
  67. 39 0
      native/Avalonia.Native/src/OSX/PlatformBehaviorInhibition.mm
  68. 113 0
      native/Avalonia.Native/src/OSX/PlatformSettings.mm
  69. 1 1
      native/Avalonia.Native/src/OSX/PopupImpl.mm
  70. 2 2
      native/Avalonia.Native/src/OSX/Screens.mm
  71. 12 5
      native/Avalonia.Native/src/OSX/WindowBaseImpl.h
  72. 55 33
      native/Avalonia.Native/src/OSX/WindowBaseImpl.mm
  73. 9 5
      native/Avalonia.Native/src/OSX/WindowImpl.h
  74. 71 48
      native/Avalonia.Native/src/OSX/WindowImpl.mm
  75. 7 4
      native/Avalonia.Native/src/OSX/app.mm
  76. 3 1
      native/Avalonia.Native/src/OSX/common.h
  77. 56 6
      native/Avalonia.Native/src/OSX/main.mm
  78. 10 3
      native/Avalonia.Native/src/OSX/menu.h
  79. 20 6
      native/Avalonia.Native/src/OSX/menu.mm
  80. 4 1
      native/Avalonia.Native/src/OSX/rendertarget.mm
  81. 61 85
      nukebuild/Build.cs
  82. 2 6
      nukebuild/BuildParameters.cs
  83. 98 14
      nukebuild/BuildTasksPatcher.cs
  84. 56 0
      nukebuild/DotNetConfigHelper.cs
  85. 0 14
      nukebuild/MicroComGen.cs
  86. 15 0
      nukebuild/Shims.cs
  87. 25 18
      nukebuild/_build.csproj
  88. 1 0
      nukebuild/il-repack
  89. 5 0
      nukebuild/numerge.config
  90. 5 1
      packages/Avalonia/Avalonia.csproj
  91. 5 0
      packages/Avalonia/Avalonia.props
  92. 37 13
      packages/Avalonia/AvaloniaBuildTasks.targets
  93. 3 1
      readme.md
  94. 3 4
      samples/BindingDemo/App.xaml
  95. 1 0
      samples/BindingDemo/BindingDemo.csproj
  96. 3 3
      samples/BindingDemo/MainWindow.xaml
  97. 4 2
      samples/BindingDemo/TestItemView.xaml
  98. 2 10
      samples/ControlCatalog.Android/MainActivity.cs
  99. 5 1
      samples/ControlCatalog.Android/Resources/values/styles.xml
  100. 14 1
      samples/ControlCatalog.Android/SplashActivity.cs

+ 59 - 10
.editorconfig

@@ -55,16 +55,17 @@ dotnet_naming_symbols.constant_fields.required_modifiers = const
 
 dotnet_naming_style.pascal_case_style.capitalization = pascal_case
 
-# static fields should have s_ prefix
-dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
-dotnet_naming_rule.static_fields_should_have_prefix.symbols  = static_fields
-dotnet_naming_rule.static_fields_should_have_prefix.style    = static_prefix_style
+# private static fields should have s_ prefix
+dotnet_naming_rule.private_static_fields_should_have_prefix.severity = suggestion
+dotnet_naming_rule.private_static_fields_should_have_prefix.symbols  = private_static_fields
+dotnet_naming_rule.private_static_fields_should_have_prefix.style    = private_static_prefix_style
 
-dotnet_naming_symbols.static_fields.applicable_kinds   = field
-dotnet_naming_symbols.static_fields.required_modifiers = static
+dotnet_naming_symbols.private_static_fields.applicable_kinds   = field
+dotnet_naming_symbols.private_static_fields.required_modifiers = static
+dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private
 
-dotnet_naming_style.static_prefix_style.required_prefix = s_
-dotnet_naming_style.static_prefix_style.capitalization = camel_case 
+dotnet_naming_style.private_static_prefix_style.required_prefix = s_
+dotnet_naming_style.private_static_prefix_style.capitalization = camel_case
 
 # internal and private fields should be _camelCase
 dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
@@ -117,7 +118,7 @@ csharp_space_after_dot = false
 csharp_space_after_keywords_in_control_flow_statements = true
 csharp_space_after_semicolon_in_for_statement = true
 csharp_space_around_binary_operators = before_and_after
-csharp_space_around_declaration_statements = do_not_ignore
+csharp_space_around_declaration_statements = false
 csharp_space_before_colon_in_inheritance_clause = true
 csharp_space_before_comma = false
 csharp_space_before_dot = false
@@ -134,9 +135,57 @@ csharp_space_between_parentheses = false
 csharp_space_between_square_brackets = false
 space_within_single_line_array_initializer_braces = true
 
+#Net Analyzer
+dotnet_analyzer_diagnostic.category-Performance.severity = none #error - Uncomment when all violations are fixed.
+
+# CS0649: Field 'field' is never assigned to, and will always have its default value 'value'
+dotnet_diagnostic.CS0649.severity = error
+
+# CS1591: Missing XML comment for publicly visible type or member
+dotnet_diagnostic.CS1591.severity = suggestion
+
+# CS0162: Remove unreachable code
+dotnet_diagnostic.CS0162.severity = error
+# CA1018: Mark attributes with AttributeUsageAttribute
+dotnet_diagnostic.CA1018.severity = error
+# CA1304: Specify CultureInfo
+dotnet_diagnostic.CA1304.severity = warning
+# CA1802: Use literals where appropriate
+dotnet_diagnostic.CA1802.severity = warning
+# CA1813: Avoid unsealed attributes
+dotnet_diagnostic.CA1813.severity = error
+# CA1815: Override equals and operator equals on value types
+dotnet_diagnostic.CA1815.severity = warning
+# CA1820: Test for empty strings using string length
+dotnet_diagnostic.CA1820.severity = warning
+# CA1821: Remove empty finalizers
+dotnet_diagnostic.CA1821.severity = warning
+# CA1822: Mark members as static
+dotnet_diagnostic.CA1822.severity = suggestion
+# CA1823: Avoid unused private fields
+dotnet_diagnostic.CA1823.severity = warning
+dotnet_code_quality.CA1822.api_surface = private, internal
+# CA1825: Avoid zero-length array allocations
+dotnet_diagnostic.CA1825.severity = warning
+# CA1826: Use property instead of Linq Enumerable method
+dotnet_diagnostic.CA1826.severity = suggestion
+# CA1827: Do not use Count/LongCount when Any can be used
+dotnet_diagnostic.CA1827.severity = warning
+# CA1828: Do not use CountAsync/LongCountAsync when AnyAsync can be used
+dotnet_diagnostic.CA1828.severity = warning
+# CA1829: Use Length/Count property instead of Enumerable.Count method
+dotnet_diagnostic.CA1829.severity = warning
+#CA1847: Use string.Contains(char) instead of string.Contains(string) with single characters
+dotnet_diagnostic.CA1847.severity = warning
+#CACA2211:Non-constant fields should not be visible
+dotnet_diagnostic.CA2211.severity = error
+
 # Wrapping preferences
 csharp_wrap_before_ternary_opsigns = false
 
+# Avalonia DevAnalyzer preferences
+dotnet_diagnostic.AVADEV2001.severity = error
+
 # Xaml files
 [*.{xaml,axaml}]
 indent_size = 2
@@ -163,5 +212,5 @@ indent_size = 2
 # Shell scripts
 [*.sh]
 end_of_line = lf
-[*.{cmd, bat}]
+[*.{cmd,bat}]
 end_of_line = crlf

+ 1 - 0
.github/FUNDING.yml

@@ -1 +1,2 @@
+github: avaloniaui
 open_collective: avalonia

+ 1 - 1
.github/PULL_REQUEST_TEMPLATE.md

@@ -21,7 +21,7 @@
 - [ ] Consider submitting a PR to https://github.com/AvaloniaUI/Documentation with user documentation
 
 ## Breaking changes
-<!--- List any breaking changes here. When the PR is merged please add an entry to https://github.com/AvaloniaUI/Avalonia/wiki/Breaking-Changes -->
+<!--- List any breaking changes here. -->
 
 ## Obsoletions / Deprecations
 <!--- Obsolete and Deprecated attributes on APIs MUST only be included when discussed with Core team. @grokys, @kekekeks & @danwalmsley -->

+ 7 - 2
.gitignore

@@ -102,6 +102,7 @@ csx
 AppPackages/
 
 # NCrunch
+.NCrunch_*/
 _NCrunch_*/
 *.ncrunchsolution.user
 nCrunchTemp_*
@@ -210,5 +211,9 @@ coc-settings.json
 .ccls-cache
 .ccls
 *.map
-src/Web/Avalonia.Web.Blazor/wwwroot/*.js
-src/Web/Avalonia.Web.Blazor/Interop/Typescript/*.js
+src/Browser/Avalonia.Browser.Blazor/wwwroot/*.js
+src/Browser/Avalonia.Browser.Blazor/Interop/Typescript/*.js
+node_modules
+src/Browser/Avalonia.Browser.Blazor/webapp/package-lock.json
+src/Browser/Avalonia.Browser.Blazor/wwwroot
+src/Browser/Avalonia.Browser/wwwroot

+ 3 - 0
.gitmodules

@@ -4,3 +4,6 @@
 [submodule "src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github"]
 	path = src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github
 	url = https://github.com/kekekeks/XamlX.git
+[submodule "nukebuild/il-repack"]
+	path = nukebuild/il-repack
+	url = https://github.com/Gillibald/il-repack

+ 0 - 0
.ncrunch/ControlCatalog.Web.v3.ncrunchproject → .ncrunch/Avalonia.Benchmarks.v3.ncrunchproject


+ 5 - 0
.ncrunch/Avalonia.Browser.Blazor.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/Avalonia.Browser.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/Avalonia.Designer.HostApp.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/Avalonia.Themes.Fluent.net6.0.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <InstrumentOutputAssembly>False</InstrumentOutputAssembly>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/Avalonia.Themes.Fluent.netstandard2.0.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <InstrumentOutputAssembly>False</InstrumentOutputAssembly>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/Avalonia.Themes.Simple.net6.0.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <InstrumentOutputAssembly>False</InstrumentOutputAssembly>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/Avalonia.Themes.Simple.netstandard2.0.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <InstrumentOutputAssembly>False</InstrumentOutputAssembly>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/Avalonia.UnitTests.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <XUnit2Enabled>False</XUnit2Enabled>
+  </Settings>
+</ProjectConfiguration>

+ 1 - 5
.ncrunch/Avalonia.Win32.net6.0.v3.ncrunchproject

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

+ 1 - 5
.ncrunch/Avalonia.Win32.netstandard2.0.v3.ncrunchproject

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

+ 5 - 0
.ncrunch/ControlCatalog.Browser.Blazor.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/ControlCatalog.Browser.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/GpuInterop.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/MobileSandbox.Android.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/MobileSandbox.Desktop.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/MobileSandbox.iOS.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/MobileSandbox.net6.0.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/MobileSandbox.netstandard2.0.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/MobileSandbox.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/ReactiveUIDemo.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/_build.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 0 - 0
.nuke


+ 148 - 0
.nuke/build.schema.json

@@ -0,0 +1,148 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "title": "Build Schema",
+  "$ref": "#/definitions/build",
+  "definitions": {
+    "build": {
+      "type": "object",
+      "properties": {
+        "Configuration": {
+          "type": "string",
+          "description": "configuration"
+        },
+        "Continue": {
+          "type": "boolean",
+          "description": "Indicates to continue a previously failed build attempt"
+        },
+        "ForceNugetVersion": {
+          "type": "string",
+          "description": "force-nuget-version"
+        },
+        "Help": {
+          "type": "boolean",
+          "description": "Shows the help text for this build assembly"
+        },
+        "Host": {
+          "type": "string",
+          "description": "Host for execution. Default is 'automatic'",
+          "enum": [
+            "AppVeyor",
+            "AzurePipelines",
+            "Bamboo",
+            "Bitbucket",
+            "Bitrise",
+            "GitHubActions",
+            "GitLab",
+            "Jenkins",
+            "Rider",
+            "SpaceAutomation",
+            "TeamCity",
+            "Terminal",
+            "TravisCI",
+            "VisualStudio",
+            "VSCode"
+          ]
+        },
+        "NoLogo": {
+          "type": "boolean",
+          "description": "Disables displaying the NUKE logo"
+        },
+        "Partition": {
+          "type": "string",
+          "description": "Partition to use on CI"
+        },
+        "Plan": {
+          "type": "boolean",
+          "description": "Shows the execution plan (HTML)"
+        },
+        "Profile": {
+          "type": "array",
+          "description": "Defines the profiles to load",
+          "items": {
+            "type": "string"
+          }
+        },
+        "Root": {
+          "type": "string",
+          "description": "Root directory during build execution"
+        },
+        "Skip": {
+          "type": "array",
+          "description": "List of targets to be skipped. Empty list skips all dependencies",
+          "items": {
+            "type": "string",
+            "enum": [
+              "CiAzureLinux",
+              "CiAzureOSX",
+              "CiAzureWindows",
+              "Clean",
+              "Compile",
+              "CompileHtmlPreviewer",
+              "CompileNative",
+              "CreateIntermediateNugetPackages",
+              "CreateNugetPackages",
+              "GenerateCppHeaders",
+              "Package",
+              "RunCoreLibsTests",
+              "RunHtmlPreviewerTests",
+              "RunLeakTests",
+              "RunRenderTests",
+              "RunTests",
+              "RunToolsTests",
+              "ZipFiles"
+            ]
+          }
+        },
+        "SkipPreviewer": {
+          "type": "boolean",
+          "description": "skip-previewer"
+        },
+        "SkipTests": {
+          "type": "boolean",
+          "description": "skip-tests"
+        },
+        "Solution": {
+          "type": "string",
+          "description": "Path to a solution file that is automatically loaded. Default is Avalonia.sln"
+        },
+        "Target": {
+          "type": "array",
+          "description": "List of targets to be invoked. Default is '{default_target}'",
+          "items": {
+            "type": "string",
+            "enum": [
+              "CiAzureLinux",
+              "CiAzureOSX",
+              "CiAzureWindows",
+              "Clean",
+              "Compile",
+              "CompileHtmlPreviewer",
+              "CompileNative",
+              "CreateIntermediateNugetPackages",
+              "CreateNugetPackages",
+              "GenerateCppHeaders",
+              "Package",
+              "RunCoreLibsTests",
+              "RunHtmlPreviewerTests",
+              "RunLeakTests",
+              "RunRenderTests",
+              "RunTests",
+              "RunToolsTests",
+              "ZipFiles"
+            ]
+          }
+        },
+        "Verbosity": {
+          "type": "string",
+          "description": "Logging verbosity during build execution. Default is 'Normal'",
+          "enum": [
+            "Minimal",
+            "Normal",
+            "Quiet",
+            "Verbose"
+          ]
+        }
+      }
+    }
+  }
+}

+ 4 - 0
.nuke/parameters.json

@@ -0,0 +1,4 @@
+{
+  "$schema": "./build.schema.json",
+  "Solution": ""
+}

+ 67 - 0
Avalonia.Desktop.slnf

@@ -0,0 +1,67 @@
+{
+  "solution": {
+    "path": "Avalonia.sln",
+    "projects": [
+      "packages\\Avalonia\\Avalonia.csproj",
+      "samples\\ControlCatalog.NetCore\\ControlCatalog.NetCore.csproj",
+      "samples\\ControlCatalog\\ControlCatalog.csproj",
+      "samples\\GpuInterop\\GpuInterop.csproj",
+      "samples\\IntegrationTestApp\\IntegrationTestApp.csproj",
+      "samples\\MiniMvvm\\MiniMvvm.csproj",
+      "samples\\ReactiveUIDemo\\ReactiveUIDemo.csproj",
+      "samples\\SampleControls\\ControlSamples.csproj",
+      "samples\\Sandbox\\Sandbox.csproj",
+      "src\\Avalonia.Base\\Avalonia.Base.csproj",
+      "src\\Avalonia.Build.Tasks\\Avalonia.Build.Tasks.csproj",
+      "src\\Avalonia.Controls.ColorPicker\\Avalonia.Controls.ColorPicker.csproj",
+      "src\\Avalonia.Controls.DataGrid\\Avalonia.Controls.DataGrid.csproj",
+      "src\\Avalonia.Controls.ItemsRepeater\\Avalonia.Controls.ItemsRepeater.csproj",
+      "src\\Avalonia.Controls\\Avalonia.Controls.csproj",
+      "src\\Avalonia.DesignerSupport\\Avalonia.DesignerSupport.csproj",
+      "src\\Avalonia.Desktop\\Avalonia.Desktop.csproj",
+      "src\\Avalonia.Diagnostics\\Avalonia.Diagnostics.csproj",
+      "src\\Avalonia.Dialogs\\Avalonia.Dialogs.csproj",
+      "src\\Avalonia.Fonts.Inter\\Avalonia.Fonts.Inter.csproj",
+      "src\\Avalonia.FreeDesktop\\Avalonia.FreeDesktop.csproj",
+      "src\\Avalonia.Headless.Vnc\\Avalonia.Headless.Vnc.csproj",
+      "src\\Avalonia.Headless\\Avalonia.Headless.csproj",
+      "src\\Avalonia.MicroCom\\Avalonia.MicroCom.csproj",
+      "src\\Avalonia.Native\\Avalonia.Native.csproj",
+      "src\\Avalonia.OpenGL\\Avalonia.OpenGL.csproj",
+      "src\\Avalonia.ReactiveUI\\Avalonia.ReactiveUI.csproj",
+      "src\\Avalonia.Remote.Protocol\\Avalonia.Remote.Protocol.csproj",
+      "src\\Avalonia.Themes.Fluent\\Avalonia.Themes.Fluent.csproj",
+      "src\\Avalonia.Themes.Simple\\Avalonia.Themes.Simple.csproj",
+      "src\\Avalonia.X11\\Avalonia.X11.csproj",
+      "src\\Linux\\Avalonia.LinuxFramebuffer\\Avalonia.LinuxFramebuffer.csproj",
+      "src\\Markup\\Avalonia.Markup.Xaml.Loader\\Avalonia.Markup.Xaml.Loader.csproj",
+      "src\\Markup\\Avalonia.Markup.Xaml\\Avalonia.Markup.Xaml.csproj",
+      "src\\Markup\\Avalonia.Markup\\Avalonia.Markup.csproj",
+      "src\\Skia\\Avalonia.Skia\\Avalonia.Skia.csproj",
+      "src\\Windows\\Avalonia.Direct2D1\\Avalonia.Direct2D1.csproj",
+      "src\\Windows\\Avalonia.Win32.Interop\\Avalonia.Win32.Interop.csproj",
+      "src\\Windows\\Avalonia.Win32\\Avalonia.Win32.csproj",
+      "src\\tools\\Avalonia.Generators\\Avalonia.Generators.csproj",
+      "src\\tools\\DevAnalyzers\\DevAnalyzers.csproj",
+      "src\\tools\\DevGenerators\\DevGenerators.csproj",
+      "src\\tools\\PublicAnalyzers\\Avalonia.Analyzers.csproj",
+      "tests\\Avalonia.Base.UnitTests\\Avalonia.Base.UnitTests.csproj",
+      "tests\\Avalonia.Benchmarks\\Avalonia.Benchmarks.csproj",
+      "tests\\Avalonia.Controls.DataGrid.UnitTests\\Avalonia.Controls.DataGrid.UnitTests.csproj",
+      "tests\\Avalonia.Controls.ItemsRepeater.UnitTests\\Avalonia.Controls.ItemsRepeater.UnitTests.csproj",
+      "tests\\Avalonia.Controls.UnitTests\\Avalonia.Controls.UnitTests.csproj",
+      "tests\\Avalonia.DesignerSupport.TestApp\\Avalonia.DesignerSupport.TestApp.csproj",
+      "tests\\Avalonia.DesignerSupport.Tests\\Avalonia.DesignerSupport.Tests.csproj",
+      "tests\\Avalonia.Direct2D1.RenderTests\\Avalonia.Direct2D1.RenderTests.csproj",
+      "tests\\Avalonia.Direct2D1.UnitTests\\Avalonia.Direct2D1.UnitTests.csproj",
+      "tests\\Avalonia.IntegrationTests.Appium\\Avalonia.IntegrationTests.Appium.csproj",
+      "tests\\Avalonia.LeakTests\\Avalonia.LeakTests.csproj",
+      "tests\\Avalonia.Markup.UnitTests\\Avalonia.Markup.UnitTests.csproj",
+      "tests\\Avalonia.Markup.Xaml.UnitTests\\Avalonia.Markup.Xaml.UnitTests.csproj",
+      "tests\\Avalonia.ReactiveUI.UnitTests\\Avalonia.ReactiveUI.UnitTests.csproj",
+      "tests\\Avalonia.Skia.RenderTests\\Avalonia.Skia.RenderTests.csproj",
+      "tests\\Avalonia.Skia.UnitTests\\Avalonia.Skia.UnitTests.csproj",
+      "tests\\Avalonia.UnitTests\\Avalonia.UnitTests.csproj"
+    ]
+  }
+}

+ 133 - 28
Avalonia.sln

@@ -13,7 +13,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Direct2D1", "src\W
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls", "src\Avalonia.Controls\Avalonia.Controls.csproj", "{D2221C82-4A25-4583-9B43-D791E3F6820C}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Themes.Default", "src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj", "{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Themes.Simple", "src\Avalonia.Themes.Simple\Avalonia.Themes.Simple.csproj", "{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Diagnostics", "src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj", "{7062AE20-5DCC-4442-9645-8195BDECE63E}"
 EndProject
@@ -40,7 +40,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{A689DE
 		.editorconfig = .editorconfig
 		src\Shared\IsExternalInit.cs = src\Shared\IsExternalInit.cs
 		src\Shared\ModuleInitializer.cs = src\Shared\ModuleInitializer.cs
+		src\Shared\NullableAttributes.cs = src\Shared\NullableAttributes.cs
 		src\Shared\SourceGeneratorAttributes.cs = src\Shared\SourceGeneratorAttributes.cs
+		src\Avalonia.Base\Compatibility\StringCompatibilityExtensions.cs = src\Avalonia.Base\Compatibility\StringCompatibilityExtensions.cs
 	EndProjectSection
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI", "src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj", "{6417B24E-49C2-4985-8DB2-3AB9D898EC91}"
@@ -90,6 +92,7 @@ EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1-27F5-4255-9AFC-04ABFD11683A}"
 	ProjectSection(SolutionItems) = preProject
 		build\ApiDiff.props = build\ApiDiff.props
+		build\AvaloniaPublicKey.props = build\AvaloniaPublicKey.props
 		build\Base.props = build\Base.props
 		build\Binding.props = build\Binding.props
 		build\CoreLibraries.props = build\CoreLibraries.props
@@ -97,13 +100,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1
 		build\EmbedXaml.props = build\EmbedXaml.props
 		build\HarfBuzzSharp.props = build\HarfBuzzSharp.props
 		build\ImageSharp.props = build\ImageSharp.props
-		build\JetBrains.Annotations.props = build\JetBrains.Annotations.props
 		build\JetBrains.dotMemoryUnit.props = build\JetBrains.dotMemoryUnit.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\ReactiveUI.props = build\ReactiveUI.props
 		build\ReferenceCoreLibraries.props = build\ReferenceCoreLibraries.props
 		build\Rx.props = build\Rx.props
@@ -115,6 +119,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1
 		build\SourceLink.props = build\SourceLink.props
 		build\System.Drawing.Common.props = build\System.Drawing.Common.props
 		build\System.Memory.props = build\System.Memory.props
+		build\TrimmingEnable.props = build\TrimmingEnable.props
 		build\UnitTests.NetFX.props = build\UnitTests.NetFX.props
 		build\XUnit.props = build\XUnit.props
 	EndProjectSection
@@ -130,8 +135,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linux", "Linux", "{86C53C40
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.LinuxFramebuffer", "src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj", "{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Direct3DInteropSample", "samples\interop\Direct3DInteropSample\Direct3DInteropSample.csproj", "{638580B0-7910-40EF-B674-DCB34DA308CD}"
-EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Win32.Interop", "src\Windows\Avalonia.Win32.Interop\Avalonia.Win32.Interop.csproj", "{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.RenderTests", "tests\Avalonia.Skia.RenderTests\Avalonia.Skia.RenderTests.csproj", "{E1582370-37B3-403C-917F-8209551B1634}"
@@ -194,11 +197,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTestApp", "sampl
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.IntegrationTests.Appium", "tests\Avalonia.IntegrationTests.Appium\Avalonia.IntegrationTests.Appium.csproj", "{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}"
 EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web", "Web", "{86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Web.Blazor", "src\Web\Avalonia.Web.Blazor\Avalonia.Web.Blazor.csproj", "{25831348-EB2A-483E-9576-E8F6528674A5}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Web", "samples\ControlCatalog.Web\ControlCatalog.Web.csproj", "{C08E9894-AA92-426E-BF56-033E262CAD3E}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Browser", "Browser", "{86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WindowsInteropTest", "samples\interop\WindowsInteropTest\WindowsInteropTest.csproj", "{26A98DA1-D89D-4A95-8152-349F404DA2E2}"
 EndProject
@@ -212,7 +211,46 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls.ColorPick
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DesignerSupport.Tests", "tests\Avalonia.DesignerSupport.Tests\Avalonia.DesignerSupport.Tests.csproj", "{EABE2161-989B-42BF-BD8D-1E34B20C21F1}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevGenerators", "src\tools\DevGenerators\DevGenerators.csproj", "{1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevGenerators", "src\tools\DevGenerators\DevGenerators.csproj", "{1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox", "samples\MobileSandbox\MobileSandbox.csproj", "{3B8519C1-2F51-4F12-A348-120AB91D4532}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox.Android", "samples\MobileSandbox.Android\MobileSandbox.Android.csproj", "{C90FE60B-B01E-4F35-91D6-379D6966030F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox.iOS", "samples\MobileSandbox.iOS\MobileSandbox.iOS.csproj", "{FED9A71D-00D7-4F40-A9E4-1229EEA28EEB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox.Desktop", "samples\MobileSandbox.Desktop\MobileSandbox.Desktop.csproj", "{62D392C9-81CF-487F-92E8-598B2AF3FDCE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Browser", "src\Browser\Avalonia.Browser\Avalonia.Browser.csproj", "{4A39637C-9338-4925-A4DB-D072E292EC78}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Browser.Blazor", "src\Browser\Avalonia.Browser.Blazor\Avalonia.Browser.Blazor.csproj", "{47F8530C-F19B-4B1A-B4D6-EB231522AE5D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Browser", "samples\ControlCatalog.Browser\ControlCatalog.Browser.csproj", "{15B93A4C-1B46-43F6-B534-7B25B6E99932}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Browser.Blazor", "samples\ControlCatalog.Browser.Blazor\ControlCatalog.Browser.Blazor.csproj", "{90B08091-9BBD-4362-B712-E9F2CC62B218}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUIDemo", "samples\ReactiveUIDemo\ReactiveUIDemo.csproj", "{75C47156-C5D8-44BC-A5A7-E8657C2248D6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GpuInterop", "samples\GpuInterop\GpuInterop.csproj", "{C810060E-3809-4B74-A125-F11533AF9C1B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Analyzers", "src\tools\PublicAnalyzers\Avalonia.Analyzers.csproj", "{C692FE73-43DB-49CE-87FC-F03ED61F25C9}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{176582E8-46AF-416A-85C1-13A5C6744497}"
+	ProjectSection(SolutionItems) = preProject
+		.editorconfig = .editorconfig
+	EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls.ItemsRepeater", "src\Avalonia.Controls.ItemsRepeater\Avalonia.Controls.ItemsRepeater.csproj", "{EE0F0DD4-A70D-472B-BD5D-B7D32D0E9386}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls.ItemsRepeater.UnitTests", "tests\Avalonia.Controls.ItemsRepeater.UnitTests\Avalonia.Controls.ItemsRepeater.UnitTests.csproj", "{F4E36AA8-814E-4704-BC07-291F70F45193}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Generators", "src\tools\Avalonia.Generators\Avalonia.Generators.csproj", "{DDA28789-C21A-4654-86CE-D01E81F095C5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Generators.Tests", "tests\Avalonia.Generators.Tests\Avalonia.Generators.Tests.csproj", "{2D7C812B-7E73-4252-8EFD-BC8A4D5CCB9F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Fonts.Inter", "src\Avalonia.Fonts.Inter\Avalonia.Fonts.Inter.csproj", "{13F1135D-BA1A-435C-9C5B-A368D1D63DE4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Generators.Sandbox", "samples\Generators.Sandbox\Generators.Sandbox.csproj", "{A82AD1BC-EBE6-4FC3-A13B-D52A50297533}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -346,10 +384,6 @@ Global
 		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|Any CPU.Build.0 = Release|Any CPU
-		{638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{638580B0-7910-40EF-B674-DCB34DA308CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{638580B0-7910-40EF-B674-DCB34DA308CD}.Release|Any CPU.Build.0 = Release|Any CPU
 		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -399,9 +433,7 @@ Global
 		{BF28998D-072C-439A-AFBB-2FE5021241E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{BF28998D-072C-439A-AFBB-2FE5021241E0}.Release|Any CPU.Build.0 = Release|Any CPU
 		{3F00BC43-5095-477F-93D8-E65B08179A00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{3F00BC43-5095-477F-93D8-E65B08179A00}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{3F00BC43-5095-477F-93D8-E65B08179A00}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{3F00BC43-5095-477F-93D8-E65B08179A00}.Release|Any CPU.Build.0 = Release|Any CPU
 		{41B02319-965D-4945-8005-C1A3D1224165}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{41B02319-965D-4945-8005-C1A3D1224165}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{41B02319-965D-4945-8005-C1A3D1224165}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -466,14 +498,6 @@ Global
 		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|Any CPU.Build.0 = Release|Any CPU
-		{25831348-EB2A-483E-9576-E8F6528674A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{25831348-EB2A-483E-9576-E8F6528674A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{25831348-EB2A-483E-9576-E8F6528674A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{25831348-EB2A-483E-9576-E8F6528674A5}.Release|Any CPU.Build.0 = Release|Any CPU
-		{C08E9894-AA92-426E-BF56-033E262CAD3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{C08E9894-AA92-426E-BF56-033E262CAD3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{C08E9894-AA92-426E-BF56-033E262CAD3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{C08E9894-AA92-426E-BF56-033E262CAD3E}.Release|Any CPU.Build.0 = Release|Any CPU
 		{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -502,6 +526,75 @@ Global
 		{1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB}.Release|Any CPU.Build.0 = Release|Any CPU
+		{3B8519C1-2F51-4F12-A348-120AB91D4532}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3B8519C1-2F51-4F12-A348-120AB91D4532}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3B8519C1-2F51-4F12-A348-120AB91D4532}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3B8519C1-2F51-4F12-A348-120AB91D4532}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C90FE60B-B01E-4F35-91D6-379D6966030F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C90FE60B-B01E-4F35-91D6-379D6966030F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C90FE60B-B01E-4F35-91D6-379D6966030F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+		{C90FE60B-B01E-4F35-91D6-379D6966030F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C90FE60B-B01E-4F35-91D6-379D6966030F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{FED9A71D-00D7-4F40-A9E4-1229EEA28EEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{FED9A71D-00D7-4F40-A9E4-1229EEA28EEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{FED9A71D-00D7-4F40-A9E4-1229EEA28EEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{FED9A71D-00D7-4F40-A9E4-1229EEA28EEB}.Release|Any CPU.Build.0 = Release|Any CPU
+		{62D392C9-81CF-487F-92E8-598B2AF3FDCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{62D392C9-81CF-487F-92E8-598B2AF3FDCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{62D392C9-81CF-487F-92E8-598B2AF3FDCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{62D392C9-81CF-487F-92E8-598B2AF3FDCE}.Release|Any CPU.Build.0 = Release|Any CPU
+		{4A39637C-9338-4925-A4DB-D072E292EC78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4A39637C-9338-4925-A4DB-D072E292EC78}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{4A39637C-9338-4925-A4DB-D072E292EC78}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{4A39637C-9338-4925-A4DB-D072E292EC78}.Release|Any CPU.Build.0 = Release|Any CPU
+		{47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{15B93A4C-1B46-43F6-B534-7B25B6E99932}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{15B93A4C-1B46-43F6-B534-7B25B6E99932}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{15B93A4C-1B46-43F6-B534-7B25B6E99932}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{15B93A4C-1B46-43F6-B534-7B25B6E99932}.Release|Any CPU.Build.0 = Release|Any CPU
+		{90B08091-9BBD-4362-B712-E9F2CC62B218}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{90B08091-9BBD-4362-B712-E9F2CC62B218}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{90B08091-9BBD-4362-B712-E9F2CC62B218}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{90B08091-9BBD-4362-B712-E9F2CC62B218}.Release|Any CPU.Build.0 = Release|Any CPU
+		{75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C810060E-3809-4B74-A125-F11533AF9C1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C810060E-3809-4B74-A125-F11533AF9C1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C810060E-3809-4B74-A125-F11533AF9C1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C810060E-3809-4B74-A125-F11533AF9C1B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C692FE73-43DB-49CE-87FC-F03ED61F25C9}.Debug|Any CPU.ActiveCfg = Release|Any CPU
+		{C692FE73-43DB-49CE-87FC-F03ED61F25C9}.Debug|Any CPU.Build.0 = Release|Any CPU
+		{C692FE73-43DB-49CE-87FC-F03ED61F25C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C692FE73-43DB-49CE-87FC-F03ED61F25C9}.Release|Any CPU.Build.0 = Release|Any CPU
+		{EE0F0DD4-A70D-472B-BD5D-B7D32D0E9386}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{EE0F0DD4-A70D-472B-BD5D-B7D32D0E9386}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{EE0F0DD4-A70D-472B-BD5D-B7D32D0E9386}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{EE0F0DD4-A70D-472B-BD5D-B7D32D0E9386}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F4E36AA8-814E-4704-BC07-291F70F45193}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F4E36AA8-814E-4704-BC07-291F70F45193}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F4E36AA8-814E-4704-BC07-291F70F45193}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F4E36AA8-814E-4704-BC07-291F70F45193}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DDA28789-C21A-4654-86CE-D01E81F095C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DDA28789-C21A-4654-86CE-D01E81F095C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DDA28789-C21A-4654-86CE-D01E81F095C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DDA28789-C21A-4654-86CE-D01E81F095C5}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2D7C812B-7E73-4252-8EFD-BC8A4D5CCB9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2D7C812B-7E73-4252-8EFD-BC8A4D5CCB9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2D7C812B-7E73-4252-8EFD-BC8A4D5CCB9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2D7C812B-7E73-4252-8EFD-BC8A4D5CCB9F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{13F1135D-BA1A-435C-9C5B-A368D1D63DE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{13F1135D-BA1A-435C-9C5B-A368D1D63DE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{13F1135D-BA1A-435C-9C5B-A368D1D63DE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{13F1135D-BA1A-435C-9C5B-A368D1D63DE4}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A82AD1BC-EBE6-4FC3-A13B-D52A50297533}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A82AD1BC-EBE6-4FC3-A13B-D52A50297533}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A82AD1BC-EBE6-4FC3-A13B-D52A50297533}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A82AD1BC-EBE6-4FC3-A13B-D52A50297533}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -533,7 +626,6 @@ Global
 		{7D2D3083-71DD-4CC9-8907-39A0D86FB322} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
 		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B}
-		{638580B0-7910-40EF-B674-DCB34DA308CD} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9}
 		{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}
@@ -545,21 +637,34 @@ Global
 		{41B02319-965D-4945-8005-C1A3D1224165} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B}
 		{D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
+		{4D36CEC8-53F2-40A5-9A37-79AAE356E2DA} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B}
 		{351337F5-D66F-461B-A957-4EF60BDB4BA6} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{909A8CBD-7D0E-42FD-B841-022AD8925820} = {8B6A8209-894F-4BA1-B880-965FD453982C}
 		{11BE52AF-E2DD-4CF0-B19A-05285ACAF571} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{BC594FD5-4AF2-409E-A1E6-04123F54D7C5} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{676D6BFD-029D-4E43-BFC7-3892265CE251} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
-		{25831348-EB2A-483E-9576-E8F6528674A5} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}
-		{C08E9894-AA92-426E-BF56-033E262CAD3E} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{26A98DA1-D89D-4A95-8152-349F404DA2E2} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9}
 		{A0D0A6A4-5C72-4ADA-9B27-621C7D94F270} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{2B390431-288C-435C-BB6B-A374033BD8D1} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
 		{EABE2161-989B-42BF-BD8D-1E34B20C21F1} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
-		{4D36CEC8-53F2-40A5-9A37-79AAE356E2DA} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B}
+		{3B8519C1-2F51-4F12-A348-120AB91D4532} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+		{C90FE60B-B01E-4F35-91D6-379D6966030F} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+		{FED9A71D-00D7-4F40-A9E4-1229EEA28EEB} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+		{62D392C9-81CF-487F-92E8-598B2AF3FDCE} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+		{4A39637C-9338-4925-A4DB-D072E292EC78} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}
+		{47F8530C-F19B-4B1A-B4D6-EB231522AE5D} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}
+		{15B93A4C-1B46-43F6-B534-7B25B6E99932} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+		{90B08091-9BBD-4362-B712-E9F2CC62B218} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+		{75C47156-C5D8-44BC-A5A7-E8657C2248D6} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+		{C810060E-3809-4B74-A125-F11533AF9C1B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+		{C692FE73-43DB-49CE-87FC-F03ED61F25C9} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
+		{DDA28789-C21A-4654-86CE-D01E81F095C5} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
+		{2D7C812B-7E73-4252-8EFD-BC8A4D5CCB9F} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
+		{F4E36AA8-814E-4704-BC07-291F70F45193} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
+		{A82AD1BC-EBE6-4FC3-A13B-D52A50297533} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}

+ 1 - 0
Directory.Build.props

@@ -7,5 +7,6 @@
       <AddSyntheticProjectReferencesForSolutionDependencies>false</AddSyntheticProjectReferencesForSolutionDependencies>
       <MSBuildEnableWorkloadResolver>false</MSBuildEnableWorkloadResolver>
       <RunApiCompat>False</RunApiCompat>
+      <LangVersion>11</LangVersion>
   </PropertyGroup>
 </Project>

+ 5 - 0
Directory.Build.targets

@@ -0,0 +1,5 @@
+<Project>
+  <PropertyGroup Condition="$(NETCoreSdkVersion.StartsWith('7.0'))">
+    <DefineConstants>$(DefineConstants);NET7SDK</DefineConstants>
+  </PropertyGroup>  
+</Project>

+ 26 - 12
Documentation/build.md

@@ -1,8 +1,8 @@
 # Windows
 
-Avalonia requires at least Visual Studio 2022 and dotnet 6 SDK 6.0.100 to build on all platforms.
+Avalonia requires at least Visual Studio 2022 and dotnet 7-rc2 SDK 7.0.100-rc.2 to build on all platforms.
 
-###  Clone the Avalonia repository
+##  Clone the Avalonia repository
 
 ```
 git clone https://github.com/AvaloniaUI/Avalonia.git
@@ -10,15 +10,30 @@ cd Avalonia
 git submodule update --init
 ```
 
-### Install the required version of the .NET Core SDK
+## Install the required version of the .NET Core SDK
 
 Go to https://dotnet.microsoft.com/download/visual-studio-sdks and install the latest version of the .NET Core SDK compatible with Avalonia UI. Make sure to download the SDK (not just the "runtime") package. The version compatible is indicated within the [global.json](https://github.com/AvaloniaUI/Avalonia/blob/master/global.json) file. Note that Avalonia UI does not always use the latest version and is hardcoded to use the last version known to be compatible (SDK releases may break the builds from time-to-time).
 
-###  Open in Visual Studio
+##  Build and Run Avalonia
 
-Open the `Avalonia.sln` solution in Visual Studio 2022 or newer. The free Visual Studio Community edition works fine. Build and run the `Samples\ControlCatalog.Desktop` or `ControlCatalog.NetCore` project to see the sample application.
+```
+cd samples\ControlCatalog.NetCore
+dotnet restore
+dotnet run
+```
+
+##  Opening in Visual Studio
 
-### Troubleshooting
+If you want to open Avalonia in Visual Studio you have two options:
+
+- Avalonia.sln: This contains the whole of Avalonia in including desktop, mobile and web. You must have a number of dotnet workloads installed in order to build everything in this solution
+- Avalonia.Desktop.slnf: This solution filter opens only the parts of Avalonia required to run on desktop. This requires no extra workloads to be installed.
+
+Avalonia requires Visual Studio 2022 or newer. The free Visual Studio Community edition works fine.
+
+Build and run `ControlCatalog.NetCore` project to see the sample application.
+
+### Visual Studio Troubleshooting
 
  * **Error CS0006: Avalonia.DesktopRuntime.dll could not be found**
 
@@ -35,16 +50,15 @@ It's *not* possible to build the *whole* project on Linux/macOS. You can only bu
 
 MonoDevelop, Xamarin Studio and Visual Studio for Mac aren't capable of properly opening our solution. You can use Rider (at least 2017.2 EAP) or VSCode instead. They will fail to load most of platform specific projects, but you don't need them to run on .NET Core.
 
-###  Install the latest version of the .NET Core SDK
+##  Install the latest version of the .NET Core SDK
 
 Go to https://www.microsoft.com/net/core and follow the instructions for your OS. Make sure to download the SDK (not just the "runtime") package.
 
-###  Additional requirements for macOS
+##  Additional requirements for macOS
 
 The build process needs [Xcode](https://developer.apple.com/xcode/) to build the native library.  Following the install instructions at the [Xcode](https://developer.apple.com/xcode/) website to properly install.
 
-
-###  Clone the Avalonia repository
+##  Clone the Avalonia repository
 
 ```
 git clone https://github.com/AvaloniaUI/Avalonia.git
@@ -52,7 +66,7 @@ cd Avalonia
 git submodule update --init --recursive
 ```
 
-### Build native libraries (macOS only)
+## Build native libraries (macOS only)
 
 On macOS it is necessary to build and manually install the respective native libraries using [Xcode](https://developer.apple.com/xcode/). Execute the build script in the root project with the `CompileNative` task. It will build the headers, build the libraries, and place them in the appropriate place to allow .NET to find them at compilation and run time.
 
@@ -60,7 +74,7 @@ On macOS it is necessary to build and manually install the respective native lib
 ./build.sh CompileNative
 ```
 
-###  Build and Run Avalonia
+##  Build and Run Avalonia
 
 ```
 cd samples/ControlCatalog.NetCore

+ 70 - 11
NOTICE.md

@@ -81,14 +81,14 @@ A "contributor" is any person that distributes its contribution under this licen
 
 https://github.com/wayland-project/wayland-protocols
 
-Copyright © 2008-2013 Kristian Høgsberg
-Copyright © 2010-2013 Intel Corporation
-Copyright © 2013      Rafael Antognolli
-Copyright © 2013      Jasper St. Pierre
-Copyright © 2014      Jonas Ådahl
-Copyright © 2014      Jason Ekstrand
-Copyright © 2014-2015 Collabora, Ltd.
-Copyright © 2015      Red Hat Inc.
+Copyright © 2008-2013 Kristian Høgsberg
+Copyright © 2010-2013 Intel Corporation
+Copyright © 2013      Rafael Antognolli
+Copyright © 2013      Jasper St. Pierre
+Copyright © 2014      Jonas Ådahl
+Copyright © 2014      Jason Ekstrand
+Copyright © 2014-2015 Collabora, Ltd.
+Copyright © 2015      Red Hat Inc.
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -111,7 +111,7 @@ DEALINGS IN THE SOFTWARE.
 
 # Metsys.Bson
 
-Copyright (c) 2010, Karl Seguin - http://www.openmymind.net/
+Copyright (c) 2010, Karl Seguin - https://www.openmymind.net/
 All rights reserved.
  
 Redistribution and use in source and binary forms, with or without
@@ -140,7 +140,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 https://github.com/toptensoftware/RichTextKit
 
-Copyright © 2019 Topten Software. All Rights Reserved.
+Copyright © 2019 Topten Software. All Rights Reserved.
 
 Licensed under the Apache License, Version 2.0 (the "License"); you may 
 not use this product except in compliance with the License. You may obtain 
@@ -302,4 +302,63 @@ https://github.com/chromium/chromium
 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Flutter
+
+https://github.com/flutter/flutter
+
+//Copyright 2014 The Flutter Authors. All rights reserved.
+
+//Redistribution and use in source and binary forms, with or without modification,
+//are permitted provided that the following conditions are met:
+
+//    * Redistributions of source code must retain the above copyright
+//      notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+//      copyright notice, this list of conditions and the following
+//      disclaimer in the documentation and/or other materials provided
+//      with the distribution.
+//    * Neither the name of Google Inc. nor the names of its
+//      contributors may be used to endorse or promote products derived
+//      from this software without specific prior written permission.
+
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+//DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+//ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+//LOSS OF USE, DATA, OR PROFITS;
+//OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+//ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+//(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Reactive Extensions
+
+https://github.com/dotnet/reactive
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.

+ 36 - 12
azure-pipelines-integrationtests.yml

@@ -1,39 +1,55 @@
-# Starter pipeline
-# Start with a minimal pipeline that you can customize to build and deploy your code.
-# Add steps that build, run tests, deploy, and more:
-# https://aka.ms/yaml
-
-trigger:
-- master
-
 jobs:
 - job: Mac
   pool:
     name: 'AvaloniaMacPool'
 
   steps:
+  - task: UseDotNet@2
+    displayName: 'Use .NET Core SDK 6.0.404'
+    inputs:
+      version: 6.0.404
+
+  - task: UseDotNet@2
+    displayName: 'Use .NET Core SDK 7.0.101'
+    inputs:
+      version: 7.0.101
+      
   - script: system_profiler SPDisplaysDataType |grep Resolution
+    displayName: 'Get Resolution'
   
   - script: |
+      arch="x64"
+      if [[ $(uname -m) == 'arm64' ]]; then
+      arch="arm64"
+      fi
+      sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
       pkill node
-      appium &
+      pkill testmanagerd
+      appium > appium.out &
       pkill IntegrationTestApp
       ./build.sh CompileNative
       rm -rf $(osascript -e "POSIX path of (path to application id \"net.avaloniaui.avalonia.integrationtestapp\")")
       pkill IntegrationTestApp
       ./samples/IntegrationTestApp/bundle.sh
-      open -n ./samples/IntegrationTestApp/bin/Debug/net6.0/osx-arm64/publish/IntegrationTestApp.app
+      open -n ./samples/IntegrationTestApp/bin/Debug/net7.0/osx-$arch/publish/IntegrationTestApp.app
       pkill IntegrationTestApp
+    displayName: 'Build IntegrationTestApp'
 
   - task: DotNetCoreCLI@2
+    displayName: 'Run Integration Tests'
     inputs:
       command: 'test'
       projects: 'tests/Avalonia.IntegrationTests.Appium/Avalonia.IntegrationTests.Appium.csproj'
+      arguments: '-l "console;verbosity=detailed"'
 
   - script: |
       pkill IntegrationTestApp
       pkill node
+    displayName: 'Stop Appium'
 
+  - publish: appium.out
+    displayName: 'Publish appium logs on failure'
+    condition: failed()
 
 - job: Windows
   pool:
@@ -41,9 +57,14 @@ jobs:
 
   steps:
   - task: UseDotNet@2
-    displayName: 'Use .NET Core SDK 6.0.202'
+    displayName: 'Use .NET Core SDK 6.0.404'
+    inputs:
+      version: 6.0.404
+
+  - task: UseDotNet@2
+    displayName: 'Use .NET Core SDK 7.0.101'
     inputs:
-      version: 6.0.202
+      version: 7.0.101
 
   - task: Windows Application Driver@0
     inputs:
@@ -52,11 +73,14 @@ jobs:
     displayName: 'Start WinAppDriver'
   
   - task: DotNetCoreCLI@2
+    displayName: 'Build IntegrationTestApp'
     inputs:
       command: 'build'
       projects: 'samples/IntegrationTestApp/IntegrationTestApp.csproj'
 
   - task: DotNetCoreCLI@2
+    displayName: 'Run Integration Tests'
+    retryCountOnTaskFailure: 3
     inputs:
       command: 'test'
       projects: 'tests/Avalonia.IntegrationTests.Appium/Avalonia.IntegrationTests.Appium.csproj'

+ 27 - 23
azure-pipelines.yml

@@ -6,7 +6,6 @@ jobs:
   variables:
     SolutionDir: '$(Build.SourcesDirectory)'
   steps:
-    
   - task: PowerShell@2
     displayName: Get PR Number
     inputs:
@@ -31,14 +30,20 @@ jobs:
     vmImage: 'ubuntu-20.04'
   steps:
   - task: UseDotNet@2
-    displayName: 'Use .NET Core SDK 3.1.418'
+    displayName: 'Use .NET Core SDK 6.0.404'
     inputs:
-      version: 3.1.418
+      version: 6.0.404
 
   - task: UseDotNet@2
-    displayName: 'Use .NET Core SDK 6.0.202'
+    displayName: 'Use .NET Core SDK 7.0.101'
+    inputs:
+      version: 7.0.101
+
+  - task: CmdLine@2
+    displayName: 'Install Workloads'
     inputs:
-      version: 6.0.202
+      script: |
+       dotnet workload install wasm-tools wasm-experimental
 
   - task: CmdLine@2
     displayName: 'Run Build'
@@ -59,25 +64,24 @@ jobs:
   variables:
     SolutionDir: '$(Build.SourcesDirectory)'
   pool:
-    vmImage: 'macOS-10.15'
+    vmImage: 'macos-12'
   steps:
   - task: UseDotNet@2
-    displayName: 'Use .NET Core SDK 3.1.418'
+    displayName: 'Use .NET Core SDK 6.0.404'
     inputs:
-      version: 3.1.418
+      version: 6.0.404
 
   - task: UseDotNet@2
-    displayName: 'Use .NET Core SDK 6.0.202'
+    displayName: 'Use .NET Core SDK 7.0.101'
     inputs:
-      version: 6.0.202
-      
+      version: 7.0.101
+
   - task: CmdLine@2
-    displayName: 'Install Mono 5.18'
+    displayName: 'Install Workloads'
     inputs:
       script: |
-        curl -o ./mono.pkg https://download.mono-project.com/archive/5.18.0/macos-10-universal/MonoFramework-MDK-5.18.0.225.macos10.xamarin.universal.pkg 
-        sudo installer -verbose -pkg ./mono.pkg -target /
-
+       dotnet workload install wasm-tools wasm-experimental
+      
   - task: CmdLine@2
     displayName: 'Generate avalonia-native'
     inputs:
@@ -91,10 +95,10 @@ jobs:
     inputs:
       actions: 'build'
       scheme: ''
-      sdk: 'macosx11.1'
+      sdk: 'macosx12.3'
       configuration: 'Release'
       xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
-      xcodeVersion: '12' # Options: 8, 9, default, specifyPath
+      xcodeVersion: '13' # Options: 8, 9, default, specifyPath
       args: '-derivedDataPath ./'
 
   - task: CmdLine@2
@@ -134,26 +138,26 @@ jobs:
     SolutionDir: '$(Build.SourcesDirectory)'
   steps:
   - task: UseDotNet@2
-    displayName: 'Use .NET Core SDK 3.1.418'
+    displayName: 'Use .NET Core SDK 6.0.404'
     inputs:
-      version: 3.1.418
+      version: 6.0.404
 
   - task: UseDotNet@2
-    displayName: 'Use .NET Core SDK 6.0.202'
+    displayName: 'Use .NET Core SDK 7.0.101'
     inputs:
-      version: 6.0.202
+      version: 7.0.101
 
   - task: CmdLine@2
     displayName: 'Install Workloads'
     inputs:
       script: |
-       dotnet workload install android ios
+       dotnet workload install android ios wasm-tools wasm-experimental
 
   - task: CmdLine@2
     displayName: 'Install Nuke'
     inputs:
       script: |
-       dotnet tool install --global Nuke.GlobalTool --version 0.24.0 
+       dotnet tool install --global Nuke.GlobalTool --version 6.2.1 
 
   - task: CmdLine@2
     displayName: 'Run Nuke'

+ 7 - 0
build.cmd

@@ -0,0 +1,7 @@
+:; set -eo pipefail
+:; SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
+:; ${SCRIPT_DIR}/build.sh "$@"
+:; exit $?
+
+@ECHO OFF
+powershell -ExecutionPolicy ByPass -NoProfile -File "%~dp0build.ps1" %*

+ 24 - 26
build.ps1

@@ -1,13 +1,12 @@
 [CmdletBinding()]
 Param(
-    #[switch]$CustomParam,
     [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
     [string[]]$BuildArguments
 )
 
-Write-Output "Windows PowerShell $($Host.Version)"
+Write-Output "PowerShell $($PSVersionTable.PSEdition) version $($PSVersionTable.PSVersion)"
 
-Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { exit 1 }
+Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { Write-Error $_ -ErrorAction Continue; exit 1 }
 $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
 
 ###########################################################################
@@ -15,15 +14,15 @@ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
 ###########################################################################
 
 $BuildProjectFile = "$PSScriptRoot\nukebuild\_build.csproj"
-$TempDirectory = "$PSScriptRoot\\.tmp"
+$TempDirectory = "$PSScriptRoot\\.nuke\temp"
 
 $DotNetGlobalFile = "$PSScriptRoot\\global.json"
-$DotNetInstallUrl = "https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.ps1"
+$DotNetInstallUrl = "https://dot.net/v1/dotnet-install.ps1"
 $DotNetChannel = "Current"
 
 $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 1
 $env:DOTNET_CLI_TELEMETRY_OPTOUT = 1
-$env:NUGET_XMLDOC_MODE = "skip"
+$env:DOTNET_MULTILEVEL_LOOKUP = 0
 
 ###########################################################################
 # EXECUTION
@@ -34,38 +33,37 @@ function ExecSafe([scriptblock] $cmd) {
     if ($LASTEXITCODE) { exit $LASTEXITCODE }
 }
 
-# If global.json exists, load expected version
-if (Test-Path $DotNetGlobalFile) {
-    $DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json)
-    if ($DotNetGlobal.PSObject.Properties["sdk"] -and $DotNetGlobal.sdk.PSObject.Properties["version"]) {
-        $DotNetVersion = $DotNetGlobal.sdk.version
-    }
-}
-
-# If dotnet is installed locally, and expected version is not set or installation matches the expected version
+# If dotnet CLI is installed globally and it matches requested version, use for execution
 if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and `
-     (!(Test-Path variable:DotNetVersion) -or $(& dotnet --version) -eq $DotNetVersion)) {
+     $(dotnet --version) -and $LASTEXITCODE -eq 0) {
     $env:DOTNET_EXE = (Get-Command "dotnet").Path
 }
 else {
-    $DotNetDirectory = "$TempDirectory\dotnet-win"
-    $env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe"
-
     # Download install script
     $DotNetInstallFile = "$TempDirectory\dotnet-install.ps1"
-    mkdir -force $TempDirectory > $null
+    New-Item -ItemType Directory -Path $TempDirectory -Force | Out-Null
+    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
     (New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile)
 
+    # If global.json exists, load expected version
+    if (Test-Path $DotNetGlobalFile) {
+        $DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json)
+        if ($DotNetGlobal.PSObject.Properties["sdk"] -and $DotNetGlobal.sdk.PSObject.Properties["version"]) {
+            $DotNetVersion = $DotNetGlobal.sdk.version
+        }
+    }
+
     # Install by channel or version
+    $DotNetDirectory = "$TempDirectory\dotnet-win"
     if (!(Test-Path variable:DotNetVersion)) {
-        ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath }
+        ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath }
     } else {
-        ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath }
+        ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath }
     }
-
-    $env:PATH="$DotNetDirectory;$env:PATH"
+    $env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe"
 }
 
-Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)"
+Write-Output "Microsoft (R) .NET SDK version $(& $env:DOTNET_EXE --version)"
 
-ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile -- $BuildArguments }
+ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet }
+ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments }

+ 46 - 14
build.sh

@@ -1,16 +1,6 @@
 #!/usr/bin/env bash
 
-echo $(bash --version 2>&1 | head -n 1)
-
-#CUSTOMPARAM=0
-BUILD_ARGUMENTS=()
-for i in "$@"; do
-    case $(echo $1 | awk '{print tolower($0)}') in
-        # -custom-param) CUSTOMPARAM=1;;
-        *) BUILD_ARGUMENTS+=("$1") ;;
-    esac
-    shift
-done
+bash --version 2>&1 | head -n 1
 
 set -eo pipefail
 SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
@@ -20,11 +10,53 @@ SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
 ###########################################################################
 
 BUILD_PROJECT_FILE="$SCRIPT_DIR/nukebuild/_build.csproj"
+TEMP_DIRECTORY="$SCRIPT_DIR//.nuke/temp"
+
+DOTNET_GLOBAL_FILE="$SCRIPT_DIR//global.json"
+DOTNET_INSTALL_URL="https://dot.net/v1/dotnet-install.sh"
+DOTNET_CHANNEL="Current"
 
 export DOTNET_CLI_TELEMETRY_OPTOUT=1
 export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
-export NUGET_XMLDOC_MODE="skip"
+export DOTNET_MULTILEVEL_LOOKUP=0
 
-dotnet --info
+###########################################################################
+# EXECUTION
+###########################################################################
 
-dotnet run --project "$BUILD_PROJECT_FILE" -- ${BUILD_ARGUMENTS[@]}
+function FirstJsonValue {
+    perl -nle 'print $1 if m{"'"$1"'": "([^"]+)",?}' <<< "${@:2}"
+}
+
+# If dotnet CLI is installed globally and it matches requested version, use for execution
+if [ -x "$(command -v dotnet)" ] && dotnet --version &>/dev/null; then
+    export DOTNET_EXE="$(command -v dotnet)"
+else
+    # Download install script
+    DOTNET_INSTALL_FILE="$TEMP_DIRECTORY/dotnet-install.sh"
+    mkdir -p "$TEMP_DIRECTORY"
+    curl -Lsfo "$DOTNET_INSTALL_FILE" "$DOTNET_INSTALL_URL"
+    chmod +x "$DOTNET_INSTALL_FILE"
+
+    # If global.json exists, load expected version
+    if [[ -f "$DOTNET_GLOBAL_FILE" ]]; then
+        DOTNET_VERSION=$(FirstJsonValue "version" "$(cat "$DOTNET_GLOBAL_FILE")")
+        if [[ "$DOTNET_VERSION" == ""  ]]; then
+            unset DOTNET_VERSION
+        fi
+    fi
+
+    # Install by channel or version
+    DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix"
+    if [[ -z ${DOTNET_VERSION+x} ]]; then
+        "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --channel "$DOTNET_CHANNEL" --no-path
+    else
+        "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" --no-path
+    fi
+    export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet"
+fi
+
+echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)"
+
+"$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet
+"$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@"

+ 4 - 1
build/Base.props

@@ -1,6 +1,9 @@
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
+  <!-- '!NET6_0_OR_GREATER' equivalent -->
+  <ItemGroup Condition="!('$(TargetFrameworkIdentifier)' == '.NETCoreApp' AND $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '6.0')))">
     <PackageReference Include="System.ValueTuple" Version="4.5.0" />
+    <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
+    <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
     <PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.6.0" />
   </ItemGroup>
 </Project>

+ 1 - 0
build/BuildTargets.targets

@@ -3,6 +3,7 @@
     <AvaloniaBuildTasksLocation>$(MSBuildThisFileDirectory)\..\src\Avalonia.Build.Tasks\bin\$(Configuration)\netstandard2.0\Avalonia.Build.Tasks.dll</AvaloniaBuildTasksLocation>
     <AvaloniaUseExternalMSBuild>true</AvaloniaUseExternalMSBuild>
     <AvaloniaXamlIlVerifyIl>true</AvaloniaXamlIlVerifyIl>
+    <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
   </PropertyGroup>
   <Import Project="$(MSBuildThisFileDirectory)\..\packages\Avalonia\AvaloniaBuildTasks.props"/>
   <Import Project="$(MSBuildThisFileDirectory)\..\packages\Avalonia\AvaloniaBuildTasks.targets"/>

+ 5 - 0
build/DevAnalyzers.props

@@ -5,5 +5,10 @@
                       ReferenceOutputAssembly="false"
                       OutputItemType="Analyzer"
                       SetTargetFramework="TargetFramework=netstandard2.0"/>
+    <ProjectReference Include="$(MSBuildThisFileDirectory)..\src\tools\PublicAnalyzers\Avalonia.Analyzers.csproj"
+                      PrivateAssets="all"
+                      ReferenceOutputAssembly="false"
+                      OutputItemType="Analyzer"
+                      SetTargetFramework="TargetFramework=netstandard2.0"/>
   </ItemGroup>
 </Project>

+ 3 - 3
build/HarfBuzzSharp.props

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

+ 1 - 1
build/ImageSharp.props

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

+ 0 - 5
build/JetBrains.Annotations.props

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

+ 1 - 1
build/Moq.props

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

+ 5 - 0
build/NetAnalyzers.props

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

+ 1 - 1
build/ReactiveUI.props

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

+ 3 - 3
build/SharedVersion.props

@@ -2,13 +2,13 @@
   xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
     <Product>Avalonia</Product>
-    <Version>0.10.999</Version>
+    <Version>11.0.999</Version>
+    <Authors>Avalonia Team</Authors>
     <Copyright>Copyright 2022 &#169; The AvaloniaUI Project</Copyright>
     <PackageProjectUrl>https://avaloniaui.net</PackageProjectUrl>
     <RepositoryUrl>https://github.com/AvaloniaUI/Avalonia/</RepositoryUrl>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <NoWarn>CS1591</NoWarn>
-    <LangVersion>latest</LangVersion>
+    <NoWarn>$(NoWarn);CS1591</NoWarn>
     <PackageLicenseExpression>MIT</PackageLicenseExpression>
     <PackageIcon>Icon.png</PackageIcon>
     <PackageDescription>Avalonia is a cross-platform UI framework for .NET providing a flexible styling system and supporting a wide range of Operating Systems such as Windows, Linux, macOS and with experimental support for Android, iOS and WebAssembly.</PackageDescription>

+ 10 - 5
build/SharpDX.props

@@ -1,9 +1,14 @@
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <SharpDXPackageVersion>4.0.1</SharpDXPackageVersion>
+  </PropertyGroup>
   <ItemGroup>
-    <PackageReference Include="SharpDX" Version="4.0.1" />
-    <PackageReference Include="SharpDX.Direct2D1" Version="4.0.1" />
-    <PackageReference Include="SharpDX.Direct3D11" Version="4.0.1" />
-    <PackageReference Include="SharpDX.DXGI" Version="4.0.1" />
-    <PackageReference Include="SharpDX.Direct3D9" Version="4.0.1" Condition="'$(UseDirect3D9)' == 'true'" />
+    <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>

+ 3 - 3
build/SkiaSharp.props

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

+ 16 - 1
build/SourceGenerators.props

@@ -1,5 +1,10 @@
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
+  <PropertyGroup>
+    <IncludeDevGenerators Condition="'$(IncludeDevGenerators)' == ''">true</IncludeDevGenerators>
+    <IncludeAvaloniaGenerators Condition="'$(IncludeAvaloniaGenerators)' == ''">false</IncludeAvaloniaGenerators>
+  </PropertyGroup>
+
+  <ItemGroup Condition="'$(IncludeDevGenerators)' == 'true'">
     <ProjectReference 
       Include="$(MSBuildThisFileDirectory)/../src/tools/DevGenerators/DevGenerators.csproj"
       OutputItemType="Analyzer" 
@@ -7,4 +12,14 @@
       PrivateAssets="all" />
     <Compile Include="$(MSBuildThisFileDirectory)/../src/Shared/SourceGeneratorAttributes.cs" />
   </ItemGroup>
+
+  <ItemGroup Condition="'$(IncludeAvaloniaGenerators)' == 'true'">
+    <ProjectReference
+      Include="../../src/tools/Avalonia.Generators/Avalonia.Generators.csproj"
+      OutputItemType="Analyzer"
+      ReferenceOutputAssembly="false"
+      PrivateAssets="all" />
+  </ItemGroup>
+  <Import Project="$(MSBuildThisFileDirectory)/../src/tools/Avalonia.Generators/Avalonia.Generators.props"
+          Condition="'$(IncludeDevGenerators)' == 'true'" />
 </Project>

+ 2 - 1
build/System.Memory.props

@@ -1,5 +1,6 @@
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
+  <!-- '!NET6_0_OR_GREATER' equivalent -->
+  <ItemGroup Condition="!('$(TargetFrameworkIdentifier)' == '.NETCoreApp' AND $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '6.0')))">
     <PackageReference Include="System.Memory" Version="4.5.3" />
   </ItemGroup>
 </Project>

+ 16 - 0
build/TrimmingEnable.props

@@ -0,0 +1,16 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
+    <EnableTrimAnalyzer>true</EnableTrimAnalyzer>
+    <TrimmerSingleWarn>false</TrimmerSingleWarn>
+    <IsTrimmable>true</IsTrimmable>
+  </PropertyGroup>
+  <!-- Remove check for the AOT when we get rid of dependencies with reflection -->
+  <PropertyGroup Condition="'$(TargetFramework)' != 'netstandard2.0' and '$(PublishAot)' != 'true'">
+    <ILLinkTreatWarningsAsErrors>true</ILLinkTreatWarningsAsErrors>
+    <!-- Trim warnings -->
+    <WarningsAsErrors>$(WarningsAsErrors);IL2000;IL2001;IL2002;IL2003;IL2004;IL2005;IL2006;IL2007;IL2008;IL2009;IL2010;IL2011;IL2012;IL2013;IL2014;IL2015;IL2016;IL2017;IL2018;IL2019;IL2020;IL2021;IL2022;IL2023;IL2024;IL2025;IL2026;IL2027;IL2028;IL2029;IL2030;IL2031;IL2032;IL2033;IL2034;IL2035;IL2036;IL2037;IL2038;IL2039;IL2040;IL2041;IL2042;IL2043;IL2044;IL2045;IL2046;IL2047;IL2048;IL2049;IL2050;IL2051;IL2052;IL2053;IL2054;IL2055;IL2056;IL2057;IL2058;IL2059;IL2060;IL2061;IL2062;IL2063;IL2064;IL2065;IL2066;IL2067;IL2068;IL2069;IL2070;IL2071;IL2072;IL2073;IL2074;IL2075;IL2076;IL2077;IL2078;IL2079;IL2080;IL2081;IL2082;IL2083;IL2084;IL2085;IL2086;IL2087;IL2088;IL2089;IL2090;IL2091;IL2092;IL2093;IL2094;IL2095;IL2096;IL2097;IL2098;IL2099;IL2100;IL2101;IL2102;IL2103;IL2104;IL2105;IL2106;IL2107;IL2108;IL2109;IL2110;IL2111;IL2112;IL2113;IL2114;IL2115;IL2116;IL2117;IL2118;IL2119;IL2120;IL2121;IL2122;IL2123;IL2124;IL2125;IL2126;IL2127;IL2128;IL2129;IL2130;IL2131;IL2132;IL2133;IL2134;IL2135;IL2136;IL2137;IL2138;IL2139;IL2140;IL2141;IL2142;IL2143;IL2144;IL2145;IL2146;IL2147;IL2148;IL2149;IL2150;IL2151;IL2152;IL2153;IL2154;IL2155;IL2156;IL2157</WarningsAsErrors>
+    <!-- NativeAOT warnings -->
+    <WarningsAsErrors>$(WarningsAsErrors);IL3050;IL3051;IL3052;IL3053;IL3054;IL3055;IL3056</WarningsAsErrors>
+  </PropertyGroup>
+</Project>

+ 7 - 8
build/XUnit.props

@@ -1,13 +1,12 @@
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
-    <PackageReference Include="xunit" Version="2.4.1" />
-    <PackageReference Include="xunit.abstractions" Version="2.0.3" />
-    <PackageReference Include="xunit.assert" Version="2.4.1" />
-    <PackageReference Include="xunit.core" Version="2.4.1" />
-    <PackageReference Include="xunit.extensibility.core" Version="2.4.1" />
-    <PackageReference Include="xunit.extensibility.execution" Version="2.4.1" />
-    <PackageReference Include="xunit.runner.console" Version="2.4.1" />
-    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
+    <PackageReference Include="xunit" Version="2.4.2" />
+    <PackageReference Include="xunit.assert" Version="2.4.2" />
+    <PackageReference Include="xunit.core" Version="2.4.2" />
+    <PackageReference Include="xunit.extensibility.core" Version="2.4.2" />
+    <PackageReference Include="xunit.extensibility.execution" Version="2.4.2" />
+    <PackageReference Include="xunit.runner.console" Version="2.4.2" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.5" />
     <PackageReference Include="Xunit.SkippableFact" Version="1.4.13" />
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
   </ItemGroup>

+ 6 - 6
dirs.proj

@@ -9,17 +9,17 @@
     <ProjectReference Remove="**/*.shproj" />
     <ProjectReference Remove="src/Markup/Avalonia.Markup.Xaml/PortableXaml/**/*.*proj" />
     <ProjectReference Remove="src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github/**/*.*proj" />
-    <ProjectReference Remove="tests/Avalonia.ReactiveUI.Events.UnitTests/Avalonia.ReactiveUI.Events.UnitTests.csproj" />
-    <ProjectReference Remove="samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj" />
-    <ProjectReference Remove="samples/ControlCatalog.iOS.Legacy/ControlCatalog.iOS.Legacy.csproj" />
-    <ProjectReference Remove="samples/ControlCatalog.Android/ControlCatalog.Android.csproj" />
-    <ProjectReference Remove="src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj" />
+    <!-- Exclude iOS, Android and Web samples from build -->
+    <ProjectReference Remove="samples/*.iOS/*.csproj" />
+    <ProjectReference Remove="samples/*.Android/*.csproj" />
+    <ProjectReference Remove="samples/*.Web/*.csproj" />
   </ItemGroup>
   <ItemGroup Condition="!$([MSBuild]::IsOsPlatform('Windows')) OR '$(MSBuildRuntimeType)' != 'Full'">
     <ProjectReference Remove="src/Windows/Avalonia.Win32.Interop/Avalonia.Win32.Interop.csproj" />
     <ProjectReference Remove="samples/interop/**/*.*proj" />
     <ProjectReference Remove="samples/ControlCatalog.Desktop/*.*proj" />
   </ItemGroup>
+
   <!-- Build android and iOS projects only on Windows, where we have installed android workload -->
   <ItemGroup Condition="!$([MSBuild]::IsOsPlatform('Windows'))">
     <ProjectReference Remove="src/Android/**/*.*proj" />
@@ -27,6 +27,6 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="SlnGen" Version="2.0.40" PrivateAssets="all" />
+    <PackageReference Include="Microsoft.VisualStudio.SlnGen" Version="8.5.17" PrivateAssets="all" />
   </ItemGroup>
 </Project>

+ 2 - 4
global.json

@@ -1,11 +1,9 @@
 {
     "sdk": {
-        "version": "6.0.202",
+        "version": "7.0.101",
         "rollForward": "latestFeature"
     },
     "msbuild-sdks": {
-        "Microsoft.Build.Traversal": "1.0.43",
-        "MSBuild.Sdk.Extras": "3.0.22",
-        "AggregatePackage.NuGet.Sdk" : "0.1.12"
+        "Microsoft.Build.Traversal": "3.2.0"
     }
 }

+ 20 - 0
native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj

@@ -43,6 +43,10 @@
 		523484CA26EA688F00EA0C2C /* trayicon.mm in Sources */ = {isa = PBXBuildFile; fileRef = 523484C926EA688F00EA0C2C /* trayicon.mm */; };
 		5B21A982216530F500CEE36E /* cursor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B21A981216530F500CEE36E /* cursor.mm */; };
 		5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */; };
+		855EDC9F28C6546F00807998 /* PlatformBehaviorInhibition.mm in Sources */ = {isa = PBXBuildFile; fileRef = 855EDC9E28C6546F00807998 /* PlatformBehaviorInhibition.mm */; };
+		8D2F3512292F6AAE007FCF54 /* AvnTextInputMethodDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D2F3511292F6AAE007FCF54 /* AvnTextInputMethodDelegate.h */; };
+		8D300D65292D0A6800320C49 /* AvnTextInputMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D300D64292D0A6800320C49 /* AvnTextInputMethod.h */; };
+		8D300D69292E1E5D00320C49 /* AvnTextInputMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8D300D68292E1E5D00320C49 /* AvnTextInputMethod.mm */; };
 		AB00E4F72147CA920032A60A /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB00E4F62147CA920032A60A /* main.mm */; };
 		AB1E522C217613570091CD71 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB1E522B217613570091CD71 /* OpenGL.framework */; };
 		AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB661C1D2148230F00291242 /* AppKit.framework */; };
@@ -50,6 +54,7 @@
 		BC11A5BE2608D58F0017BAD0 /* automation.h in Headers */ = {isa = PBXBuildFile; fileRef = BC11A5BC2608D58F0017BAD0 /* automation.h */; };
 		BC11A5BF2608D58F0017BAD0 /* automation.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC11A5BD2608D58F0017BAD0 /* automation.mm */; };
 		ED3791C42862E1F40080BD62 /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED3791C32862E1F40080BD62 /* UniformTypeIdentifiers.framework */; };
+		EDF8CDCD2964CB01001EE34F /* PlatformSettings.mm in Sources */ = {isa = PBXBuildFile; fileRef = EDF8CDCC2964CB01001EE34F /* PlatformSettings.mm */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
@@ -94,6 +99,10 @@
 		5B21A981216530F500CEE36E /* cursor.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cursor.mm; sourceTree = "<group>"; };
 		5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = clipboard.mm; sourceTree = "<group>"; };
 		5BF943652167AD1D009CAE35 /* cursor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cursor.h; sourceTree = "<group>"; };
+		855EDC9E28C6546F00807998 /* PlatformBehaviorInhibition.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformBehaviorInhibition.mm; sourceTree = "<group>"; };
+		8D2F3511292F6AAE007FCF54 /* AvnTextInputMethodDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AvnTextInputMethodDelegate.h; sourceTree = "<group>"; };
+		8D300D64292D0A6800320C49 /* AvnTextInputMethod.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AvnTextInputMethod.h; sourceTree = "<group>"; };
+		8D300D68292E1E5D00320C49 /* AvnTextInputMethod.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AvnTextInputMethod.mm; sourceTree = "<group>"; };
 		AB00E4F62147CA920032A60A /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; };
 		AB1E522B217613570091CD71 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
 		AB661C1D2148230F00291242 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
@@ -103,6 +112,7 @@
 		BC11A5BC2608D58F0017BAD0 /* automation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = automation.h; sourceTree = "<group>"; };
 		BC11A5BD2608D58F0017BAD0 /* automation.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = automation.mm; sourceTree = "<group>"; };
 		ED3791C32862E1F40080BD62 /* UniformTypeIdentifiers.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UniformTypeIdentifiers.framework; path = System/Library/Frameworks/UniformTypeIdentifiers.framework; sourceTree = SDKROOT; };
+		EDF8CDCC2964CB01001EE34F /* PlatformSettings.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformSettings.mm; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -138,6 +148,10 @@
 		AB7A61E62147C814003C5833 = {
 			isa = PBXGroup;
 			children = (
+				855EDC9E28C6546F00807998 /* PlatformBehaviorInhibition.mm */,
+				8D2F3511292F6AAE007FCF54 /* AvnTextInputMethodDelegate.h */,
+				8D300D68292E1E5D00320C49 /* AvnTextInputMethod.mm */,
+				8D300D64292D0A6800320C49 /* AvnTextInputMethod.h */,
 				BC11A5BC2608D58F0017BAD0 /* automation.h */,
 				BC11A5BD2608D58F0017BAD0 /* automation.mm */,
 				1A1852DB23E05814008F0DED /* deadlock.mm */,
@@ -163,6 +177,7 @@
 				1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */,
 				37A517B22159597E00FBA241 /* Screens.mm */,
 				37C09D8721580FE4006A6758 /* SystemDialogs.mm */,
+				EDF8CDCC2964CB01001EE34F /* PlatformSettings.mm */,
 				AB7A61F02147C815003C5833 /* Products */,
 				AB661C1C2148230E00291242 /* Frameworks */,
 				18391676ECF0E983F4964357 /* WindowBaseImpl.mm */,
@@ -207,6 +222,8 @@
 				1839171DCC651B0638603AC4 /* INSWindowHolder.h in Headers */,
 				183919D91DB9AAB5D700C2EA /* WindowImpl.h in Headers */,
 				18391CF07316F819E76B617C /* IWindowStateChanged.h in Headers */,
+				8D300D65292D0A6800320C49 /* AvnTextInputMethod.h in Headers */,
+				8D2F3512292F6AAE007FCF54 /* AvnTextInputMethodDelegate.h in Headers */,
 				18391C28BF1823B5464FDD36 /* ResizeScope.h in Headers */,
 				18391ED5F611FF62C45F196D /* AvnView.h in Headers */,
 				18391E1381E2D5BFD60265A9 /* AutoFitContentView.h in Headers */,
@@ -285,7 +302,9 @@
 				1A3E5EAE23E9FB1300EDE661 /* cgl.mm in Sources */,
 				BC11A5BF2608D58F0017BAD0 /* automation.mm in Sources */,
 				37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */,
+				855EDC9F28C6546F00807998 /* PlatformBehaviorInhibition.mm in Sources */,
 				520624B322973F4100C4DCEF /* menu.mm in Sources */,
+				8D300D69292E1E5D00320C49 /* AvnTextInputMethod.mm in Sources */,
 				37A517B32159597E00FBA241 /* Screens.mm in Sources */,
 				1AFD334123E03C4F0042899B /* controlhost.mm in Sources */,
 				1A465D10246AB61600C5858B /* dnd.mm in Sources */,
@@ -299,6 +318,7 @@
 				1839151F32D1BB1AB51A7BB6 /* AvnPanelWindow.mm in Sources */,
 				18391AC16726CBC45856233B /* AvnWindow.mm in Sources */,
 				18391D8CD1756DC858DC1A09 /* PopupImpl.mm in Sources */,
+				EDF8CDCD2964CB01001EE34F /* PlatformSettings.mm in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 46 - 0
native/Avalonia.Native/src/OSX/AvnTextInputMethod.h

@@ -0,0 +1,46 @@
+//
+//  AvnTextInputMethod.h
+//  Avalonia.Native.OSX
+//
+//  Created by Benedikt Stebner on 22.11.22.
+//  Copyright © 2022 Avalonia. All rights reserved.
+//
+
+#ifndef AvnTextInputMethod_h
+#define AvnTextInputMethod_h
+
+#import <Foundation/Foundation.h>
+
+#include "com.h"
+#include "comimpl.h"
+#include "avalonia-native.h"
+#import "AvnTextInputMethodDelegate.h"
+
+class AvnTextInputMethod: public virtual ComObject, public virtual IAvnTextInputMethod{
+private:
+    id<AvnTextInputMethodDelegate> _inputMethodDelegate;
+public:
+    FORWARD_IUNKNOWN()
+    
+    BEGIN_INTERFACE_MAP()
+    INTERFACE_MAP_ENTRY(IAvnTextInputMethod, IID_IAvnTextInputMethod)
+    END_INTERFACE_MAP()
+    
+    virtual ~AvnTextInputMethod();
+    
+    AvnTextInputMethod(id<AvnTextInputMethodDelegate> inputMethodDelegate);
+    
+    bool IsActive ();
+    
+    HRESULT SetClient (IAvnTextInputMethodClient* client) override;
+    
+    virtual void Reset () override;
+    
+    virtual void SetCursorRect (AvnRect rect) override;
+    
+    virtual void SetSurroundingText (char* text, int anchorOffset, int cursorOffset) override;
+    
+public:
+    ComPtr<IAvnTextInputMethodClient> Client;
+};
+#endif /* AvnTextInputMethod_h */

+ 41 - 0
native/Avalonia.Native/src/OSX/AvnTextInputMethod.mm

@@ -0,0 +1,41 @@
+//
+//  AvnTextInputMethod.mm
+//  Avalonia.Native.OSX
+//
+//  Created by Benedikt Stebner on 23.11.22.
+//  Copyright © 2022 Avalonia. All rights reserved.
+//
+
+#include "AvnTextInputMethod.h"
+
+AvnTextInputMethod::~AvnTextInputMethod() {
+    Client = nullptr;
+}
+
+AvnTextInputMethod::AvnTextInputMethod(id<AvnTextInputMethodDelegate> inputMethodDelegate) {
+    _inputMethodDelegate = inputMethodDelegate;
+}
+
+bool AvnTextInputMethod::IsActive() {
+    return Client != nullptr;
+}
+
+HRESULT AvnTextInputMethod::SetClient(IAvnTextInputMethodClient *client) {
+    START_COM_CALL;
+    
+    Client = client;
+    
+    return S_OK;
+}
+
+void AvnTextInputMethod::Reset() {
+}
+
+void AvnTextInputMethod::SetSurroundingText(char* text, int anchorOffset, int cursorOffset) {
+    [_inputMethodDelegate setText:[NSString stringWithUTF8String:text]];
+    [_inputMethodDelegate setSelection: anchorOffset : cursorOffset];
+}
+
+void AvnTextInputMethod::SetCursorRect(AvnRect rect) {
+    [_inputMethodDelegate setCursorRect: rect];
+}

+ 20 - 0
native/Avalonia.Native/src/OSX/AvnTextInputMethodDelegate.h

@@ -0,0 +1,20 @@
+//
+//  AvnTextInputMethodHost.h
+//  Avalonia.Native.OSX
+//
+//  Created by Benedikt Stebner on 24.11.22.
+//  Copyright © 2022 Avalonia. All rights reserved.
+//
+
+#ifndef AvnTextInputMethodHost_h
+#define AvnTextInputMethodHost_h
+
+@protocol AvnTextInputMethodDelegate
+@required
+-(void) setText:(NSString* _Nonnull) text;
+-(void) setCursorRect:(AvnRect) cursorRect;
+-(void) setSelection: (int) start : (int) end;
+
+@end
+
+#endif /* AvnTextInputMethodHost_h */

+ 2 - 4
native/Avalonia.Native/src/OSX/AvnView.h

@@ -5,8 +5,6 @@
 #pragma once
 #import <Foundation/Foundation.h>
 
-
-#import <Foundation/Foundation.h>
 #import <AppKit/AppKit.h>
 #include "common.h"
 #include "WindowImpl.h"
@@ -14,7 +12,7 @@
 
 @class AvnAccessibilityElement;
 
-@interface AvnView : NSView<NSTextInputClient, NSDraggingDestination>
+@interface AvnView : NSView<NSTextInputClient, NSDraggingDestination, AvnTextInputMethodDelegate>
 -(AvnView* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent;
 -(NSEvent* _Nonnull) lastMouseDownEvent;
 -(AvnPoint) translateLocalPoint:(AvnPoint)pt;
@@ -24,4 +22,4 @@
 -(AvnPlatformResizeReason) getResizeReason;
 -(void) setResizeReason:(AvnPlatformResizeReason)reason;
 + (AvnPoint)toAvnPoint:(CGPoint)p;
-@end
+@end

+ 74 - 18
native/Avalonia.Native/src/OSX/AvnView.mm

@@ -12,6 +12,7 @@
 {
     ComPtr<WindowBaseImpl> _parent;
     NSTrackingArea* _area;
+    NSMutableAttributedString* _markedText;
     bool _isLeftPressed, _isMiddlePressed, _isRightPressed, _isXButton1Pressed, _isXButton2Pressed;
     AvnInputModifiers _modifierState;
     NSEvent* _lastMouseDownEvent;
@@ -20,6 +21,9 @@
     NSObject<IRenderTarget>* _renderTarget;
     AvnPlatformResizeReason _resizeReason;
     AvnAccessibilityElement* _accessibilityChild;
+    NSRect _cursorRect;
+    NSMutableString* _text;
+    NSRange _selection;
 }
 
 - (void)onClosed
@@ -127,11 +131,8 @@
         [self updateRenderTarget];
 
         auto reason = [self inLiveResize] ? ResizeUser : _resizeReason;
-        
-        if(_parent->IsShown())
-        {
-            _parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height}, reason);
-        }
+
+        _parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height}, reason);
     }
 }
 
@@ -521,7 +522,7 @@
 - (void)keyDown:(NSEvent *)event
 {
     [self keyboardEvent:event withType:KeyDown];
-    [[self inputContext] handleEvent:event];
+    _lastKeyHandled = [[self inputContext] handleEvent:event];
     [super keyDown:event];
 }
 
@@ -560,27 +561,50 @@
 
 - (BOOL)hasMarkedText
 {
-    return _lastKeyHandled;
+    return [_markedText length] > 0;
 }
 
 - (NSRange)markedRange
 {
+    if([_markedText length] > 0)
+        return NSMakeRange(0, [_markedText length] - 1);
     return NSMakeRange(NSNotFound, 0);
 }
 
 - (NSRange)selectedRange
 {
-    return NSMakeRange(NSNotFound, 0);
+    return _selection;
 }
 
 - (void)setMarkedText:(id)string selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
 {
-
+    if([string isKindOfClass:[NSAttributedString class]])
+    {
+        _markedText = [[NSMutableAttributedString alloc] initWithAttributedString:string];
+    }
+    else
+    {
+        _markedText = [[NSMutableAttributedString alloc] initWithString:string];
+    }
+    
+    if(!_parent->InputMethod->IsActive()){
+        return;
+    }
+    
+    _parent->InputMethod->Client->SetPreeditText((char*)[_markedText.string UTF8String]);
 }
 
 - (void)unmarkText
 {
-
+    [[_markedText mutableString] setString:@""];
+    
+    if(!_parent->InputMethod->IsActive()){
+        return;
+    }
+    
+    _parent->InputMethod->Client->SetPreeditText(nullptr);
+    
+    [[self inputContext] discardMarkedText];
 }
 
 - (NSArray<NSString *> *)validAttributesForMarkedText
@@ -590,30 +614,38 @@
 
 - (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)range actualRange:(NSRangePointer)actualRange
 {
-    return [NSAttributedString new];
+    return nullptr;
 }
 
 - (void)insertText:(id)string replacementRange:(NSRange)replacementRange
 {
-    if(!_lastKeyHandled)
-    {
+    //[_text replaceCharactersInRange:replacementRange withString:string];
+    
+    [self unmarkText];
+    
+    //if(!_lastKeyHandled)
+    //{
         if(_parent != nullptr)
         {
             _lastKeyHandled = _parent->BaseEvents->RawTextInputEvent(0, [string UTF8String]);
         }
-    }
+    //}
+    
+    [[self inputContext] invalidateCharacterCoordinates];
 }
 
 - (NSUInteger)characterIndexForPoint:(NSPoint)point
 {
-    return 0;
+    return NSNotFound;
 }
 
 - (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(NSRangePointer)actualRange
 {
-    CGRect result = { 0 };
-
-    return result;
+    if(!_parent->InputMethod->IsActive()){
+        return NSZeroRect;
+    }
+    
+    return _cursorRect;
 }
 
 - (NSDragOperation)triggerAvnDragEvent: (AvnDragEventType) type info: (id <NSDraggingInfo>)info
@@ -718,4 +750,28 @@
     return [[self accessibilityChild] accessibilityFocusedUIElement];
 }
 
+- (void) setText:(NSString *)text{
+    [_text setString:text];
+    
+    [[self inputContext] discardMarkedText];
+}
+
+- (void) setSelection:(int)start :(int)end{
+    _selection = NSMakeRange(start, end - start);
+    
+    [[self inputContext] invalidateCharacterCoordinates];
+}
+
+- (void) setCursorRect:(AvnRect)rect{
+    NSRect cursorRect = ToNSRect(rect);
+    NSRect windowRectOnScreen = [[self window] convertRectToScreen:self.frame];
+    
+    windowRectOnScreen.size = cursorRect.size;
+    windowRectOnScreen.origin = NSMakePoint(windowRectOnScreen.origin.x + cursorRect.origin.x, windowRectOnScreen.origin.y + self.frame.size.height - cursorRect.origin.y - cursorRect.size.height);
+    
+    _cursorRect = windowRectOnScreen;
+    
+    [[self inputContext] invalidateCharacterCoordinates];
+}
+
 @end

+ 23 - 13
native/Avalonia.Native/src/OSX/AvnWindow.mm

@@ -44,7 +44,7 @@
 
 -(bool) isDialog
 {
-    return _parent->IsDialog();
+    return _parent->IsModal();
 }
 
 -(double) getExtendedTitleBarHeight
@@ -171,9 +171,7 @@
     _closed = false;
     _isEnabled = true;
 
-    [self backingScaleFactor];
     [self setOpaque:NO];
-    [self setBackgroundColor: [NSColor clearColor]];
 
     _isExtended = false;
     _isTransitioningToFullScreen = false;
@@ -225,9 +223,22 @@
     }
 }
 
+// From chromium:
+//
+// > The delegate or the window class should implement this method so that
+// > -[NSWindow isZoomed] can be then determined by whether or not the current
+// > window frame is equal to the zoomed frame.
+//
+// If we don't implement this, then isZoomed always returns true for a non-
+// resizable window ¯\_(ツ)_/¯
+- (NSRect)windowWillUseStandardFrame:(NSWindow*)window
+                        defaultFrame:(NSRect)newFrame {
+  return newFrame;
+}
+
 -(BOOL)canBecomeKeyWindow
 {
-    if(_canBecomeKeyWindow)
+    if(_canBecomeKeyWindow && !_closed)
     {
         // If the window has a child window being shown as a dialog then don't allow it to become the key window.
         auto parent = dynamic_cast<WindowImpl*>(_parent.getRaw());
@@ -263,10 +274,6 @@
 -(void) setEnabled:(bool)enable
 {
     _isEnabled = enable;
-    
-    [[self standardWindowButton:NSWindowCloseButton] setEnabled:enable];
-    [[self standardWindowButton:NSWindowMiniaturizeButton] setEnabled:enable];
-    [[self standardWindowButton:NSWindowZoomButton] setEnabled:enable];
 }
 
 -(void)becomeKeyWindow
@@ -283,11 +290,16 @@
 
 - (void)windowDidBecomeKey:(NSNotification *_Nonnull)notification
 {
+    if (_parent == nullptr)
+        return;
+    
     _parent->BringToFront();
     
     dispatch_async(dispatch_get_main_queue(), ^{
         @try {
-        [self invalidateShadow];
+            [self invalidateShadow];
+            if (self->_parent != nullptr)
+                self->_parent->BringToFront();
         }
         @finally{
         }
@@ -382,10 +394,10 @@
 
 - (BOOL)windowShouldZoom:(NSWindow *_Nonnull)window toFrame:(NSRect)newFrame
 {
-    return true;
+    return _parent->CanZoom();
 }
 
--(void)resignKeyWindow
+-(void)windowDidResignKey:(NSNotification *)notification
 {
     if(_parent)
         _parent->BaseEvents->Deactivated();
@@ -393,8 +405,6 @@
     [self showAppMenuOnly];
     
     [self invalidateShadow];
-
-    [super resignKeyWindow];
 }
 
 - (void)windowDidMove:(NSNotification *_Nonnull)notification

+ 39 - 0
native/Avalonia.Native/src/OSX/PlatformBehaviorInhibition.mm

@@ -0,0 +1,39 @@
+#include "common.h"
+
+namespace
+{
+    id<NSObject> s_inhibitAppSleepHandle{};
+}
+
+class PlatformBehaviorInhibition : public ComSingleObject<IAvnPlatformBehaviorInhibition, &IID_IAvnCursorFactory>
+{
+public:
+    FORWARD_IUNKNOWN()
+    
+    virtual void SetInhibitAppSleep(bool inhibitAppSleep, char* reason) override
+    {
+        START_COM_CALL;
+        
+        @autoreleasepool
+        {
+            if (inhibitAppSleep && s_inhibitAppSleepHandle == nullptr)
+            {
+                NSActivityOptions options = NSActivityUserInitiatedAllowingIdleSystemSleep;
+                s_inhibitAppSleepHandle = [[NSProcessInfo processInfo] beginActivityWithOptions:options reason:[NSString stringWithUTF8String: reason]];
+            }
+            
+            if (!inhibitAppSleep)
+            {
+                s_inhibitAppSleepHandle = nullptr;
+            }
+        }
+    }
+};
+
+extern IAvnPlatformBehaviorInhibition* CreatePlatformBehaviorInhibition()
+{
+    @autoreleasepool
+    {
+        return new PlatformBehaviorInhibition();
+    }
+}

+ 113 - 0
native/Avalonia.Native/src/OSX/PlatformSettings.mm

@@ -0,0 +1,113 @@
+#include "common.h"
+
+@interface CocoaThemeObserver : NSObject
+-(id)initWithCallback:(IAvnActionCallback *)callback;
+@end
+
+class PlatformSettings : public ComSingleObject<IAvnPlatformSettings, &IID_IAvnPlatformSettings>
+{
+    CocoaThemeObserver* observer;
+
+public:
+    FORWARD_IUNKNOWN()
+    virtual AvnPlatformThemeVariant GetPlatformTheme() override
+    {
+        @autoreleasepool
+        {
+            if (@available(macOS 10.14, *))
+            {
+                if (NSApplication.sharedApplication.effectiveAppearance.name == NSAppearanceNameAqua
+                    || NSApplication.sharedApplication.effectiveAppearance.name == NSAppearanceNameVibrantLight) {
+                    return AvnPlatformThemeVariant::Light;
+                } else if (NSApplication.sharedApplication.effectiveAppearance.name == NSAppearanceNameDarkAqua
+                    || NSApplication.sharedApplication.effectiveAppearance.name == NSAppearanceNameVibrantDark) {
+                    return AvnPlatformThemeVariant::Dark;
+                } else if (NSApplication.sharedApplication.effectiveAppearance.name == NSAppearanceNameAccessibilityHighContrastAqua
+                    || NSApplication.sharedApplication.effectiveAppearance.name == NSAppearanceNameAccessibilityHighContrastVibrantLight) {
+                    return AvnPlatformThemeVariant::HighContrastLight;
+                } else if (NSApplication.sharedApplication.effectiveAppearance.name == NSAppearanceNameAccessibilityHighContrastDarkAqua
+                    || NSApplication.sharedApplication.effectiveAppearance.name == NSAppearanceNameAccessibilityHighContrastVibrantDark) {
+                    return AvnPlatformThemeVariant::HighContrastDark;
+                }
+            }
+            return AvnPlatformThemeVariant::Light;
+        }
+    }
+    
+    virtual unsigned int GetAccentColor() override
+    {
+        @autoreleasepool
+        {
+            if (@available(macOS 10.14, *))
+            {
+                auto color = [NSColor controlAccentColor];
+                return to_argb(color);
+            }
+            else
+            {
+                return 0;
+            }
+        }
+    }
+    
+    virtual void RegisterColorsChange(IAvnActionCallback *callback) override
+    {
+        if (@available(macOS 10.14, *))
+        {
+            observer = [[CocoaThemeObserver alloc] initWithCallback: callback];
+            [[NSApplication sharedApplication] addObserver:observer forKeyPath:@"effectiveAppearance" options:NSKeyValueObservingOptionNew context:nil];
+        }
+    }
+    
+private:
+    unsigned int to_argb(NSColor* color)
+    {
+        const CGFloat* components = CGColorGetComponents(color.CGColor);
+        unsigned int alpha = static_cast<unsigned int>(CGColorGetAlpha(color.CGColor) * 0xFF);
+        unsigned int red = static_cast<unsigned int>(components[0] * 0xFF);
+        unsigned int green = static_cast<unsigned int>(components[1] * 0xFF);
+        unsigned int blue = static_cast<unsigned int>(components[2] * 0xFF);
+        return (alpha << 24) + (red << 16) + (green << 8) + blue;
+    }
+};
+
+@implementation CocoaThemeObserver
+{
+    ComPtr<IAvnActionCallback> _callback;
+}
+- (id) initWithCallback:(IAvnActionCallback *)callback{
+    self = [super init];
+    if (self) {
+        _callback = callback;
+    }
+    return self;
+}
+
+/*- (void)didChangeValueForKey:(NSString *)key {
+    if([key isEqualToString:@"effectiveAppearance"]) {
+        _callback->Run();
+    }
+    else {
+        [super didChangeValueForKey:key];
+    }
+}*/
+
+- (void)observeValueForKeyPath:(NSString *)keyPath
+                      ofObject:(id)object
+                        change:(NSDictionary *)change
+                       context:(void *)context {
+    if([keyPath isEqualToString:@"effectiveAppearance"]) {
+        _callback->Run();
+    } else {
+        [super observeValueForKeyPath:keyPath
+                             ofObject:object
+                               change:change
+                              context:context];
+    }
+}
+@end
+
+extern IAvnPlatformSettings* CreatePlatformSettings()
+{
+    return new PlatformSettings();
+}

+ 1 - 1
native/Avalonia.Native/src/OSX/PopupImpl.mm

@@ -29,7 +29,7 @@ private:
         [Window setLevel:NSPopUpMenuWindowLevel];
     }
 protected:
-    virtual NSWindowStyleMask GetStyle() override
+    virtual NSWindowStyleMask CalculateStyleMask() override
     {
         return NSWindowStyleMaskBorderless;
     }

+ 2 - 2
native/Avalonia.Native/src/OSX/Screens.mm

@@ -41,9 +41,9 @@ public:
             ret->WorkingArea.X = [screen visibleFrame].origin.x;
             ret->WorkingArea.Y = ConvertPointY(ToAvnPoint([screen visibleFrame].origin)).Y - ret->WorkingArea.Height;
             
-            ret->PixelDensity = [screen backingScaleFactor];
+            ret->Scaling = 1;
             
-            ret->Primary = index == 0;
+            ret->IsPrimary = index == 0;
             
             return S_OK;
         }

+ 12 - 5
native/Avalonia.Native/src/OSX/WindowBaseImpl.h

@@ -8,6 +8,7 @@
 
 #include "rendertarget.h"
 #include "INSWindowHolder.h"
+#include "AvnTextInputMethod.h"
 
 @class AutoFitContentView;
 @class AvnMenu;
@@ -90,22 +91,27 @@ BEGIN_INTERFACE_MAP()
 
     virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost **retOut) override;
 
-    virtual HRESULT SetBlurEnabled(bool enable) override;
+    virtual HRESULT SetTransparencyMode(AvnWindowTransparencyMode mode) override;
+
+    virtual HRESULT SetFrameThemeVariant(AvnPlatformThemeVariant variant) override;
 
     virtual HRESULT BeginDragAndDropOperation(AvnDragDropEffects effects, AvnPoint point,
             IAvnClipboard *clipboard, IAvnDndResultCallback *cb,
             void *sourceHandle) override;
 
-    virtual bool IsDialog();
+    virtual bool IsModal();
 
     id<AvnWindowProtocol> GetWindowProtocol ();
                            
     virtual void BringToFront ();
+                           
+    virtual HRESULT GetInputMethod(IAvnTextInputMethod **retOut) override;
 
+    virtual bool CanZoom() { return false; }
+                           
 protected:
-    virtual NSWindowStyleMask GetStyle();
-
-    void UpdateStyle();
+    virtual NSWindowStyleMask CalculateStyleMask() = 0;
+    virtual void UpdateStyle();
 
 private:
     void CreateNSWindow (bool isDialog);
@@ -129,6 +135,7 @@ public:
     NSObject <IRenderTarget> *renderTarget;
     NSWindow * Window;
     ComPtr<IAvnWindowBaseEvents> BaseEvents;
+    ComPtr<AvnTextInputMethod> InputMethod;
     AvnView *View;
 };
 

+ 55 - 33
native/Avalonia.Native/src/OSX/WindowBaseImpl.mm

@@ -4,6 +4,7 @@
 //
 
 #import <AppKit/AppKit.h>
+#import <Cocoa/Cocoa.h>
 #include "common.h"
 #include "AvnView.h"
 #include "menu.h"
@@ -14,6 +15,7 @@
 #import "WindowProtocol.h"
 #import "WindowInterfaces.h"
 #include "WindowBaseImpl.h"
+#include "AvnTextInputMethod.h"
 
 
 WindowBaseImpl::~WindowBaseImpl() {
@@ -28,6 +30,7 @@ WindowBaseImpl::WindowBaseImpl(IAvnWindowBaseEvents *events, IAvnGlContext *gl,
     _glContext = gl;
     renderTarget = [[IOSurfaceRenderTarget alloc] initWithOpenGlContext:gl];
     View = [[AvnView alloc] initWithParent:this];
+    InputMethod = new AvnTextInputMethod(View);
     StandardContainer = [[AutoFitContentView new] initWithContent:View];
 
     lastPositionSet = { 0, 0 };
@@ -35,18 +38,14 @@ WindowBaseImpl::WindowBaseImpl(IAvnWindowBaseEvents *events, IAvnGlContext *gl,
     lastSize = NSSize { 100, 100 };
     lastMaxSize = NSSize { CGFLOAT_MAX, CGFLOAT_MAX};
     lastMinSize = NSSize { 0, 0 };
-
     lastMenu = nullptr;
     
     CreateNSWindow(usePanel);
     
     [Window setContentView:StandardContainer];
-    [Window setStyleMask:NSWindowStyleMaskBorderless];
     [Window setBackingType:NSBackingStoreBuffered];
-
     [Window setContentMinSize:lastMinSize];
     [Window setContentMaxSize:lastMaxSize];
-
     [Window setOpaque:false];
 }
 
@@ -297,15 +296,24 @@ HRESULT WindowBaseImpl::Resize(double x, double y, AvnPlatformResizeReason reaso
         }
 
         @try {
-            if(x != lastSize.width || y != lastSize.height) {
-                lastSize = NSSize{x, y};
-
+            if(x != lastSize.width || y != lastSize.height)
+            {
                 if (!_shown) {
-                    BaseEvents->Resized(AvnSize{x, y}, reason);
-                } else if (Window != nullptr) {
-                    [Window setContentSize:lastSize];
-                    [Window invalidateShadow];
+                    auto screenSize = [Window screen].visibleFrame.size;
+
+                    if (x > screenSize.width) {
+                        x = screenSize.width;
+                    }
+
+                    if (y > screenSize.height) {
+                        y = screenSize.height;
+                    }
                 }
+
+                lastSize = NSSize{x, y};
+
+                [Window setContentSize:lastSize];
+                [Window invalidateShadow];
             }
         }
         @finally {
@@ -489,10 +497,29 @@ HRESULT WindowBaseImpl::CreateNativeControlHost(IAvnNativeControlHost **retOut)
     return S_OK;
 }
 
-HRESULT WindowBaseImpl::SetBlurEnabled(bool enable) {
+HRESULT WindowBaseImpl::SetTransparencyMode(AvnWindowTransparencyMode mode) {
     START_COM_CALL;
 
-    [StandardContainer ShowBlur:enable];
+    [Window setBackgroundColor: (mode != Transparent ? [NSColor windowBackgroundColor] : [NSColor clearColor])];
+    [StandardContainer ShowBlur: mode == Blur];
+
+    return S_OK;
+}
+
+HRESULT WindowBaseImpl::SetFrameThemeVariant(AvnPlatformThemeVariant variant) {
+    START_COM_CALL;
+
+    NSAppearanceName appearanceName;
+    if (@available(macOS 10.14, *))
+    {
+        appearanceName = variant == AvnPlatformThemeVariant::Dark ? NSAppearanceNameDarkAqua : NSAppearanceNameAqua;
+    }
+    else
+    {
+        appearanceName = variant == AvnPlatformThemeVariant::Dark ? NSAppearanceNameVibrantDark : NSAppearanceNameAqua;
+    }
+
+    [Window setAppearance: [NSAppearance appearanceNamed: appearanceName]];
 
     return S_OK;
 }
@@ -541,16 +568,12 @@ HRESULT WindowBaseImpl::BeginDragAndDropOperation(AvnDragDropEffects effects, Av
     return S_OK;
 }
 
-bool WindowBaseImpl::IsDialog() {
+bool WindowBaseImpl::IsModal() {
     return false;
 }
 
-NSWindowStyleMask WindowBaseImpl::GetStyle() {
-    return NSWindowStyleMaskBorderless;
-}
-
 void WindowBaseImpl::UpdateStyle() {
-    [Window setStyleMask:GetStyle()];
+    [Window setStyleMask:CalculateStyleMask()];
 }
 
 void WindowBaseImpl::CleanNSWindow() {
@@ -561,21 +584,12 @@ void WindowBaseImpl::CleanNSWindow() {
     }
 }
 
-void WindowBaseImpl::CreateNSWindow(bool isDialog) {
-    if (isDialog) {
-        if (![Window isKindOfClass:[AvnPanel class]]) {
-            CleanNSWindow();
-
-            Window = [[AvnPanel alloc] initWithParent:this contentRect:NSRect{0, 0, lastSize} styleMask:GetStyle()];
-            
-            [Window setHidesOnDeactivate:false];
-        }
+void WindowBaseImpl::CreateNSWindow(bool usePanel) {
+    if (usePanel) {
+        Window = [[AvnPanel alloc] initWithParent:this contentRect:NSRect{0, 0, lastSize} styleMask:NSWindowStyleMaskBorderless];
+        [Window setHidesOnDeactivate:false];
     } else {
-        if (![Window isKindOfClass:[AvnWindow class]]) {
-            CleanNSWindow();
-
-            Window = [[AvnWindow alloc] initWithParent:this contentRect:NSRect{0, 0, lastSize} styleMask:GetStyle()];
-        }
+        Window = [[AvnWindow alloc] initWithParent:this contentRect:NSRect{0, 0, lastSize} styleMask:NSWindowStyleMaskBorderless];
     }
 }
 
@@ -593,6 +607,14 @@ void WindowBaseImpl::BringToFront()
     // do nothing.
 }
 
+HRESULT WindowBaseImpl::GetInputMethod(IAvnTextInputMethod **retOut) {
+    START_COM_CALL;
+
+    *retOut = InputMethod;
+
+    return S_OK;
+}
+
 extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events, IAvnGlContext* gl)
 {
     @autoreleasepool

+ 9 - 5
native/Avalonia.Native/src/OSX/WindowImpl.h

@@ -23,7 +23,7 @@ private:
     NSRect _preZoomSize;
     bool _transitioningWindowState;
     bool _isClientAreaExtended;
-    bool _isDialog;
+    bool _isModal;
     WindowImpl* _parent;
     std::list<WindowImpl*> _children;
     AvnExtendClientAreaChromeHints _extendClientHints;
@@ -41,8 +41,6 @@ BEGIN_INTERFACE_MAP()
 
     WindowImpl(IAvnWindowEvents* events, IAvnGlContext* gl);
 
-    void HideOrShowTrafficLights ();
-
     virtual HRESULT Show (bool activate, bool isDialog) override;
 
     virtual HRESULT SetEnabled (bool enable) override;
@@ -91,16 +89,22 @@ BEGIN_INTERFACE_MAP()
 
     virtual HRESULT SetWindowState (AvnWindowState state) override;
 
-    virtual bool IsDialog() override;
+    virtual bool IsModal() override;
+    
+    bool IsOwned();
     
     virtual void BringToFront () override;
     
     bool CanBecomeKeyWindow ();
 
+    bool CanZoom() override { return _isEnabled && _canResize; }
+    
 protected:
-    virtual NSWindowStyleMask GetStyle() override;
+    virtual NSWindowStyleMask CalculateStyleMask() override;
+    void UpdateStyle () override;
 
 private:
+    void ZOrderChildWindows();
     void OnInitialiseNSWindow();
     NSString *_lastTitle;
 };

+ 71 - 48
native/Avalonia.Native/src/OSX/WindowImpl.mm

@@ -30,19 +30,6 @@ WindowImpl::WindowImpl(IAvnWindowEvents *events, IAvnGlContext *gl) : WindowBase
     OnInitialiseNSWindow();
 }
 
-void WindowImpl::HideOrShowTrafficLights() {
-    if (Window == nil) {
-        return;
-    }
-
-    bool wantsChrome = (_extendClientHints & AvnSystemChrome) || (_extendClientHints & AvnPreferSystemChrome);
-    bool hasTrafficLights = _isClientAreaExtended ? wantsChrome : _decorations == SystemDecorationsFull;
-    
-    [[Window standardWindowButton:NSWindowCloseButton] setHidden:!hasTrafficLights];
-    [[Window standardWindowButton:NSWindowMiniaturizeButton] setHidden:!hasTrafficLights];
-    [[Window standardWindowButton:NSWindowZoomButton] setHidden:!hasTrafficLights];
-}
-
 void WindowImpl::OnInitialiseNSWindow(){
     [GetWindowProtocol() setCanBecomeKeyWindow:true];
     
@@ -63,11 +50,14 @@ HRESULT WindowImpl::Show(bool activate, bool isDialog) {
     START_COM_CALL;
 
     @autoreleasepool {
-        _isDialog = isDialog;
+        _isModal = isDialog;
 
         WindowBaseImpl::Show(activate, isDialog);
+        GetWindowState(&_actualWindowState);
 
-        HideOrShowTrafficLights();
+        if(IsZoomed()) {
+            _lastWindowState = _actualWindowState;
+        }
 
         return SetWindowState(_lastWindowState);
     }
@@ -91,13 +81,13 @@ HRESULT WindowImpl::SetParent(IAvnWindow *parent) {
         if(_parent != nullptr)
         {
             _parent->_children.remove(this);
-            
-            _parent->BringToFront();
         }
 
         auto cparent = dynamic_cast<WindowImpl *>(parent);
         
         _parent = cparent;
+
+        _isModal = _parent != nullptr;
         
         if(_parent != nullptr && Window != nullptr){
             // If one tries to show a child window with a minimized parent window, then the parent window will be
@@ -121,9 +111,9 @@ void WindowImpl::BringToFront()
 {
     if(Window != nullptr)
     {
-        if (![Window isMiniaturized])
+        if ([Window isVisible] && ![Window isMiniaturized])
         {
-            if(IsDialog())
+            if(IsModal())
             {
                 Activate();
             }
@@ -134,9 +124,18 @@ void WindowImpl::BringToFront()
         }
         
         [Window invalidateShadow];
+        ZOrderChildWindows();
+    }
+}
+
+void WindowImpl::ZOrderChildWindows()
+{
+    for(auto iterator = _children.begin(); iterator != _children.end(); iterator++)
+    {
+        auto window = (*iterator)->Window;
         
-        for(auto iterator = _children.begin(); iterator != _children.end(); iterator++)
-        {
+        // #9565: Only bring window to front if it's on the currently active space
+        if ([window isOnActiveSpace]) {
             (*iterator)->BringToFront();
         }
     }
@@ -146,7 +145,7 @@ bool WindowImpl::CanBecomeKeyWindow()
 {
     for(auto iterator = _children.begin(); iterator != _children.end(); iterator++)
     {
-        if((*iterator)->IsDialog())
+        if((*iterator)->IsModal())
         {
             return false;
         }
@@ -157,10 +156,15 @@ bool WindowImpl::CanBecomeKeyWindow()
 
 void WindowImpl::StartStateTransition() {
     _transitioningWindowState = true;
+    UpdateStyle();
 }
 
 void WindowImpl::EndStateTransition() {
     _transitioningWindowState = false;
+    UpdateStyle();
+
+    // Ensure correct order of child windows after fullscreen transition.
+    ZOrderChildWindows();
 }
 
 SystemDecorations WindowImpl::Decorations() {
@@ -218,16 +222,12 @@ bool WindowImpl::IsZoomed() {
 }
 
 void WindowImpl::DoZoom() {
-    switch (_decorations) {
-        case SystemDecorationsNone:
-        case SystemDecorationsBorderOnly:
-            [Window setFrame:[Window screen].visibleFrame display:true];
-            break;
-
-
-        case SystemDecorationsFull:
-            [Window performZoom:Window];
-            break;
+    if (_decorations == SystemDecorationsNone ||
+        _decorations == SystemDecorationsBorderOnly ||
+        _canResize == false) {
+        [Window setFrame:[Window screen].visibleFrame display:true];
+    } else {
+        [Window performZoom:Window];
     }
 }
 
@@ -254,8 +254,6 @@ HRESULT WindowImpl::SetDecorations(SystemDecorations value) {
 
         UpdateStyle();
 
-        HideOrShowTrafficLights();
-
         switch (_decorations) {
             case SystemDecorationsNone:
                 [Window setHasShadow:NO];
@@ -412,9 +410,6 @@ HRESULT WindowImpl::SetExtendClientArea(bool enable) {
             }
 
             [GetWindowProtocol() setIsExtended:enable];
-
-            HideOrShowTrafficLights();
-
             UpdateStyle();
         }
 
@@ -562,18 +557,24 @@ HRESULT WindowImpl::SetWindowState(AvnWindowState state) {
     }
 }
 
-bool WindowImpl::IsDialog() {
-    return _isDialog;
+bool WindowImpl::IsModal() {
+    return _isModal;
 }
 
-NSWindowStyleMask WindowImpl::GetStyle() {
-    unsigned long s = NSWindowStyleMaskBorderless;
-    
-    if(_actualWindowState == FullScreen)
-    {
-        s |= NSWindowStyleMaskFullScreen;
-    }
+bool WindowImpl::IsOwned() {
+    return _parent != nullptr;
+}
 
+NSWindowStyleMask WindowImpl::CalculateStyleMask() {
+    // Use the current style mask and only clear the flags we're going to be modifying.
+    unsigned long s = [Window styleMask] &
+        ~(NSWindowStyleMaskFullSizeContentView |
+          NSWindowStyleMaskTitled |
+          NSWindowStyleMaskClosable |
+          NSWindowStyleMaskResizable |
+          NSWindowStyleMaskMiniaturizable |
+          NSWindowStyleMaskTexturedBackground);
+    
     switch (_decorations) {
         case SystemDecorationsNone:
             s = s | NSWindowStyleMaskFullSizeContentView;
@@ -586,13 +587,13 @@ NSWindowStyleMask WindowImpl::GetStyle() {
         case SystemDecorationsFull:
             s = s | NSWindowStyleMaskTitled | NSWindowStyleMaskClosable;
 
-            if (_canResize && _isEnabled) {
+            if ((_canResize && _isEnabled) || _transitioningWindowState) {
                 s = s | NSWindowStyleMaskResizable;
             }
             break;
     }
 
-    if (!IsDialog()) {
+    if (!IsOwned()) {
         s |= NSWindowStyleMaskMiniaturizable;
     }
 
@@ -601,3 +602,25 @@ NSWindowStyleMask WindowImpl::GetStyle() {
     }
     return s;
 }
+
+void WindowImpl::UpdateStyle() {
+    WindowBaseImpl::UpdateStyle();
+    
+    if (Window == nil) {
+        return;
+    }
+
+    bool wantsChrome = (_extendClientHints & AvnSystemChrome) || (_extendClientHints & AvnPreferSystemChrome);
+    bool hasTrafficLights = _isClientAreaExtended ? wantsChrome : _decorations == SystemDecorationsFull;
+    
+    NSButton* closeButton = [Window standardWindowButton:NSWindowCloseButton];
+    NSButton* miniaturizeButton = [Window standardWindowButton:NSWindowMiniaturizeButton];
+    NSButton* zoomButton = [Window standardWindowButton:NSWindowZoomButton];
+
+    [closeButton setHidden:!hasTrafficLights];
+    [closeButton setEnabled:_isEnabled];
+    [miniaturizeButton setHidden:!hasTrafficLights];
+    [miniaturizeButton setEnabled:_isEnabled];
+    [zoomButton setHidden:!hasTrafficLights];
+    [zoomButton setEnabled:CanZoom()];
+}

+ 7 - 4
native/Avalonia.Native/src/OSX/app.mm

@@ -95,11 +95,14 @@ ComPtr<IAvnApplicationEvents> _events;
 }
 @end
 
-extern void InitializeAvnApp(IAvnApplicationEvents* events)
+extern void InitializeAvnApp(IAvnApplicationEvents* events, bool disableAppDelegate)
 {
-    NSApplication* app = [AvnApplication sharedApplication];
-    id delegate = [[AvnAppDelegate alloc] initWithEvents:events];
-    [app setDelegate:delegate];
+    if(!disableAppDelegate)
+    {
+        NSApplication* app = [AvnApplication sharedApplication];
+        id delegate = [[AvnAppDelegate alloc] initWithEvents:events];
+        [app setDelegate:delegate];
+    }
 }
 
 HRESULT AvnApplicationCommands::HideApp()

+ 3 - 1
native/Avalonia.Native/src/OSX/common.h

@@ -26,13 +26,15 @@ extern IAvnTrayIcon* CreateTrayIcon();
 extern IAvnMenuItem* CreateAppMenuItem();
 extern IAvnMenuItem* CreateAppMenuItemSeparator();
 extern IAvnApplicationCommands* CreateApplicationCommands();
+extern IAvnPlatformBehaviorInhibition* CreatePlatformBehaviorInhibition();
 extern IAvnNativeControlHost* CreateNativeControlHost(NSView* parent);
+extern IAvnPlatformSettings* CreatePlatformSettings();
 extern void SetAppMenu(IAvnMenu *menu);
 extern void SetServicesMenu (IAvnMenu* menu);
 extern IAvnMenu* GetAppMenu ();
 extern NSMenuItem* GetAppMenuItem ();
 
-extern void InitializeAvnApp(IAvnApplicationEvents* events);
+extern void InitializeAvnApp(IAvnApplicationEvents* events, bool disableAppDelegate);
 extern NSApplicationActivationPolicy AvnDesiredActivationPolicy;
 extern NSPoint ToNSPoint (AvnPoint p);
 extern NSRect ToNSRect (AvnRect r);

+ 56 - 6
native/Avalonia.Native/src/OSX/main.mm

@@ -3,6 +3,8 @@
 #include "common.h"
 
 static NSString* s_appTitle = @"Avalonia";
+static int disableSetProcessName = 0;
+static bool disableAppDelegate = false;
 
 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -111,11 +113,17 @@ public:
         @autoreleasepool
         {
             auto appTitle = [NSString stringWithUTF8String: utf8String];
-            
-            [[NSProcessInfo processInfo] setProcessName:appTitle];
-            
-            
-            SetProcessName(appTitle);
+            if (disableSetProcessName == 0)
+            {
+                [[NSProcessInfo processInfo] setProcessName:appTitle];
+                
+                SetProcessName(appTitle);
+            }
+            if (disableSetProcessName == 1)
+            {
+                auto rootMenu = [NSApp mainMenu];
+                [rootMenu setTitle:appTitle];
+            }
             
             return S_OK;
         }
@@ -133,6 +141,27 @@ public:
         }
     }
     
+    virtual HRESULT SetDisableSetProcessName(int disable)  override
+    {
+        START_COM_CALL;
+        
+        @autoreleasepool
+        {
+            disableSetProcessName = disable;
+            return S_OK;
+        }
+    }
+    
+    virtual HRESULT SetDisableAppDelegate(int disable) override
+    {
+        START_COM_CALL;
+        
+        @autoreleasepool {
+            disableAppDelegate = disable;
+            return S_OK;
+        }
+    }
+    
 };
 
 /// See "Using POSIX Threads in a Cocoa Application" section here:
@@ -175,7 +204,7 @@ public:
         @autoreleasepool{
             [[ThreadingInitializer new] do];
         }
-        InitializeAvnApp(events);
+        InitializeAvnApp(events, disableAppDelegate);
         return S_OK;
     };
     
@@ -369,6 +398,27 @@ public:
         }
     }
     
+    virtual HRESULT CreatePlatformSettings (IAvnPlatformSettings** ppv) override
+    {
+        START_COM_CALL;
+        
+        @autoreleasepool
+        {
+            *ppv = ::CreatePlatformSettings();
+            return S_OK;
+        }
+    }
+
+    virtual HRESULT CreatePlatformBehaviorInhibition(IAvnPlatformBehaviorInhibition** ppv) override
+    {
+        START_COM_CALL;
+        
+        @autoreleasepool
+        {
+            *ppv = ::CreatePlatformBehaviorInhibition();
+            return S_OK;
+        }
+    }
 };
 
 extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative()

+ 10 - 3
native/Avalonia.Native/src/OSX/menu.h

@@ -59,11 +59,20 @@ public:
     void RaiseOnClicked();
 };
 
+class AvnAppMenu;
+
+@interface AvnMenuDelegate : NSObject<NSMenuDelegate>
+- (id) initWithParent: (AvnAppMenu*) parent;
+- (void) parentDestroyed;
+@end
+
+
 class AvnAppMenu : public ComSingleObject<IAvnMenu, &IID_IAvnMenu>
 {
 private:
     AvnMenu* _native;
     ComPtr<IAvnMenuEvents> _baseEvents;
+    AvnMenuDelegate* _delegate;
     
 public:
     FORWARD_IUNKNOWN()
@@ -83,12 +92,10 @@ public:
     virtual HRESULT SetTitle (char* utf8String) override;
     
     virtual HRESULT Clear () override;
+    virtual ~AvnAppMenu() override;
 };
 
 
-@interface AvnMenuDelegate : NSObject<NSMenuDelegate>
-- (id) initWithParent: (AvnAppMenu*) parent;
-@end
 
 #endif
 

+ 20 - 6
native/Avalonia.Native/src/OSX/menu.mm

@@ -292,8 +292,13 @@ void AvnAppMenuItem::RaiseOnClicked()
 AvnAppMenu::AvnAppMenu(IAvnMenuEvents* events)
 {
     _baseEvents = events;
-    id del = [[AvnMenuDelegate alloc] initWithParent: this];
-    _native = [[AvnMenu alloc] initWithDelegate: del];
+    _delegate = [[AvnMenuDelegate alloc] initWithParent: this];
+    _native = [[AvnMenu alloc] initWithDelegate: _delegate];
+}
+
+AvnAppMenu::~AvnAppMenu()
+{
+    [_delegate parentDestroyed];
 }
 
 
@@ -394,7 +399,7 @@ HRESULT AvnAppMenu::Clear()
 
 @implementation AvnMenuDelegate
 {
-    ComPtr<AvnAppMenu> _parent;
+    AvnAppMenu* _parent;
 }
 - (id) initWithParent:(AvnAppMenu *)parent
 {
@@ -402,6 +407,12 @@ HRESULT AvnAppMenu::Clear()
     _parent = parent;
     return self;
 }
+
+- (void) parentDestroyed
+{
+    _parent = nullptr;
+}
+
 - (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
 {
     if(shouldCancel)
@@ -416,17 +427,20 @@ HRESULT AvnAppMenu::Clear()
 
 - (void)menuNeedsUpdate:(NSMenu *)menu
 {
-    _parent->RaiseNeedsUpdate();
+    if(_parent)
+        _parent->RaiseNeedsUpdate();
 }
 
 - (void)menuWillOpen:(NSMenu *)menu
 {
-    _parent->RaiseOpening();
+    if(_parent)
+        _parent->RaiseOpening();
 }
 
 - (void)menuDidClose:(NSMenu *)menu
 {
-    _parent->RaiseClosed();
+    if(_parent)
+        _parent->RaiseClosed();
 }
 
 @end

+ 4 - 1
native/Avalonia.Native/src/OSX/rendertarget.mm

@@ -183,8 +183,11 @@ static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* ta
                 [_layer setContents: (__bridge IOSurface*) surface->surface];
             }
             [CATransaction commit];
-            [CATransaction flush];
         }
+        // This can trigger event processing on the main thread
+        // which might need to lock the renderer
+        // which can cause a deadlock. So flush call is outside of the lock
+        [CATransaction flush];
     }
     else
         dispatch_async(dispatch_get_main_queue(), ^{

+ 61 - 85
nukebuild/Build.cs

@@ -23,6 +23,7 @@ using static Nuke.Common.Tools.MSBuild.MSBuildTasks;
 using static Nuke.Common.Tools.DotNet.DotNetTasks;
 using static Nuke.Common.Tools.Xunit.XunitTasks;
 using static Nuke.Common.Tools.VSWhere.VSWhereTasks;
+using MicroCom.CodeGenerator;
 
 /*
  Before editing this file, install support plugin for your IDE,
@@ -36,25 +37,6 @@ partial class Build : NukeBuild
 {
     [Solution("Avalonia.sln")] readonly Solution Solution;
 
-    static Lazy<string> MsBuildExe = new Lazy<string>(() =>
-    {
-        if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
-            return null;
-
-        var msBuildDirectory = VSWhere("-latest -nologo -property installationPath -format value -prerelease").FirstOrDefault().Text;
-
-        if (!string.IsNullOrWhiteSpace(msBuildDirectory))
-        {
-            string msBuildExe = Path.Combine(msBuildDirectory, @"MSBuild\Current\Bin\MSBuild.exe");
-            if (!System.IO.File.Exists(msBuildExe))
-                msBuildExe = Path.Combine(msBuildDirectory, @"MSBuild\15.0\Bin\MSBuild.exe");
-
-            return msBuildExe;
-        }
-
-        return null;
-    }, false);
-
     BuildParameters Parameters { get; set; }
     protected override void OnBuildInitialized()
     {
@@ -89,25 +71,27 @@ partial class Build : NukeBuild
         }
         ExecWait("dotnet version:", "dotnet", "--info");
         ExecWait("dotnet workloads:", "dotnet", "workload list");
+        Information("Processor count: " + Environment.ProcessorCount);
+        Information("Available RAM: " + GC.GetGCMemoryInfo().TotalAvailableMemoryBytes / 0x100000 + "MB");
     }
 
-    IReadOnlyCollection<Output> MsBuildCommon(
-        string projectFile,
-        Configure<MSBuildSettings> configurator = null)
+    DotNetConfigHelper ApplySettingCore(DotNetConfigHelper c)
     {
-        return MSBuild(c => c
-            .SetProjectFile(projectFile)
-            // This is required for VS2019 image on Azure Pipelines
-            .When(Parameters.IsRunningOnWindows &&
-                  Parameters.IsRunningOnAzure, _ => _
-                .AddProperty("JavaSdkDirectory", GetVariable<string>("JAVA_HOME_11_X64")))
-            .AddProperty("PackageVersion", Parameters.Version)
-            .AddProperty("iOSRoslynPathHackRequired", true)
-            .SetProcessToolPath(MsBuildExe.Value)
+        if (Parameters.IsRunningOnAzure)
+            c.AddProperty("JavaSdkDirectory", GetVariable<string>("JAVA_HOME_11_X64"));
+        c.AddProperty("PackageVersion", Parameters.Version)
             .SetConfiguration(Parameters.Configuration)
-            .SetVerbosity(MSBuildVerbosity.Minimal)
-            .Apply(configurator));
+            .SetVerbosity(DotNetVerbosity.Minimal);
+        return c;
     }
+    DotNetBuildSettings ApplySetting(DotNetBuildSettings c, Configure<DotNetBuildSettings> configurator = null) =>
+        ApplySettingCore(c).Build.Apply(configurator);
+
+    DotNetPackSettings ApplySetting(DotNetPackSettings c, Configure<DotNetPackSettings> configurator = null) =>
+        ApplySettingCore(c).Pack.Apply(configurator);
+
+    DotNetTestSettings ApplySetting(DotNetTestSettings c, Configure<DotNetTestSettings> configurator = null) =>
+        ApplySettingCore(c).Test.Apply(configurator);
 
     Target Clean => _ => _.Executes(() =>
     {
@@ -149,47 +133,54 @@ partial class Build : NukeBuild
     Target Compile => _ => _
         .DependsOn(Clean, CompileNative)
         .DependsOn(CompileHtmlPreviewer)
-        .Executes(async () =>
+        .Executes(() =>
         {
-            if (Parameters.IsRunningOnWindows)
-                MsBuildCommon(Parameters.MSBuildSolution, c => c
-                    .SetProcessArgumentConfigurator(a => a.Add("/r"))
-                    .AddTargets("Build")
-                );
-
-            else
-                DotNetBuild(c => c
-                    .SetProjectFile(Parameters.MSBuildSolution)
-                    .AddProperty("PackageVersion", Parameters.Version)
-                    .SetConfiguration(Parameters.Configuration)
-                );
+            DotNetBuild(c => ApplySetting(c)
+                .SetProjectFile(Parameters.MSBuildSolution)
+            );
         });
 
     void RunCoreTest(string projectName)
     {
         Information($"Running tests from {projectName}");
         var project = Solution.GetProject(projectName).NotNull("project != null");
+        // Nuke and MSBuild tools have build-in helpers to get target frameworks from the project.
+        // Unfortunately, it gets broken with every second SDK update, so we had to do it manually.
+        var fileXml = XDocument.Parse(File.ReadAllText(project.Path));
+        var targetFrameworks = fileXml.Descendants("TargetFrameworks")
+            .FirstOrDefault()?.Value.Split(';').Select(f => f.Trim());
+        if (targetFrameworks is null)
+        {
+            var targetFramework = fileXml.Descendants("TargetFramework").FirstOrDefault()?.Value;
+            if (targetFramework is not null)
+            {
+                targetFrameworks = new[] { targetFramework };
+            }
+        }
+        if (targetFrameworks is null)
+        {
+            throw new InvalidOperationException("No target frameworks were found in the test project");
+        }
 
-        foreach (var fw in project.GetTargetFrameworks())
+        foreach (var fw in targetFrameworks)
         {
             if (fw.StartsWith("net4")
-                && RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
+                && (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                 && Environment.GetEnvironmentVariable("FORCE_LINUX_TESTS") != "1")
             {
-                Information($"Skipping {projectName} ({fw}) tests on Linux - https://github.com/mono/mono/issues/13969");
+                Information($"Skipping {projectName} ({fw}) tests on *nix - https://github.com/mono/mono/issues/13969");
                 continue;
             }
 
             Information($"Running for {projectName} ({fw}) ...");
 
-            DotNetTest(c => c
+            DotNetTest(c => ApplySetting(c)
                 .SetProjectFile(project)
-                .SetConfiguration(Parameters.Configuration)
                 .SetFramework(fw)
                 .EnableNoBuild()
                 .EnableNoRestore()
                 .When(Parameters.PublishTestResults, _ => _
-                    .SetLogger("trx")
+                    .SetLoggers("trx")
                     .SetResultsDirectory(Parameters.TestResultsRoot)));
         }
     }
@@ -229,20 +220,20 @@ partial class Build : NukeBuild
         .Executes(() =>
         {
             RunCoreTest("Avalonia.Skia.RenderTests");
-            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+            if (Parameters.IsRunningOnWindows)
                 RunCoreTest("Avalonia.Direct2D1.RenderTests");
         });
 
-    Target RunDesignerTests => _ => _
-        .OnlyWhenStatic(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows)
+    Target RunToolsTests => _ => _
+        .OnlyWhenStatic(() => !Parameters.SkipTests)
         .DependsOn(Compile)
         .Executes(() =>
         {
-            RunCoreTest("Avalonia.DesignerSupport.Tests");
+            RunCoreTest("Avalonia.Generators.Tests");
+            if (Parameters.IsRunningOnWindows)
+                RunCoreTest("Avalonia.DesignerSupport.Tests");
         });
 
-    [PackageExecutable("JetBrains.dotMemoryUnit", "dotMemoryUnit.exe")] readonly Tool DotMemoryUnit;
-
     Target RunLeakTests => _ => _
         .OnlyWhenStatic(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows)
         .DependsOn(Compile)
@@ -250,12 +241,9 @@ partial class Build : NukeBuild
         {
             void DoMemoryTest()
             {
-                var testAssembly = "tests\\Avalonia.LeakTests\\bin\\Release\\net461\\Avalonia.LeakTests.dll";
-                DotMemoryUnit(
-                    $"{XunitPath.DoubleQuoteIfNeeded()} --propagate-exit-code -- {testAssembly}",
-                    timeout: 120_000);
+                RunCoreTest("Avalonia.LeakTests");
             }
-            ControlFlow.ExecuteWithRetry(DoMemoryTest, waitInSeconds: 3);
+            ControlFlow.ExecuteWithRetry(DoMemoryTest, delay: TimeSpan.FromMilliseconds(3));
         });
 
     Target ZipFiles => _ => _
@@ -263,19 +251,7 @@ partial class Build : NukeBuild
         .Executes(() =>
         {
             var data = Parameters;
-            var pathToProjectSource = RootDirectory / "samples" / "ControlCatalog.NetCore";
-            var pathToPublish = pathToProjectSource / "bin" / data.Configuration / "publish";
-
-            DotNetPublish(c => c
-                .SetProject(pathToProjectSource / "ControlCatalog.NetCore.csproj")
-                .EnableNoBuild()
-                .SetConfiguration(data.Configuration)
-                .AddProperty("PackageVersion", data.Version)
-                .AddProperty("PublishDir", pathToPublish));
-
-            Zip(data.ZipCoreArtifacts, data.BinRoot);
             Zip(data.ZipNuGetArtifacts, data.NugetRoot);
-            Zip(data.ZipTargetControlCatalogNetCoreDir, pathToPublish);
         });
 
     Target CreateIntermediateNugetPackages => _ => _
@@ -283,15 +259,7 @@ partial class Build : NukeBuild
         .After(RunTests)
         .Executes(() =>
         {
-            if (Parameters.IsRunningOnWindows)
-
-                MsBuildCommon(Parameters.MSBuildSolution, c => c
-                    .AddTargets("Pack"));
-            else
-                DotNetPack(c => c
-                    .SetProject(Parameters.MSBuildSolution)
-                    .SetConfiguration(Parameters.Configuration)
-                    .AddProperty("PackageVersion", Parameters.Version));
+            DotNetPack(c => ApplySetting(c).SetProject(Parameters.MSBuildSolution));
         });
 
     Target CreateNugetPackages => _ => _
@@ -310,7 +278,7 @@ partial class Build : NukeBuild
     Target RunTests => _ => _
         .DependsOn(RunCoreLibsTests)
         .DependsOn(RunRenderTests)
-        .DependsOn(RunDesignerTests)
+        .DependsOn(RunToolsTests)
         .DependsOn(RunHtmlPreviewerTests)
         .DependsOn(RunLeakTests);
 
@@ -329,6 +297,14 @@ partial class Build : NukeBuild
         .DependsOn(Package)
         .DependsOn(ZipFiles);
 
+    Target GenerateCppHeaders => _ => _.Executes(() =>
+    {
+        var file = MicroComCodeGenerator.Parse(
+            File.ReadAllText(RootDirectory / "src" / "Avalonia.Native" / "avn.idl"));
+        File.WriteAllText(RootDirectory / "native" / "Avalonia.Native" / "inc" / "avalonia-native.h",
+            file.GenerateCppHeader());
+    });
+
 
     public static int Main() =>
         RuntimeInformation.IsOSPlatform(OSPlatform.Windows)

+ 2 - 6
nukebuild/BuildParameters.cs

@@ -51,14 +51,12 @@ public partial class Build
         public AbsolutePath NugetIntermediateRoot { get; }
         public AbsolutePath NugetRoot { get; }
         public AbsolutePath ZipRoot { get; }
-        public AbsolutePath BinRoot { get; }
         public AbsolutePath TestResultsRoot { get; }
         public string DirSuffix { get; }
         public List<string> BuildDirs { get; }
         public string FileZipSuffix { get; }
         public AbsolutePath ZipCoreArtifacts { get; }
         public AbsolutePath ZipNuGetArtifacts { get; }
-        public AbsolutePath ZipTargetControlCatalogNetCoreDir { get; }
 
 
         public BuildParameters(Build b)
@@ -76,11 +74,11 @@ public partial class Build
             MSBuildSolution = RootDirectory / "dirs.proj";
 
             // PARAMETERS
-            IsLocalBuild = Host == HostType.Console;
+            IsLocalBuild = NukeBuild.IsLocalBuild;
             IsRunningOnUnix = Environment.OSVersion.Platform == PlatformID.Unix ||
                               Environment.OSVersion.Platform == PlatformID.MacOSX;
             IsRunningOnWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
-            IsRunningOnAzure = Host == HostType.AzurePipelines ||
+            IsRunningOnAzure = Host is AzurePipelines ||
                                Environment.GetEnvironmentVariable("LOGNAME") == "vsts";
 
             if (IsRunningOnAzure)
@@ -121,14 +119,12 @@ public partial class Build
             NugetRoot = ArtifactsDir / "nuget";
             NugetIntermediateRoot = RootDirectory / "build-intermediate" / "nuget";
             ZipRoot = ArtifactsDir / "zip";
-            BinRoot = ArtifactsDir / "bin";
             TestResultsRoot = ArtifactsDir / "test-results";
             BuildDirs = GlobDirectories(RootDirectory, "**bin").Concat(GlobDirectories(RootDirectory, "**obj")).ToList();
             DirSuffix = Configuration;
             FileZipSuffix = Version + ".zip";
             ZipCoreArtifacts = ZipRoot / ("Avalonia-" + FileZipSuffix);
             ZipNuGetArtifacts = ZipRoot / ("Avalonia-NuGet-" + FileZipSuffix);
-            ZipTargetControlCatalogNetCoreDir = ZipRoot / ("ControlCatalog.NetCore-" + FileZipSuffix);
         }
 
         string GetVersion()

+ 98 - 14
nukebuild/BuildTasksPatcher.cs

@@ -4,9 +4,58 @@ using System.IO.Compression;
 using System.Linq;
 using ILRepacking;
 using Mono.Cecil;
+using Mono.Cecil.Cil;
 
 public class BuildTasksPatcher
 {
+    /// <summary>
+    /// This helper class, avoid argument null exception
+    /// when cecil write AssemblyNameDefinition on MemoryStream.
+    /// </summary>
+    private class Wrapper : ISymbolWriterProvider
+    {
+        readonly ISymbolWriterProvider _provider;
+        readonly string _filename;
+
+        public Wrapper(ISymbolWriterProvider provider, string filename)
+        {
+            _provider = provider;
+            _filename = filename;
+        }
+
+        public ISymbolWriter GetSymbolWriter(ModuleDefinition module, string fileName) =>
+            _provider.GetSymbolWriter(module, string.IsNullOrWhiteSpace(fileName) ? _filename : fileName);
+
+        public ISymbolWriter GetSymbolWriter(ModuleDefinition module, Stream symbolStream) =>
+            _provider.GetSymbolWriter(module, symbolStream);
+    }
+
+    private static string GetSourceLinkInfo(string path)
+    {
+        try
+        {
+            using (var asm = AssemblyDefinition.ReadAssembly(path,
+                new ReaderParameters
+                {
+                    ReadWrite = true,
+                    InMemory = true,
+                    ReadSymbols = true,
+                    SymbolReaderProvider = new DefaultSymbolReaderProvider(false),
+                }))
+            {
+                if (asm.MainModule.CustomDebugInformations?.OfType<SourceLinkDebugInformation>()?.FirstOrDefault() is { } sli)
+                {
+                    return sli.Content;
+                }
+            }
+        }
+        catch
+        {
+
+        }
+        return null;
+    }
+
     public static void PatchBuildTasksInPackage(string packagePath)
     {
         using (var archive = new ZipArchive(File.Open(packagePath, FileMode.Open, FileAccess.ReadWrite),
@@ -17,50 +66,85 @@ public class BuildTasksPatcher
             {
                 if (entry.Name == "Avalonia.Build.Tasks.dll")
                 {
-                    var temp = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".dll");
+                    var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
+                    Directory.CreateDirectory(tempDir);
+                    var temp = Path.Combine(tempDir, entry.Name);
                     var output = temp + ".output";
+                    File.Copy(typeof(Microsoft.Build.Framework.ITask).Assembly.GetModules()[0].FullyQualifiedName,
+                        Path.Combine(tempDir, "Microsoft.Build.Framework.dll"));
                     var patched = new MemoryStream();
                     try
                     {
                         entry.ExtractToFile(temp, true);
+                        // Get Original SourceLinkInfo Content
+                        var sourceLinkInfoContent = GetSourceLinkInfo(temp);
                         var repack = new ILRepacking.ILRepack(new RepackOptions()
                         {
                             Internalize = true,
                             InputAssemblies = new[]
                             {
-                                temp, typeof(Mono.Cecil.AssemblyDefinition).Assembly.GetModules()[0]
-                                    .FullyQualifiedName,
+                                temp,
+                                typeof(Mono.Cecil.AssemblyDefinition).Assembly.GetModules()[0].FullyQualifiedName,
                                 typeof(Mono.Cecil.Rocks.MethodBodyRocks).Assembly.GetModules()[0].FullyQualifiedName,
                                 typeof(Mono.Cecil.Pdb.PdbReaderProvider).Assembly.GetModules()[0].FullyQualifiedName,
-                                typeof(Mono.Cecil.Mdb.MdbReaderProvider).Assembly.GetModules()[0].FullyQualifiedName
-                                
+                                typeof(Mono.Cecil.Mdb.MdbReaderProvider).Assembly.GetModules()[0].FullyQualifiedName,
                             },
-                            SearchDirectories = new string[0],
+                            SearchDirectories = Array.Empty<string>(),
+                            DebugInfo = true, // Allowed read debug info
                             OutputFile = output
                         });
                         repack.Repack();
 
-
                         // 'hurr-durr assembly with the same name is already loaded' prevention
                         using (var asm = AssemblyDefinition.ReadAssembly(output,
-                            new ReaderParameters { ReadWrite = true, InMemory = true, }))
+                            new ReaderParameters
+                            {
+                                ReadWrite = true,
+                                InMemory = true,
+                                ReadSymbols = true,
+                                SymbolReaderProvider = new DefaultSymbolReaderProvider(false),
+                            }))
                         {
                             asm.Name = new AssemblyNameDefinition(
                                 "Avalonia.Build.Tasks."
                                 + Guid.NewGuid().ToString().Replace("-", ""),
                                 new Version(0, 0, 0));
-                            asm.Write(patched);
+
+                            var mainModule = asm.MainModule;
+
+                            // If we have SourceLink info copy to patched assembly.
+                            if (!string.IsNullOrEmpty(sourceLinkInfoContent))
+                            {
+                                mainModule.CustomDebugInformations.Add(new SourceLinkDebugInformation(sourceLinkInfoContent));
+                            }
+
+                            // Try to get SymbolWriter if it has it
+                            var reader = mainModule.SymbolReader;
+                            var hasDebugInfo = reader is not null;
+                            var proivder = reader?.GetWriterProvider() is ISymbolWriterProvider p
+                                ? new Wrapper(p, "Avalonia.Build.Tasks.dll")
+                                : default(ISymbolWriterProvider);
+
+                            var parameters = new WriterParameters
+                            {
+#if ISNETFULLFRAMEWORK
+                                StrongNameKeyPair = signingStep.KeyPair,
+#endif
+                                WriteSymbols = hasDebugInfo,
+                                SymbolWriterProvider = proivder,
+                                DeterministicMvid = hasDebugInfo,
+                            };
+                            asm.Write(patched, parameters);
                             patched.Position = 0;
                         }
+
                     }
                     finally
                     {
                         try
                         {
-                            if (File.Exists(temp))
-                                File.Delete(temp);
-                            if (File.Exists(output))
-                                File.Delete(output);
+                            if (Directory.Exists(tempDir))
+                                Directory.Delete(tempDir, true);
                         }
                         catch
                         {
@@ -77,4 +161,4 @@ public class BuildTasksPatcher
             }
         }
     }
-}
+}

+ 56 - 0
nukebuild/DotNetConfigHelper.cs

@@ -0,0 +1,56 @@
+using System.Globalization;
+using Nuke.Common.Tools.DotNet;
+// ReSharper disable ReturnValueOfPureMethodIsNotUsed
+
+public class DotNetConfigHelper
+{
+    public DotNetBuildSettings Build;
+    public DotNetPackSettings Pack;
+    public DotNetTestSettings Test;
+
+    public DotNetConfigHelper(DotNetBuildSettings s)
+    {
+        Build = s;
+    }
+
+    public DotNetConfigHelper(DotNetPackSettings s)
+    {
+        Pack = s;
+    }
+
+    public DotNetConfigHelper(DotNetTestSettings s)
+    {
+        Test = s;
+    }
+
+    public DotNetConfigHelper AddProperty(string key, bool value) =>
+        AddProperty(key, value.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
+    public DotNetConfigHelper AddProperty(string key, string value)
+    {
+        Build = Build?.AddProperty(key, value);
+        Pack = Pack?.AddProperty(key, value);
+        Test = Test?.AddProperty(key, value);
+
+        return this;
+    }
+
+    public DotNetConfigHelper SetConfiguration(string configuration)
+    {
+        Build = Build?.SetConfiguration(configuration);
+        Pack = Pack?.SetConfiguration(configuration);
+        Test = Test?.SetConfiguration(configuration);
+        return this;
+    }
+
+    public DotNetConfigHelper SetVerbosity(DotNetVerbosity verbosity)
+    {
+        Build = Build?.SetVerbosity(verbosity);
+        Pack = Pack?.SetVerbosity(verbosity);
+        Test = Test?.SetVerbosity(verbosity);
+        return this;
+    }
+
+    public static implicit operator DotNetConfigHelper(DotNetBuildSettings s) => new DotNetConfigHelper(s);
+    public static implicit operator DotNetConfigHelper(DotNetPackSettings s) => new DotNetConfigHelper(s);
+    public static implicit operator DotNetConfigHelper(DotNetTestSettings s) => new DotNetConfigHelper(s);
+}

+ 0 - 14
nukebuild/MicroComGen.cs

@@ -1,14 +0,0 @@
-using System.IO;
-using MicroCom.CodeGenerator;
-using Nuke.Common;
-
-partial class Build : NukeBuild
-{
-    Target GenerateCppHeaders => _ => _.Executes(() =>
-    {
-        var file = MicroComCodeGenerator.Parse(
-            File.ReadAllText(RootDirectory / "src" / "Avalonia.Native" / "avn.idl"));
-        File.WriteAllText(RootDirectory / "native" / "Avalonia.Native" / "inc" / "avalonia-native.h",
-            file.GenerateCppHeader());
-    });
-}

+ 15 - 0
nukebuild/Shims.cs

@@ -49,7 +49,11 @@ public partial class Build
                         {
                             if (fsEntry is FileInfo)
                             {
+#if NET6
                                 var relPath = Path.GetRelativePath(rootPath, fsEntry.FullName);
+#else
+                                var relPath = GetRelativePath(rootPath, fsEntry.FullName);
+#endif
                                 AddFile(fsEntry.FullName, relPath);
                             }
                         }
@@ -78,6 +82,17 @@ public partial class Build
         }
     }
 
+    private static string GetRelativePath(string relativeTo, string path)
+    {
+        var uri = new Uri(relativeTo);
+        var rel = Uri.UnescapeDataString(uri.MakeRelativeUri(new Uri(path)).ToString()).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
+        if (rel.Contains(Path.DirectorySeparatorChar.ToString()) == false)
+        {
+            rel = $".{Path.DirectorySeparatorChar}{rel}";
+        }
+        return rel;
+    }
+
     class NumergeNukeLogger : INumergeLogger
     {
         public void Log(NumergeLogLevel level, string message)

+ 25 - 18
nukebuild/_build.csproj

@@ -1,41 +1,48 @@
 <Project Sdk="Microsoft.NET.Sdk">
-
   <PropertyGroup>
     <OutputType>Exe</OutputType>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
     <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
     <RootNamespace></RootNamespace>
     <IsPackable>False</IsPackable>
-    <NoWarn>CS0649;CS0169</NoWarn>
+    <NoWarn>$(NoWarn);CS0649;CS0169;SYSLIB0011</NoWarn>
+    <NukeTelemetryVersion>1</NukeTelemetryVersion>
+    <TargetFramework>net7.0</TargetFramework>
   </PropertyGroup>
+ 
  <Import Project="..\build\JetBrains.dotMemoryUnit.props" />
   <ItemGroup>
-    <PackageReference Include="Nuke.Common" Version="5.0.0" />
-    <PackageReference Include="xunit.runner.console" Version="2.3.1" />
+    <PackageReference Include="Nuke.Common" Version="6.2.1" />
     <PackageReference Include="vswhere" Version="2.6.7" Condition=" '$(OS)' == 'Windows_NT' " />
-    <PackageReference Include="ILRepack.NETStandard" Version="2.0.4" />
-    <PackageReference Include="MicroCom.CodeGenerator" Version="0.10.4" />
+    <PackageReference Include="MicroCom.CodeGenerator" Version="0.11.0" />
     <!-- Keep in sync with Avalonia.Build.Tasks -->
-    <PackageReference Include="Mono.Cecil" Version="0.11.2" />
+    <PackageReference Include="Mono.Cecil" Version="0.11.4" />
+    <PackageReference Include="SourceLink" Version="1.1.0" GeneratePathProperty="true" />
+    <PackageReference Include="Microsoft.Build.Framework" Version="17.3.2" PrivateAssets="All" />
+    <PackageReference Include="xunit.runner.console" Version="2.4.2">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
   </ItemGroup>
 
   <ItemGroup>
     <NukeMetadata Include="**\*.json" Exclude="bin\**;obj\**" />
     <NukeExternalFiles Include="**\*.*.ext" Exclude="bin\**;obj\**" />
-    <None Remove="*.csproj.DotSettings;*.ref.*.txt" />
 
     <!-- Common build related files -->
-    <None Include="..\build.ps1" />
-    <None Include="..\build.sh" />
-    <None Include="..\.nuke" />
-    <None Include="..\global.json" Condition="Exists('..\global.json')" />
-    <None Include="..\nuget.config" Condition="Exists('..\nuget.config')" />
-    <None Include="..\Jenkinsfile" Condition="Exists('..\Jenkinsfile')" />
-    <None Include="..\appveyor.yml" Condition="Exists('..\appveyor.yml')" />
-    <None Include="..\.travis.yml" Condition="Exists('..\.travis.yml')" />
-    <None Include="..\GitVersion.yml" Condition="Exists('..\GitVersion.yml')" />
     <Compile Remove="Numerge/**/*.*" />
     <Compile Include="Numerge/Numerge/**/*.cs" />
   </ItemGroup>
 
+  	<ItemGroup>
+		<EmbeddedResource Include="$(NuGetPackageRoot)sourcelink/1.1.0/tools/pdbstr.exe"></EmbeddedResource>
+	</ItemGroup>
+    
+  <ItemGroup>
+    <Compile Remove="il-repack\ILRepack\Application.cs" />
+  </ItemGroup>
+    
+  <ItemGroup>
+    <Folder Include="Numerge\Numerge.Console\" />
+  </ItemGroup>
+
 </Project>

+ 1 - 0
nukebuild/il-repack

@@ -0,0 +1 @@
+Subproject commit 892f079ea8cb0c178f0a68f53a7a7eac13acdda9

+ 5 - 0
nukebuild/numerge.config

@@ -11,6 +11,11 @@
           "Id": "Avalonia.Build.Tasks",
           "IgnoreMissingFrameworkBinaries": true,
           "DoNotMergeDependencies": true
+        },
+        {
+          "Id": "Avalonia.Generators",
+          "IgnoreMissingFrameworkBinaries": true,
+          "DoNotMergeDependencies": true
         }
       ]
     }

+ 5 - 1
packages/Avalonia/Avalonia.csproj

@@ -6,11 +6,15 @@
 
   <ItemGroup>
       <ProjectReference Include="../../src/Avalonia.Remote.Protocol/Avalonia.Remote.Protocol.csproj" />
-      <ProjectReference Include="../../src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj" >
+      <ProjectReference Include="../../src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj">
         <PrivateAssets>all</PrivateAssets>
         <SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
         <SetTargetFramework>TargetFramework=netstandard2.0</SetTargetFramework>
       </ProjectReference>
+      <ProjectReference Include="..\..\src\tools\Avalonia.Generators\Avalonia.Generators.csproj"
+                        ReferenceOutputAssembly="false"
+                        PrivateAssets="all"
+                        OutputItemType="Analyzer" />
   </ItemGroup>
 
   <PropertyGroup>

+ 5 - 0
packages/Avalonia/Avalonia.props

@@ -6,4 +6,9 @@
     <AvaloniaUseExternalMSBuild>false</AvaloniaUseExternalMSBuild>
   </PropertyGroup>
   <Import Project="$(MSBuildThisFileDirectory)\AvaloniaBuildTasks.props"/>
+
+  <!-- Allow loading the AvaloniaVS extension when referencing the Avalonia nuget package -->
+  <ItemGroup>
+    <ProjectCapability Include="Avalonia"/>
+  </ItemGroup>
 </Project>

+ 37 - 13
packages/Avalonia/AvaloniaBuildTasks.targets

@@ -3,8 +3,8 @@
     <_AvaloniaUseExternalMSBuild>$(AvaloniaUseExternalMSBuild)</_AvaloniaUseExternalMSBuild>
     <_AvaloniaUseExternalMSBuild Condition="'$(_AvaloniaForceInternalMSBuild)' == 'true'">false</_AvaloniaUseExternalMSBuild>
     <AvaloniaXamlReportImportance Condition="'$(AvaloniaXamlReportImportance)' == ''">low</AvaloniaXamlReportImportance>
-    <_AvaloniaPatchComInterop Condition="'$(_AvaloniaPatchComInterop)' == ''">false</_AvaloniaPatchComInterop>
     <_AvaloniaSkipXamlCompilation Condition="'$(_AvaloniaSkipXamlCompilation)' == ''">false</_AvaloniaSkipXamlCompilation>
+    <AvaloniaUseCompiledBindingsByDefault Condition="'$(AvaloniaUseCompiledBindingsByDefault)' == ''">false</AvaloniaUseCompiledBindingsByDefault>
   </PropertyGroup>
 
   <!-- Unfortunately we have to update default items in .targets since custom nuget props are improted before Microsoft.NET.Sdk.DefaultItems.props -->
@@ -30,7 +30,9 @@
              />
 
 
-  <Target Name="AddAvaloniaResources" BeforeTargets="ResolveReferences">
+  <Target Name="AddAvaloniaResources" 
+          BeforeTargets="ResolveReferences"
+          Condition="('@(AvaloniaResource->Count())' &gt; 0) or ('@(AvaloniaXaml->Count())' &gt; 0)">
     <PropertyGroup>
       <AvaloniaResourcesTemporaryFilePath Condition="'$(AvaloniaResourcesTemporaryFilePath)' == ''">$(IntermediateOutputPath)/Avalonia/resources</AvaloniaResourcesTemporaryFilePath>
     </PropertyGroup>
@@ -44,10 +46,14 @@
   <PropertyGroup>
     <BuildAvaloniaResourcesDependsOn>$(BuildAvaloniaResourcesDependsOn);AddAvaloniaResources;ResolveReferences;_GenerateAvaloniaResourcesDependencyCache</BuildAvaloniaResourcesDependsOn>
   </PropertyGroup>
-  
+
   <Target Name="_GenerateAvaloniaResourcesDependencyCache" BeforeTargets="GenerateAvaloniaResources">
+    <PropertyGroup>
+      <_AvaloniaResourcesInputsCacheFilePath>$(IntermediateOutputPath)/Avalonia/Resources.Inputs.cache</_AvaloniaResourcesInputsCacheFilePath>
+    </PropertyGroup>
+
     <ItemGroup>
-      <CustomAdditionalGenerateAvaloniaResourcesInputs Include="$(IntermediateOutputPath)/Avalonia/Resources.Inputs.cache" />
+      <CustomAdditionalGenerateAvaloniaResourcesInputs Include="$(_AvaloniaResourcesInputsCacheFilePath)" />
     </ItemGroup>
     
     <Hash ItemsToHash="@(AvaloniaResource);@(AvaloniaXaml);$(MSBuildAllProjects)">
@@ -55,34 +61,47 @@
     </Hash>
 
     <MakeDir Directories="$(IntermediateOutputPath)/Avalonia" />
-    <WriteLinesToFile Overwrite="true" File="$(IntermediateOutputPath)/Avalonia/Resources.Inputs.cache" Lines="$(AvaloniaResourcesDependencyHash)" WriteOnlyWhenDifferent="True" />
+    <WriteLinesToFile Overwrite="true" File="$(_AvaloniaResourcesInputsCacheFilePath)" Lines="$(AvaloniaResourcesDependencyHash)" WriteOnlyWhenDifferent="True" />
+
+    <ItemGroup>
+      <FileWrites Include="$(_AvaloniaResourcesInputsCacheFilePath)" />
+    </ItemGroup>
   </Target>
   
   <Target Name="GenerateAvaloniaResources" 
           BeforeTargets="CoreCompile;CoreResGen"
           Inputs="@(AvaloniaResource);@(AvaloniaXaml);@(CustomAdditionalGenerateAvaloniaResourcesInputs);$(MSBuildAllProjects)"
           Outputs="$(AvaloniaResourcesTemporaryFilePath)"
-	  DependsOnTargets="$(BuildAvaloniaResourcesDependsOn)">
+          DependsOnTargets="$(BuildAvaloniaResourcesDependsOn)"
+          Condition="('@(AvaloniaResource->Count())' &gt; 0) or ('@(AvaloniaXaml->Count())' &gt; 0)"
+          >
     <ItemGroup>
-        <AvaloniaResource Include="@(AvaloniaXaml)"/>
+      <AvaloniaResource Include="@(AvaloniaXaml)" />
     </ItemGroup>
     <GenerateAvaloniaResourcesTask
       Condition="'$(_AvaloniaUseExternalMSBuild)' != 'true'"
       Output="$(AvaloniaResourcesTemporaryFilePath)"
       Root="$(MSBuildProjectDirectory)"
       Resources="@(AvaloniaResource)"
-      EmbeddedResources="@(EmbeddedResources)"
       ReportImportance="$(AvaloniaXamlReportImportance)"/>
+    <ItemGroup Condition="'$(_AvaloniaUseExternalMSBuild)' != 'true'">
+      <FileWrites Include="$(AvaloniaResourcesTemporaryFilePath)" />
+    </ItemGroup>
     <Exec 
       Condition="'$(_AvaloniaUseExternalMSBuild)' == 'true'"
-      Command="dotnet msbuild /nodereuse:false $(MSBuildProjectFile) /t:GenerateAvaloniaResources /p:_AvaloniaForceInternalMSBuild=true /p:Configuration=$(Configuration) /p:TargetFramework=$(TargetFramework) /p:BuildProjectReferences=false"/>
+      Command="dotnet msbuild /nodereuse:false $(MSBuildProjectFile) /t:GenerateAvaloniaResources /p:_AvaloniaForceInternalMSBuild=true /p:Configuration=$(Configuration) /p:TargetFramework=$(TargetFramework) /p:RuntimeIdentifier=$(RuntimeIdentifier) /p:BuildProjectReferences=false"/>
 
   </Target>
 
   <Target
     Name="CompileAvaloniaXaml"
     AfterTargets="AfterCompile"
-    Condition="Exists('@(IntermediateAssembly)') And $(DesignTimeBuild) != true And $(EnableAvaloniaXamlCompilation) != false"
+    Condition="
+      (('@(AvaloniaResource->Count())' &gt; 0) 
+          or ('@(AvaloniaXaml->Count())' &gt; 0))
+      and Exists('@(IntermediateAssembly)') 
+      And $(DesignTimeBuild) != true 
+      And $(EnableAvaloniaXamlCompilation) != false"
     >
     <PropertyGroup>
       <AvaloniaXamlReferencesTemporaryFilePath Condition="'$(AvaloniaXamlReferencesTemporaryFilePath)' == ''">$(IntermediateOutputPath)/Avalonia/references</AvaloniaXamlReferencesTemporaryFilePath>
@@ -95,24 +114,29 @@
       File="$(AvaloniaXamlReferencesTemporaryFilePath)"
       Lines="@(ReferencePathWithRefAssemblies)"
       Overwrite="true" />
+    <ItemGroup Condition="'$(_AvaloniaForceInternalMSBuild)' != 'true'">
+      <FileWrites Include="$(AvaloniaXamlReferencesTemporaryFilePath)" />
+    </ItemGroup>
     <CompileAvaloniaXamlTask
       Condition="'$(_AvaloniaUseExternalMSBuild)' != 'true'"
       AssemblyFile="@(IntermediateAssembly)"
       ReferencesFilePath="$(AvaloniaXamlReferencesTemporaryFilePath)"
       OriginalCopyPath="$(AvaloniaXamlOriginalCopyFilePath)"
+      RefAssemblyFile="@(IntermediateRefAssembly)"
       ProjectDirectory="$(MSBuildProjectDirectory)"
       VerifyIl="$(AvaloniaXamlIlVerifyIl)"
       ReportImportance="$(AvaloniaXamlReportImportance)"
       AssemblyOriginatorKeyFile="$(AssemblyOriginatorKeyFile)"
       SignAssembly="$(SignAssembly)"
       DelaySign="$(DelaySign)"
-      EnableComInteropPatching="$(_AvaloniaPatchComInterop)"
       SkipXamlCompilation="$(_AvaloniaSkipXamlCompilation)"
       DebuggerLaunch="$(AvaloniaXamlIlDebuggerLaunch)"
-    />
+      DefaultCompileBindings="$(AvaloniaUseCompiledBindingsByDefault)">
+      <Output TaskParameter="WrittenFilePaths" ItemName="FileWrites" />
+    </CompileAvaloniaXamlTask>
     <Exec
       Condition="'$(_AvaloniaUseExternalMSBuild)' == 'true'"
-      Command="dotnet msbuild /nodereuse:false $(MSBuildProjectFile) /t:CompileAvaloniaXaml /p:_AvaloniaForceInternalMSBuild=true /p:Configuration=$(Configuration) /p:TargetFramework=$(TargetFramework) /p:BuildProjectReferences=false"/>
+      Command="dotnet msbuild /nodereuse:false $(MSBuildProjectFile) /t:CompileAvaloniaXaml /p:_AvaloniaForceInternalMSBuild=true /p:Configuration=$(Configuration) /p:TargetFramework=$(TargetFramework) /p:RuntimeIdentifier=$(RuntimeIdentifier) /p:BuildProjectReferences=false"/>
   </Target>
 
   

+ 3 - 1
readme.md

@@ -1,3 +1,5 @@
+[![GH_Banner](https://user-images.githubusercontent.com/552074/218457976-92e76834-9e22-4e35-acfa-aa50281bc0f9.png)](https://avaloniaui.net/xpf)
+
 [![Telegram](https://raw.githubusercontent.com/Patrolavia/telegram-badge/master/chat.svg)](https://t.me/Avalonia)
 [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/AvaloniaUI/Avalonia?utm_campaign=pr-badge&utm_content=badge&utm_medium=badge&utm_source=badge) [![Discord](https://img.shields.io/badge/discord-join%20chat-46BC99)]( https://aka.ms/dotnet-discord) [![Build Status](https://dev.azure.com/AvaloniaUI/AvaloniaUI/_apis/build/status/AvaloniaUI.Avalonia)](https://dev.azure.com/AvaloniaUI/AvaloniaUI/_build/latest?definitionId=4) [![Backers on Open Collective](https://opencollective.com/Avalonia/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/Avalonia/sponsors/badge.svg)](#sponsors) ![License](https://img.shields.io/github/license/avaloniaui/avalonia.svg)
 <br />
@@ -104,7 +106,7 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
 
 ## Commercial Support 
 
-We have a range of [support plans available](https://avaloniaui.net/support.html) for those looking to partner with the creators of Avalonia, enabling access to the best support at every step of the development process.
+We have a range of [support plans available](https://avaloniaui.net/support) for those looking to partner with the creators of Avalonia, enabling access to the best support at every step of the development process.
 
 *Please note that donations are not considered payment for commercial support agreements. Please contact us to discuss your needs first. [[email protected]](mailto://[email protected])*
 ## .NET Foundation

+ 3 - 4
samples/BindingDemo/App.xaml

@@ -2,8 +2,7 @@
     xmlns="https://github.com/avaloniaui" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     x:Class="BindingDemo.App">
-    <Application.Styles>
-        <FluentTheme />
-        <StyleInclude Source="avares://Avalonia.Themes.Default/Accents/BaseLight.xaml"/>
-    </Application.Styles>
+  <Application.Styles>
+    <FluentTheme />
+   </Application.Styles>
 </Application>

+ 1 - 0
samples/BindingDemo/BindingDemo.csproj

@@ -5,6 +5,7 @@
   </PropertyGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.Fonts.Inter\Avalonia.Fonts.Inter.csproj" />
     <ProjectReference Include="..\..\src\Avalonia.Themes.Fluent\Avalonia.Themes.Fluent.csproj" />
     <ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" />
     <ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />

+ 3 - 3
samples/BindingDemo/MainWindow.xaml

@@ -1,8 +1,8 @@
 <Window xmlns="https://github.com/avaloniaui"
         xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
         x:Class="BindingDemo.MainWindow"
-        xmlns:vm="clr-namespace:BindingDemo.ViewModels" 
-        xmlns:local="clr-namespace:BindingDemo"
+        xmlns:vm="using:BindingDemo.ViewModels" 
+        xmlns:local="using:BindingDemo"
         Title="AvaloniaUI Bindings Test"
         Width="800"
         Height="600"
@@ -81,7 +81,7 @@
           <TextBlock FontSize="16" Text="Multiple"/>
           <ListBox Items="{Binding Items}" SelectionMode="Multiple" Selection="{Binding Selection}"/>
         </StackPanel>
-        <ContentControl Content="{Binding SelectedItems[0]}">
+        <ContentControl Content="{ReflectionBinding Selection.SelectedItems[0]}">
           <ContentControl.DataTemplates>
             <DataTemplate DataType="vm:TestItem">
               <local:TestItemView></local:TestItemView>

+ 4 - 2
samples/BindingDemo/TestItemView.xaml

@@ -1,8 +1,10 @@
 <UserControl xmlns="https://github.com/avaloniaui"
         xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
-        x:Class="BindingDemo.TestItemView">
+        xmlns:viewModels="using:BindingDemo.ViewModels"
+        x:Class="BindingDemo.TestItemView"
+        x:DataType="viewModels:TestItem">
   <StackPanel>
     <TextBlock Classes="h1" Text="{Binding StringValue}"/>
     <TextBox Text="{Binding Detail}" AcceptsReturn="True"/>
   </StackPanel>
-</UserControl>
+</UserControl>

+ 2 - 10
samples/ControlCatalog.Android/MainActivity.cs

@@ -5,16 +5,8 @@ using Avalonia.Android;
 
 namespace ControlCatalog.Android
 {
-    [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
-    public class MainActivity : AvaloniaActivity<App>
+    [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.Main", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
+    public class MainActivity : AvaloniaMainActivity
     {
-        protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
-        {
-            return base.CustomizeAppBuilder(builder)
-                .AfterSetup(_ =>
-                {
-                    Pages.EmbedSample.Implementation = new EmbedSampleAndroid();
-                });
-        }
     }
 }

+ 5 - 1
samples/ControlCatalog.Android/Resources/values/styles.xml

@@ -4,7 +4,7 @@
   <style name="MyTheme">
   </style>
 
-  <style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.NoActionBar">
+  <style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
     <item name="android:windowActionBar">false</item>
     <item name="android:windowNoTitle">true</item>
   </style>
@@ -14,4 +14,8 @@
     <item name="android:windowContentOverlay">@null</item>
   </style>
 
+  <style name="MyTheme.Main" parent ="MyTheme.NoActionBar">
+    <item name="android:windowIsTranslucent">true</item>
+  </style>
+
 </resources>

+ 14 - 1
samples/ControlCatalog.Android/SplashActivity.cs

@@ -1,12 +1,23 @@
 using Android.App;
 using Android.Content;
+using Android.Content.PM;
 using Android.OS;
+using Avalonia.Android;
 
 namespace ControlCatalog.Android
 {
     [Activity(Theme = "@style/MyTheme.Splash", MainLauncher = true, NoHistory = true)]
-    public class SplashActivity : Activity
+    public class SplashActivity : AvaloniaSplashActivity<App>
     {
+        protected override Avalonia.AppBuilder CustomizeAppBuilder(Avalonia.AppBuilder builder)
+        {
+            return base.CustomizeAppBuilder(builder)
+                 .AfterSetup(_ =>
+                 {
+                     Pages.EmbedSample.Implementation = new EmbedSampleAndroid();
+                 });
+        }
+
         protected override void OnCreate(Bundle? savedInstanceState)
         {
             base.OnCreate(savedInstanceState);
@@ -17,6 +28,8 @@ namespace ControlCatalog.Android
             base.OnResume();
 
             StartActivity(new Intent(Application.Context, typeof(MainActivity)));
+
+            Finish();
         }
     }
 }

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.