ソースを参照

Merge branch 'master' into gtk-file-dialog-directory-navigation

Max Katz 3 年 前
コミット
97ce91eb6d
100 ファイル変更4314 行追加3411 行削除
  1. 1 1
      .editorconfig
  2. 1 2
      .gitignore
  3. 5 0
      .ncrunch/Avalonia.IntegrationTests.Appium.v3.ncrunchproject
  4. 5 0
      .ncrunch/Avalonia.IntegrationTests.Win32.v3.ncrunchproject
  5. 5 0
      .ncrunch/IntegrationTestApp.v3.ncrunchproject
  6. 192 388
      Avalonia.sln
  7. 2 0
      Directory.Build.props
  8. 1 0
      NuGet.Config
  9. 13 13
      azure-pipelines.yml
  10. 2 0
      build/ApiCompatAttributeExcludeList.txt
  11. 5 0
      build/AvaloniaPublicKey.props
  12. 0 9
      build/CoreLibraries.props
  13. 9 0
      build/DevAnalyzers.props
  14. 3 3
      build/HarfBuzzSharp.props
  15. 1 1
      build/ImageSharp.props
  16. 1 1
      build/JetBrains.dotMemoryUnit.props
  17. 0 1
      build/NetFX.props
  18. 1 1
      build/SharedVersion.props
  19. 3 3
      build/SkiaSharp.props
  20. 10 0
      build/SourceGenerators.props
  21. 1 1
      build/SourceLink.props
  22. 9 9
      build/XUnit.props
  23. 4 5
      dirs.proj
  24. 2 2
      global.json
  25. 5 0
      native/Avalonia.Native/inc/rendertarget.h
  26. 17 0
      native/Avalonia.Native/src/OSX/AutoFitContentView.h
  27. 106 0
      native/Avalonia.Native/src/OSX/AutoFitContentView.mm
  28. 80 6
      native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj
  29. 5 1
      native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/xcshareddata/xcschemes/Avalonia.Native.OSX.xcscheme
  30. 11 0
      native/Avalonia.Native/src/OSX/AvnPanelWindow.mm
  31. 1 0
      native/Avalonia.Native/src/OSX/AvnString.h
  32. 16 0
      native/Avalonia.Native/src/OSX/AvnString.mm
  33. 27 0
      native/Avalonia.Native/src/OSX/AvnView.h
  34. 712 0
      native/Avalonia.Native/src/OSX/AvnView.mm
  35. 466 0
      native/Avalonia.Native/src/OSX/AvnWindow.mm
  36. 17 0
      native/Avalonia.Native/src/OSX/INSWindowHolder.h
  37. 18 0
      native/Avalonia.Native/src/OSX/IWindowStateChanged.h
  38. 9 0
      native/Avalonia.Native/src/OSX/PopupImpl.h
  39. 61 0
      native/Avalonia.Native/src/OSX/PopupImpl.mm
  40. 24 0
      native/Avalonia.Native/src/OSX/ResizeScope.h
  41. 18 0
      native/Avalonia.Native/src/OSX/ResizeScope.mm
  42. 1 1
      native/Avalonia.Native/src/OSX/SystemDialogs.mm
  43. 136 0
      native/Avalonia.Native/src/OSX/WindowBaseImpl.h
  44. 618 0
      native/Avalonia.Native/src/OSX/WindowBaseImpl.mm
  45. 101 0
      native/Avalonia.Native/src/OSX/WindowImpl.h
  46. 554 0
      native/Avalonia.Native/src/OSX/WindowImpl.mm
  47. 17 0
      native/Avalonia.Native/src/OSX/WindowInterfaces.h
  48. 27 0
      native/Avalonia.Native/src/OSX/WindowProtocol.h
  49. 5 12
      native/Avalonia.Native/src/OSX/app.mm
  50. 12 0
      native/Avalonia.Native/src/OSX/automation.h
  51. 497 0
      native/Avalonia.Native/src/OSX/automation.mm
  52. 2 2
      native/Avalonia.Native/src/OSX/common.h
  53. 3 0
      native/Avalonia.Native/src/OSX/controlhost.mm
  54. 0 1
      native/Avalonia.Native/src/OSX/cursor.mm
  55. 11 6
      native/Avalonia.Native/src/OSX/main.mm
  56. 0 1
      native/Avalonia.Native/src/OSX/menu.h
  57. 2 4
      native/Avalonia.Native/src/OSX/menu.mm
  58. 0 4
      native/Avalonia.Native/src/OSX/rendertarget.mm
  59. 0 76
      native/Avalonia.Native/src/OSX/window.h
  60. 0 2529
      native/Avalonia.Native/src/OSX/window.mm
  61. 1 6
      nukebuild/Build.cs
  62. 1 2
      nukebuild/_build.csproj
  63. 0 5
      nukebuild/numerge.config
  64. 3 1
      packages/Avalonia/Avalonia.csproj
  65. 2 2
      readme.md
  66. 1 0
      samples/BindingDemo/BindingDemo.csproj
  67. 17 2
      samples/ControlCatalog.Android/ControlCatalog.Android.csproj
  68. 5 8
      samples/ControlCatalog.Android/MainActivity.cs
  69. 1 1
      samples/ControlCatalog.Android/Resources/values/styles.xml
  70. 0 10
      samples/ControlCatalog.Android/SplashActivity.cs
  71. 14 0
      samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
  72. 7 1
      samples/ControlCatalog.NetCore/Program.cs
  73. 29 13
      samples/ControlCatalog.Web/ControlCatalog.Web.csproj
  74. 0 28
      samples/ControlCatalog.Web/LinkerConfig.xml
  75. 11 181
      samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj
  76. 7 2
      samples/ControlCatalog.iOS/Info.plist
  77. 2 2
      samples/ControlCatalog.iOS/Main.cs
  78. 0 36
      samples/ControlCatalog.iOS/Properties/AssemblyInfo.cs
  79. 1 1
      samples/ControlCatalog.iOS/Resources/LaunchScreen.xib
  80. 12 6
      samples/ControlCatalog/App.xaml.cs
  81. 5 2
      samples/ControlCatalog/ControlCatalog.csproj
  82. 18 0
      samples/ControlCatalog/Converter/MathSubtractConverter.cs
  83. 17 0
      samples/ControlCatalog/MainView.xaml
  84. 17 4
      samples/ControlCatalog/MainView.xaml.cs
  85. 31 1
      samples/ControlCatalog/Pages/ButtonsPage.xaml
  86. 1 2
      samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml
  87. 3 2
      samples/ControlCatalog/Pages/CanvasPage.xaml
  88. 1 0
      samples/ControlCatalog/Pages/CarouselPage.xaml
  89. 3 0
      samples/ControlCatalog/Pages/CarouselPage.xaml.cs
  90. 23 0
      samples/ControlCatalog/Pages/ClipboardPage.xaml
  91. 77 0
      samples/ControlCatalog/Pages/ClipboardPage.xaml.cs
  92. 79 0
      samples/ControlCatalog/Pages/ColorPickerPage.xaml
  93. 19 0
      samples/ControlCatalog/Pages/ColorPickerPage.xaml.cs
  94. 10 0
      samples/ControlCatalog/Pages/ComboBoxPage.xaml
  95. 17 2
      samples/ControlCatalog/Pages/DataGridPage.xaml
  96. 3 3
      samples/ControlCatalog/Pages/DialogsPage.xaml.cs
  97. 7 1
      samples/ControlCatalog/Pages/DragAndDropPage.xaml
  98. 1 3
      samples/ControlCatalog/Pages/DragAndDropPage.xaml.cs
  99. 2 0
      samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml
  100. 11 1
      samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml.cs

+ 1 - 1
.editorconfig

@@ -137,7 +137,7 @@ space_within_single_line_array_initializer_braces = true
 csharp_wrap_before_ternary_opsigns = false
 
 # Xaml files
-[*.xaml]
+[*.{xaml,axaml}]
 indent_size = 2
 
 # Xml project files

+ 1 - 2
.gitignore

@@ -192,13 +192,12 @@ dirs.sln
 
 
 ##################
-# XCode
+# Xcode
 ##################
 Index/
 Logs/
 ModuleCache.noindex/
 Build/Intermediates.noindex/
-info.plist
 build-intermediate
 obj-Direct2D1/
 obj-Skia/

+ 5 - 0
.ncrunch/Avalonia.IntegrationTests.Appium.v3.ncrunchproject

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

+ 5 - 0
.ncrunch/Avalonia.IntegrationTests.Win32.v3.ncrunchproject

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

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

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

+ 192 - 388
Avalonia.sln

@@ -5,48 +5,26 @@ VisualStudioVersion = 17.0.31903.59
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Base", "src\Avalonia.Base\Avalonia.Base.csproj", "{B09B78D8-9B26-48B0-9149-D64A2F120F3F}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Visuals", "src\Avalonia.Visuals\Avalonia.Visuals.csproj", "{EB582467-6ABB-43A1-B052-E981BA910E3A}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Layout", "src\Avalonia.Layout\Avalonia.Layout.csproj", "{42472427-4774-4C81-8AFF-9F27B8E31721}"
-EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Windows", "Windows", "{B39A8919-9F95-48FE-AD7B-76E08B509888}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Win32", "src\Windows\Avalonia.Win32\Avalonia.Win32.csproj", "{811A76CF-1CF6-440F-963B-BBE31BD72A82}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Direct2D1", "src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj", "{3E908F67-5543-4879-A1DC-08EACE79B3CD}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Input", "src\Avalonia.Input\Avalonia.Input.csproj", "{62024B2D-53EB-4638-B26B-85EEAA54866E}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Interactivity", "src\Avalonia.Interactivity\Avalonia.Interactivity.csproj", "{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}"
-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.Styling", "src\Avalonia.Styling\Avalonia.Styling.csproj", "{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}"
-EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Themes.Default", "src\Avalonia.Themes.Default\Avalonia.Themes.Default.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
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Animation", "src\Avalonia.Animation\Avalonia.Animation.csproj", "{D211E587-D8BC-45B9-95A4-F297C8FA5200}"
-EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Styling.UnitTests", "tests\Avalonia.Styling.UnitTests\Avalonia.Styling.UnitTests.csproj", "{47ECDF59-DEF8-4C53-87B1-2098A3429059}"
-EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls.UnitTests", "tests\Avalonia.Controls.UnitTests\Avalonia.Controls.UnitTests.csproj", "{5CCB5571-7C30-4E7D-967D-0E2158EBD91F}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Visuals.UnitTests", "tests\Avalonia.Visuals.UnitTests\Avalonia.Visuals.UnitTests.csproj", "{76716382-3159-460E-BDA6-C5715CF606D7}"
-EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Base.UnitTests", "tests\Avalonia.Base.UnitTests\Avalonia.Base.UnitTests.csproj", "{2905FF23-53FB-45E6-AA49-6AF47A172056}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Layout.UnitTests", "tests\Avalonia.Layout.UnitTests\Avalonia.Layout.UnitTests.csproj", "{DB070A10-BF39-4752-8456-86E9D5928478}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Interactivity.UnitTests", "tests\Avalonia.Interactivity.UnitTests\Avalonia.Interactivity.UnitTests.csproj", "{08478EF5-44E8-42E9-92D6-15E00EC038D8}"
-EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Direct2D1.RenderTests", "tests\Avalonia.Direct2D1.RenderTests\Avalonia.Direct2D1.RenderTests.csproj", "{DABFD304-D6A4-4752-8123-C2CCF7AC7831}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Input.UnitTests", "tests\Avalonia.Input.UnitTests\Avalonia.Input.UnitTests.csproj", "{AC18926A-E784-40FE-B09D-BB0FE2B599F0}"
-EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Direct2D1.UnitTests", "tests\Avalonia.Direct2D1.UnitTests\Avalonia.Direct2D1.UnitTests.csproj", "{EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup.Xaml.UnitTests", "tests\Avalonia.Markup.Xaml.UnitTests\Avalonia.Markup.Xaml.UnitTests.csproj", "{99135EAB-653D-47E4-A378-C96E1278CA44}"
@@ -61,6 +39,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{A689DE
 	ProjectSection(SolutionItems) = preProject
 		.editorconfig = .editorconfig
 		src\Shared\ModuleInitializer.cs = src\Shared\ModuleInitializer.cs
+		src\Shared\SourceGeneratorAttributes.cs = src\Shared\SourceGeneratorAttributes.cs
 	EndProjectSection
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI", "src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj", "{6417B24E-49C2-4985-8DB2-3AB9D898EC91}"
@@ -77,8 +56,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Android", "Android", "{7CF9
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Android", "src\Android\Avalonia.Android\Avalonia.Android.csproj", "{7B92AF71-6287-4693-9DCB-BD5B6E927E23}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.AndroidTestApplication", "src\Android\Avalonia.AndroidTestApplication\Avalonia.AndroidTestApplication.csproj", "{FF69B927-C545-49AE-8E16-3D14D621AA12}"
-EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "iOS", "iOS", "{0CB0B92E-6CFF-4240-80A5-CCAFE75D91E1}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.iOS", "src\iOS\Avalonia.iOS\Avalonia.iOS.csproj", "{4488AD85-1495-4809-9AA4-DDFE0A48527E}"
@@ -95,8 +72,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog", "samples\C
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Desktop", "samples\ControlCatalog.Desktop\ControlCatalog.Desktop.csproj", "{2B888490-D14A-4BCA-AB4B-48676FA93C9B}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.iOS", "samples\ControlCatalog.iOS\ControlCatalog.iOS.csproj", "{57E0455D-D565-44BB-B069-EE1AA20F8337}"
-EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DesignerSupport.Tests", "tests\Avalonia.DesignerSupport.Tests\Avalonia.DesignerSupport.Tests.csproj", "{52F55355-D120-42AC-8116-8410A7D602FA}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DesignerSupport.TestApp", "tests\Avalonia.DesignerSupport.TestApp\Avalonia.DesignerSupport.TestApp.csproj", "{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}"
@@ -119,12 +94,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1
 		build\Base.props = build\Base.props
 		build\Binding.props = build\Binding.props
 		build\CoreLibraries.props = build\CoreLibraries.props
+		build\DevAnalyzers.props = build\DevAnalyzers.props
 		build\EmbedXaml.props = build\EmbedXaml.props
 		build\HarfBuzzSharp.props = build\HarfBuzzSharp.props
-		build\iOSWorkarounds.props = build\iOSWorkarounds.props
 		build\JetBrains.Annotations.props = build\JetBrains.Annotations.props
 		build\JetBrains.dotMemoryUnit.props = build\JetBrains.dotMemoryUnit.props
-		build\Magick.NET-Q16-AnyCPU.props = build\Magick.NET-Q16-AnyCPU.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
@@ -137,11 +111,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1
 		build\SharedVersion.props = build\SharedVersion.props
 		build\SharpDX.props = build\SharpDX.props
 		build\SkiaSharp.props = build\SkiaSharp.props
+		build\SourceGenerators.props = build\SourceGenerators.props
 		build\SourceLink.props = build\SourceLink.props
 		build\System.Drawing.Common.props = build\System.Drawing.Common.props
 		build\System.Memory.props = build\System.Memory.props
 		build\UnitTests.NetFX.props = build\UnitTests.NetFX.props
 		build\XUnit.props = build\XUnit.props
+		build\ImageSharp.props = build\ImageSharp.props
 	EndProjectSection
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{4D6FAF79-58B4-482F-9122-0668C346364C}"
@@ -177,8 +153,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.OpenGL", "src\Aval
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Native", "src\Avalonia.Native\Avalonia.Native.csproj", "{12A91A62-C064-42CA-9A8C-A1272F354388}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DesktopRuntime", "src\Avalonia.DesktopRuntime\Avalonia.DesktopRuntime.csproj", "{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}"
-EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Packages", "Packages", "{E870DCD7-F46A-498D-83FC-D0FD13E0A11C}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia", "packages\Avalonia\Avalonia.csproj", "{D49233F8-F29C-47DD-9975-C4C9E4502720}"
@@ -189,14 +163,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Build.Tasks", "src
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "nukebuild\_build.csproj", "{3F00BC43-5095-477F-93D8-E65B08179A00}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Animation.UnitTests", "tests\Avalonia.Animation.UnitTests\Avalonia.Animation.UnitTests.csproj", "{AF227847-E65C-4BE9-BCE9-B551357788E0}"
-EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.X11", "src\Avalonia.X11\Avalonia.X11.csproj", "{41B02319-965D-4945-8005-C1A3D1224165}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlatformSanityChecks", "samples\PlatformSanityChecks\PlatformSanityChecks.csproj", "{D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI.UnitTests", "tests\Avalonia.ReactiveUI.UnitTests\Avalonia.ReactiveUI.UnitTests.csproj", "{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}"
 EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls.ColorPicker", "src\Avalonia.Controls.ColorPicker\Avalonia.Controls.ColorPicker.csproj", "{1ECC012A-8837-4AE2-9BDA-3E2857898727}"
+EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls.DataGrid", "src\Avalonia.Controls.DataGrid\Avalonia.Controls.DataGrid.csproj", "{3278F3A9-9509-4A3F-A15B-BDC8B5BFF632}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Dialogs", "src\Avalonia.Dialogs\Avalonia.Dialogs.csproj", "{4D55985A-1EE2-4F25-AD39-6EA8BC04F8FB}"
@@ -221,6 +195,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.MicroCom", "src\Av
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MiniMvvm", "samples\MiniMvvm\MiniMvvm.csproj", "{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}"
 EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTestApp", "samples\IntegrationTestApp\IntegrationTestApp.csproj", "{676D6BFD-029D-4E43-BFC7-3892265CE251}"
+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}"
@@ -233,6 +211,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlSamples", "samples\S
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.PlatformSupport", "src\Avalonia.PlatformSupport\Avalonia.PlatformSupport.csproj", "{E8A597F0-2AB5-4BDA-A235-41162DAF53CF}"
 EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.iOS", "samples\ControlCatalog.iOS\ControlCatalog.iOS.csproj", "{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.PlatformSupport.UnitTests", "tests\Avalonia.PlatformSupport.UnitTests\Avalonia.PlatformSupport.UnitTests.csproj", "{CE910927-CE5A-456F-BC92-E4C757354A5C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.SourceGenerator", "src\Avalonia.SourceGenerator\Avalonia.SourceGenerator.csproj", "{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevAnalyzers", "src\tools\DevAnalyzers\DevAnalyzers.csproj", "{2B390431-288C-435C-BB6B-A374033BD8D1}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
@@ -273,54 +259,6 @@ Global
 		{B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Release|iPhone.Build.0 = Release|Any CPU
 		{B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Debug|iPhone.Build.0 = Debug|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Release|Any CPU.Build.0 = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Release|iPhone.Build.0 = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{EB582467-6ABB-43A1-B052-E981BA910E3A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Debug|iPhone.Build.0 = Debug|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Release|Any CPU.Build.0 = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Release|iPhone.Build.0 = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{42472427-4774-4C81-8AFF-9F27B8E31721}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
 		{811A76CF-1CF6-440F-963B-BBE31BD72A82}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
 		{811A76CF-1CF6-440F-963B-BBE31BD72A82}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
 		{811A76CF-1CF6-440F-963B-BBE31BD72A82}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@@ -369,54 +307,6 @@ Global
 		{3E908F67-5543-4879-A1DC-08EACE79B3CD}.Release|iPhone.Build.0 = Release|Any CPU
 		{3E908F67-5543-4879-A1DC-08EACE79B3CD}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{3E908F67-5543-4879-A1DC-08EACE79B3CD}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Debug|iPhone.Build.0 = Debug|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Release|Any CPU.Build.0 = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Release|iPhone.Build.0 = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{62024B2D-53EB-4638-B26B-85EEAA54866E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Debug|iPhone.Build.0 = Debug|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Release|Any CPU.Build.0 = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Release|iPhone.Build.0 = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
 		{D2221C82-4A25-4583-9B43-D791E3F6820C}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
 		{D2221C82-4A25-4583-9B43-D791E3F6820C}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
 		{D2221C82-4A25-4583-9B43-D791E3F6820C}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@@ -441,30 +331,6 @@ Global
 		{D2221C82-4A25-4583-9B43-D791E3F6820C}.Release|iPhone.Build.0 = Release|Any CPU
 		{D2221C82-4A25-4583-9B43-D791E3F6820C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{D2221C82-4A25-4583-9B43-D791E3F6820C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Debug|iPhone.Build.0 = Debug|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Release|Any CPU.Build.0 = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Release|iPhone.Build.0 = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
 		{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
 		{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
 		{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@@ -513,54 +379,6 @@ Global
 		{7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|iPhone.Build.0 = Release|Any CPU
 		{7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Debug|iPhone.Build.0 = Debug|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Release|Any CPU.Build.0 = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Release|iPhone.Build.0 = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Debug|iPhone.Build.0 = Debug|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Release|Any CPU.Build.0 = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Release|iPhone.Build.0 = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
 		{5CCB5571-7C30-4E7D-967D-0E2158EBD91F}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
 		{5CCB5571-7C30-4E7D-967D-0E2158EBD91F}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
 		{5CCB5571-7C30-4E7D-967D-0E2158EBD91F}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@@ -585,30 +403,6 @@ Global
 		{5CCB5571-7C30-4E7D-967D-0E2158EBD91F}.Release|iPhone.Build.0 = Release|Any CPU
 		{5CCB5571-7C30-4E7D-967D-0E2158EBD91F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{5CCB5571-7C30-4E7D-967D-0E2158EBD91F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Debug|iPhone.Build.0 = Debug|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Release|Any CPU.Build.0 = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Release|iPhone.Build.0 = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{76716382-3159-460E-BDA6-C5715CF606D7}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
 		{2905FF23-53FB-45E6-AA49-6AF47A172056}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
 		{2905FF23-53FB-45E6-AA49-6AF47A172056}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
 		{2905FF23-53FB-45E6-AA49-6AF47A172056}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@@ -633,54 +427,6 @@ Global
 		{2905FF23-53FB-45E6-AA49-6AF47A172056}.Release|iPhone.Build.0 = Release|Any CPU
 		{2905FF23-53FB-45E6-AA49-6AF47A172056}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{2905FF23-53FB-45E6-AA49-6AF47A172056}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Debug|iPhone.Build.0 = Debug|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Release|Any CPU.Build.0 = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Release|iPhone.Build.0 = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{DB070A10-BF39-4752-8456-86E9D5928478}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Debug|iPhone.Build.0 = Debug|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Release|Any CPU.Build.0 = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Release|iPhone.Build.0 = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
 		{DABFD304-D6A4-4752-8123-C2CCF7AC7831}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
 		{DABFD304-D6A4-4752-8123-C2CCF7AC7831}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
 		{DABFD304-D6A4-4752-8123-C2CCF7AC7831}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@@ -705,30 +451,6 @@ Global
 		{DABFD304-D6A4-4752-8123-C2CCF7AC7831}.Release|iPhone.Build.0 = Release|Any CPU
 		{DABFD304-D6A4-4752-8123-C2CCF7AC7831}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{DABFD304-D6A4-4752-8123-C2CCF7AC7831}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Debug|iPhone.Build.0 = Debug|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Release|Any CPU.Build.0 = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Release|iPhone.Build.0 = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
 		{EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
 		{EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
 		{EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@@ -911,22 +633,6 @@ Global
 		{7B92AF71-6287-4693-9DCB-BD5B6E927E23}.Release|Any CPU.Build.0 = Release|Any CPU
 		{7B92AF71-6287-4693-9DCB-BD5B6E927E23}.Release|iPhone.ActiveCfg = Release|Any CPU
 		{7B92AF71-6287-4693-9DCB-BD5B6E927E23}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.Release|Any CPU.Build.0 = Release|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.Release|Any CPU.Deploy.0 = Release|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{FF69B927-C545-49AE-8E16-3D14D621AA12}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{4488AD85-1495-4809-9AA4-DDFE0A48527E}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
 		{4488AD85-1495-4809-9AA4-DDFE0A48527E}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
 		{4488AD85-1495-4809-9AA4-DDFE0A48527E}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@@ -1095,26 +801,6 @@ Global
 		{2B888490-D14A-4BCA-AB4B-48676FA93C9B}.Release|iPhone.Build.0 = Release|Any CPU
 		{2B888490-D14A-4BCA-AB4B-48676FA93C9B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{2B888490-D14A-4BCA-AB4B-48676FA93C9B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.AppStore|iPhone.Build.0 = AppStore|iPhone
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Debug|Any CPU.ActiveCfg = Debug|iPhone
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Debug|iPhone.ActiveCfg = Debug|iPhone
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Debug|iPhone.Build.0 = Debug|iPhone
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Release|Any CPU.ActiveCfg = Release|iPhone
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Release|iPhone.ActiveCfg = Release|iPhone
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Release|iPhone.Build.0 = Release|iPhone
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
-		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
 		{52F55355-D120-42AC-8116-8410A7D602FA}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
 		{52F55355-D120-42AC-8116-8410A7D602FA}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
 		{52F55355-D120-42AC-8116-8410A7D602FA}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@@ -1559,30 +1245,6 @@ Global
 		{12A91A62-C064-42CA-9A8C-A1272F354388}.Release|iPhone.Build.0 = Release|Any CPU
 		{12A91A62-C064-42CA-9A8C-A1272F354388}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{12A91A62-C064-42CA-9A8C-A1272F354388}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.AppStore|Any CPU.Build.0 = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.AppStore|iPhone.Build.0 = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Debug|iPhone.Build.0 = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Release|Any CPU.Build.0 = Release|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Release|iPhone.Build.0 = Release|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{878FEFE0-CD14-41CB-90B0-DBCB163E8F15}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
 		{D49233F8-F29C-47DD-9975-C4C9E4502720}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
 		{D49233F8-F29C-47DD-9975-C4C9E4502720}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
 		{D49233F8-F29C-47DD-9975-C4C9E4502720}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
@@ -1679,30 +1341,6 @@ Global
 		{3F00BC43-5095-477F-93D8-E65B08179A00}.Release|iPhone.Build.0 = Release|Any CPU
 		{3F00BC43-5095-477F-93D8-E65B08179A00}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{3F00BC43-5095-477F-93D8-E65B08179A00}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.AppStore|Any CPU.Build.0 = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.AppStore|iPhone.Build.0 = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Debug|iPhone.Build.0 = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Release|Any CPU.Build.0 = Release|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Release|iPhone.Build.0 = Release|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{AF227847-E65C-4BE9-BCE9-B551357788E0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
 		{41B02319-965D-4945-8005-C1A3D1224165}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
 		{41B02319-965D-4945-8005-C1A3D1224165}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
 		{41B02319-965D-4945-8005-C1A3D1224165}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
@@ -2063,6 +1701,54 @@ Global
 		{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhone.Build.0 = Release|Any CPU
 		{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.AppStore|iPhone.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Release|Any CPU.Build.0 = Release|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Release|iPhone.Build.0 = Release|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{676D6BFD-029D-4E43-BFC7-3892265CE251}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.AppStore|iPhone.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|iPhoneSimulator.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
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|iPhone.Build.0 = Release|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
 		{25831348-EB2A-483E-9576-E8F6528674A5}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
 		{25831348-EB2A-483E-9576-E8F6528674A5}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
 		{25831348-EB2A-483E-9576-E8F6528674A5}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
@@ -2183,6 +1869,126 @@ Global
 		{E8A597F0-2AB5-4BDA-A235-41162DAF53CF}.Release|iPhone.Build.0 = Release|Any CPU
 		{E8A597F0-2AB5-4BDA-A235-41162DAF53CF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{E8A597F0-2AB5-4BDA-A235-41162DAF53CF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.AppStore|iPhone.Build.0 = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Release|iPhone.Build.0 = Release|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.AppStore|iPhone.Build.0 = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Release|iPhone.Build.0 = Release|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{CE910927-CE5A-456F-BC92-E4C757354A5C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.AppStore|iPhone.Build.0 = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Release|iPhone.Build.0 = Release|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{CA932DF3-2616-4BF6-8F28-1AD0EC40F1FF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.AppStore|iPhone.Build.0 = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Release|iPhone.Build.0 = Release|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{2B390431-288C-435C-BB6B-A374033BD8D1}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.AppStore|iPhone.Build.0 = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Release|Any CPU.Build.0 = Release|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Release|iPhone.Build.0 = Release|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{1ECC012A-8837-4AE2-9BDA-3E2857898727}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -2190,14 +1996,9 @@ Global
 	GlobalSection(NestedProjects) = preSolution
 		{811A76CF-1CF6-440F-963B-BBE31BD72A82} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
 		{3E908F67-5543-4879-A1DC-08EACE79B3CD} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
-		{47ECDF59-DEF8-4C53-87B1-2098A3429059} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{5CCB5571-7C30-4E7D-967D-0E2158EBD91F} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
-		{76716382-3159-460E-BDA6-C5715CF606D7} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{2905FF23-53FB-45E6-AA49-6AF47A172056} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
-		{DB070A10-BF39-4752-8456-86E9D5928478} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
-		{08478EF5-44E8-42E9-92D6-15E00EC038D8} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{DABFD304-D6A4-4752-8123-C2CCF7AC7831} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
-		{AC18926A-E784-40FE-B09D-BB0FE2B599F0} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{99135EAB-653D-47E4-A378-C96E1278CA44} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{3E53A01A-B331-47F3-B828-4A5717E77A24} = {8B6A8209-894F-4BA1-B880-965FD453982C}
@@ -2205,14 +2006,12 @@ Global
 		{8EF392D5-1416-45AA-9956-7CBBC3229E8A} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{08B3E6B9-1CD5-443C-9F61-6D49D1C5F162} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{7B92AF71-6287-4693-9DCB-BD5B6E927E23} = {7CF9789C-F1D3-4D0E-90E5-F1DF67A2753F}
-		{FF69B927-C545-49AE-8E16-3D14D621AA12} = {7CF9789C-F1D3-4D0E-90E5-F1DF67A2753F}
 		{4488AD85-1495-4809-9AA4-DDFE0A48527E} = {0CB0B92E-6CFF-4240-80A5-CCAFE75D91E1}
 		{E1AA3DBF-9056-4530-9376-18119A7A3FFE} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{88060192-33D5-4932-B0F9-8BD2763E857D} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{D0A739B9-3C68-4BA6-A328-41606954B6BD} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{2B888490-D14A-4BCA-AB4B-48676FA93C9B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
-		{57E0455D-D565-44BB-B069-EE1AA20F8337} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{52F55355-D120-42AC-8116-8410A7D602FA} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{F1381F98-4D24-409A-A6C5-1C5B1E08BB08} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{FBCAF3D0-2808-4934-8E96-3F607594517B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
@@ -2221,6 +2020,7 @@ Global
 		{29132311-1848-4FD6-AE0C-4FF841151BD3} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{7D2D3083-71DD-4CC9-8907-39A0D86FB322} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
 		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+		{86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B} = {A689DEF5-D50F-4975-8B72-124C9EB54066}
 		{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}
@@ -2231,7 +2031,6 @@ Global
 		{E1240B49-7B4B-4371-A00E-068778C5CF0B} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{D49233F8-F29C-47DD-9975-C4C9E4502720} = {E870DCD7-F46A-498D-83FC-D0FD13E0A11C}
 		{3C471044-3640-45E3-B1B2-16D2FF8399EE} = {E870DCD7-F46A-498D-83FC-D0FD13E0A11C}
-		{AF227847-E65C-4BE9-BCE9-B551357788E0} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{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}
@@ -2240,10 +2039,15 @@ Global
 		{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}
+		{CE910927-CE5A-456F-BC92-E4C757354A5C} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
+		{2B390431-288C-435C-BB6B-A374033BD8D1} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}

+ 2 - 0
Directory.Build.props

@@ -1,9 +1,11 @@
 <Project>
+  <Import Project="$(MSBuildThisFileDirectory)/build/AvaloniaPublicKey.props"/>
   <PropertyGroup>
       <PackageOutputPath Condition="'$(PackageOutputPath)' == ''">$(MSBuildThisFileDirectory)build-intermediate/nuget</PackageOutputPath>
       <AvaloniaPreviewerNetCoreToolPath>$(MSBuildThisFileDirectory)\src\tools\Avalonia.Designer.HostApp\bin\$(Configuration)\netcoreapp2.0\Avalonia.Designer.HostApp.dll</AvaloniaPreviewerNetCoreToolPath>
       <!-- https://github.com/dotnet/msbuild/issues/2661 -->
       <AddSyntheticProjectReferencesForSolutionDependencies>false</AddSyntheticProjectReferencesForSolutionDependencies>
       <MSBuildEnableWorkloadResolver>false</MSBuildEnableWorkloadResolver>
+      <RunApiCompat>False</RunApiCompat>
   </PropertyGroup>
 </Project>

+ 1 - 0
NuGet.Config

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

+ 13 - 13
azure-pipelines.yml

@@ -31,14 +31,14 @@ jobs:
     vmImage: 'ubuntu-20.04'
   steps:
   - task: UseDotNet@2
-    displayName: 'Use .NET Core SDK 3.1.414'
+    displayName: 'Use .NET Core SDK 3.1.418'
     inputs:
-      version: 3.1.414
+      version: 3.1.418
 
   - task: UseDotNet@2
-    displayName: 'Use .NET Core SDK 6.0.100'
+    displayName: 'Use .NET Core SDK 6.0.202'
     inputs:
-      version: 6.0.100
+      version: 6.0.202
 
   - task: CmdLine@2
     displayName: 'Run Build'
@@ -62,14 +62,14 @@ jobs:
     vmImage: 'macOS-10.15'
   steps:
   - task: UseDotNet@2
-    displayName: 'Use .NET Core SDK 3.1.414'
+    displayName: 'Use .NET Core SDK 3.1.418'
     inputs:
-      version: 3.1.414
+      version: 3.1.418
 
   - task: UseDotNet@2
-    displayName: 'Use .NET Core SDK 6.0.100'
+    displayName: 'Use .NET Core SDK 6.0.202'
     inputs:
-      version: 6.0.100
+      version: 6.0.202
       
   - task: CmdLine@2
     displayName: 'Install Mono 5.18'
@@ -134,20 +134,20 @@ jobs:
     SolutionDir: '$(Build.SourcesDirectory)'
   steps:
   - task: UseDotNet@2
-    displayName: 'Use .NET Core SDK 3.1.414'
+    displayName: 'Use .NET Core SDK 3.1.418'
     inputs:
-      version: 3.1.414
+      version: 3.1.418
 
   - task: UseDotNet@2
-    displayName: 'Use .NET Core SDK 6.0.100'
+    displayName: 'Use .NET Core SDK 6.0.202'
     inputs:
-      version: 6.0.100
+      version: 6.0.202
 
   - task: CmdLine@2
     displayName: 'Install Workloads'
     inputs:
       script: |
-       dotnet workload install android
+       dotnet workload install android ios
 
   - task: CmdLine@2
     displayName: 'Install Nuke'

+ 2 - 0
build/ApiCompatAttributeExcludeList.txt

@@ -0,0 +1,2 @@
+T:Avalonia.Metadata.NotClientImplementableAttribute
+T:Avalonia.Metadata.UnstableAttribute

+ 5 - 0
build/AvaloniaPublicKey.props

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

+ 0 - 9
build/CoreLibraries.props

@@ -1,22 +1,13 @@
 <Project>
   <ItemGroup>
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Base/Avalonia.Base.csproj" />
-      <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Animation/Avalonia.Animation.csproj" />
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Controls/Avalonia.Controls.csproj" />
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj" />
-      <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Input/Avalonia.Input.csproj" />
-      <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Interactivity/Avalonia.Interactivity.csproj" />
-      <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Layout/Avalonia.Layout.csproj" />
-      <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Visuals/Avalonia.Visuals.csproj" />
-      <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Styling/Avalonia.Styling.csproj" />
-      <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj" />
-      <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Themes.Fluent/Avalonia.Themes.Fluent.csproj" />
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.OpenGL/Avalonia.OpenGL.csproj" />
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Dialogs/Avalonia.Dialogs.csproj" />
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Markup/Avalonia.Markup/Avalonia.Markup.csproj" />
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj" />
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.MicroCom/Avalonia.MicroCom.csproj" />
-      <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.DesktopRuntime/Avalonia.DesktopRuntime.csproj" Condition="'$(TargetFramework)' != 'netstandard2.0'" />
       <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.PlatformSupport/Avalonia.PlatformSupport.csproj" />
   </ItemGroup>
 </Project>

+ 9 - 0
build/DevAnalyzers.props

@@ -0,0 +1,9 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ProjectReference Include="$(MSBuildThisFileDirectory)..\src\tools\DevAnalyzers\DevAnalyzers.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-preview.178" />
-    <PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.8.2-preview.178" />
-    <PackageReference Condition="'$(IncludeWasmSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.WebAssembly" Version="2.8.2-preview.178"/>
+    <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" />
   </ItemGroup>
 </Project>

+ 1 - 1
build/Magick.NET-Q16-AnyCPU.props → build/ImageSharp.props

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

+ 1 - 1
build/JetBrains.dotMemoryUnit.props

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

+ 0 - 1
build/NetFX.props

@@ -1,7 +1,6 @@
 <Project>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
   </ItemGroup>
 
 </Project>

+ 1 - 1
build/SharedVersion.props

@@ -11,7 +11,7 @@
     <LangVersion>latest</LangVersion>
     <PackageLicenseExpression>MIT</PackageLicenseExpression>
     <PackageIcon>Icon.png</PackageIcon>
-    <PackageDescription>Avalonia is a WPF/UWP-inspired cross-platform XAML-based UI framework providing a flexible styling system and supporting a wide range of Operating Systems such as Windows (.NET Framework, .NET Core), Linux (via Xorg), MacOS and with experimental support for Android and iOS.</PackageDescription>
+    <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>
     <PackageTags>avalonia;avaloniaui;mvvm;rx;reactive extensions;android;ios;mac;forms;wpf;net;netstandard;net461;uwp;xamarin</PackageTags>
     <PackageReleaseNotes>https://github.com/AvaloniaUI/Avalonia/releases</PackageReleaseNotes>
     <RepositoryType>git</RepositoryType>

+ 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.0-preview.178" />
-    <PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="SkiaSharp.NativeAssets.Linux" Version="2.88.0-preview.178" />
-    <PackageReference Condition="'$(IncludeWasmSkia)' == 'true'" Include="SkiaSharp.NativeAssets.WebAssembly" Version="2.88.0-preview.178"/>
+    <PackageReference Include="SkiaSharp" Version="2.88.0" />
+    <PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="SkiaSharp.NativeAssets.Linux" Version="2.88.0" />
+    <PackageReference Condition="'$(IncludeWasmSkia)' == 'true'" Include="SkiaSharp.NativeAssets.WebAssembly" Version="2.88.0" />
   </ItemGroup>
 </Project>

+ 10 - 0
build/SourceGenerators.props

@@ -0,0 +1,10 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ProjectReference 
+      Include="$(MSBuildThisFileDirectory)/../src/Avalonia.SourceGenerator/Avalonia.SourceGenerator.csproj" 
+      OutputItemType="Analyzer" 
+      ReferenceOutputAssembly="false"
+      PrivateAssets="all" />
+    <Compile Include="$(MSBuildThisFileDirectory)/../src/Shared/SourceGeneratorAttributes.cs" />
+  </ItemGroup>
+</Project>

+ 1 - 1
build/SourceLink.props

@@ -19,7 +19,7 @@
   </PropertyGroup>
   
   <ItemGroup>
-    <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
+    <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All"/>
   </ItemGroup>
 
   <!-- Workaround for https://github.com/dotnet/sdk/issues/11105 -->

+ 9 - 9
build/XUnit.props

@@ -1,14 +1,14 @@
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
-    <PackageReference Include="xunit" Version="2.3.0" />
-    <PackageReference Include="xunit.abstractions" Version="2.0.1" />
-    <PackageReference Include="xunit.assert" Version="2.3.0" />
-    <PackageReference Include="xunit.core" Version="2.3.0" />
-    <PackageReference Include="xunit.extensibility.core" Version="2.3.0" />
-    <PackageReference Include="xunit.extensibility.execution" Version="2.3.0" />
-    <PackageReference Include="xunit.runner.console" Version="2.3.0" />
-    <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0" />
-    <PackageReference Include="Xunit.SkippableFact" Version="1.3.6" />
+    <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.SkippableFact" Version="1.4.13" />
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
   </ItemGroup>
   <PropertyGroup>

+ 4 - 5
dirs.proj

@@ -10,21 +10,20 @@
     <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" />
   </ItemGroup>
-  <ItemGroup Condition="!Exists('$(MSBuildExtensionsPath)\Xamarin\iOS')">
-    <ProjectReference Remove="src/iOS/**/*.*proj" />
-    <ProjectReference Remove="samples/ControlCatalog.iOS/ControlCatalog.iOS.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 projects only on Windows, where we have installed android workload -->
+  <!-- Build android and iOS projects only on Windows, where we have installed android workload -->
   <ItemGroup Condition="!$([MSBuild]::IsOsPlatform('Windows'))">
     <ProjectReference Remove="src/Android/**/*.*proj" />
+    <ProjectReference Remove="src/iOS/**/*.*proj" />
   </ItemGroup>
 
   <ItemGroup>

+ 2 - 2
global.json

@@ -1,10 +1,10 @@
 {
     "sdk": {
-        "version": "6.0.100"
+        "version": "6.0.202",
+        "rollForward": "latestFeature"
     },
     "msbuild-sdks": {
         "Microsoft.Build.Traversal": "1.0.43",
-        "Xamarin.Legacy.Sdk": "0.1.2-alpha6",
         "MSBuild.Sdk.Extras": "3.0.22",
         "AggregatePackage.NuGet.Sdk" : "0.1.12"
     }

+ 5 - 0
native/Avalonia.Native/inc/rendertarget.h

@@ -1,3 +1,8 @@
+#pragma once
+
+#include "com.h"
+#include "comimpl.h"
+#include "avalonia-native.h"
 
 @protocol IRenderTarget
 -(void) setNewLayer: (CALayer*) layer;

+ 17 - 0
native/Avalonia.Native/src/OSX/AutoFitContentView.h

@@ -0,0 +1,17 @@
+//
+// Created by Dan Walmsley on 05/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#pragma once
+
+#import <Foundation/Foundation.h>
+#include "avalonia-native.h"
+
+@interface AutoFitContentView : NSView
+-(AutoFitContentView* _Nonnull) initWithContent: (NSView* _Nonnull) content;
+-(void) ShowTitleBar: (bool) show;
+-(void) SetTitleBarHeightHint: (double) height;
+
+-(void) ShowBlur: (bool) show;
+@end

+ 106 - 0
native/Avalonia.Native/src/OSX/AutoFitContentView.mm

@@ -0,0 +1,106 @@
+//
+// Created by Dan Walmsley on 05/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#include "AvnView.h"
+#include "AutoFitContentView.h"
+#include "WindowInterfaces.h"
+#include "WindowProtocol.h"
+
+@implementation AutoFitContentView
+{
+    NSVisualEffectView* _titleBarMaterial;
+    NSBox* _titleBarUnderline;
+    NSView* _content;
+    NSVisualEffectView* _blurBehind;
+    double _titleBarHeightHint;
+    bool _settingSize;
+}
+
+-(AutoFitContentView* _Nonnull) initWithContent:(NSView *)content
+{
+    _titleBarHeightHint = -1;
+    _content = content;
+    _settingSize = false;
+
+    [self setAutoresizesSubviews:true];
+    [self setWantsLayer:true];
+
+    _titleBarMaterial = [NSVisualEffectView new];
+    [_titleBarMaterial setBlendingMode:NSVisualEffectBlendingModeWithinWindow];
+    [_titleBarMaterial setMaterial:NSVisualEffectMaterialTitlebar];
+    [_titleBarMaterial setWantsLayer:true];
+    _titleBarMaterial.hidden = true;
+
+    _titleBarUnderline = [NSBox new];
+    _titleBarUnderline.boxType = NSBoxSeparator;
+    _titleBarUnderline.fillColor = [NSColor underPageBackgroundColor];
+    _titleBarUnderline.hidden = true;
+
+    [self addSubview:_titleBarMaterial];
+    [self addSubview:_titleBarUnderline];
+
+    _blurBehind = [NSVisualEffectView new];
+    [_blurBehind setBlendingMode:NSVisualEffectBlendingModeBehindWindow];
+    [_blurBehind setMaterial:NSVisualEffectMaterialLight];
+    [_blurBehind setWantsLayer:true];
+    _blurBehind.hidden = true;
+
+    [_blurBehind setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+    [_content setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+
+    [self addSubview:_blurBehind];
+    [self addSubview:_content];
+
+    [self setWantsLayer:true];
+    return self;
+}
+
+-(void) ShowBlur:(bool)show
+{
+    _blurBehind.hidden = !show;
+}
+
+-(void) ShowTitleBar: (bool) show
+{
+    _titleBarMaterial.hidden = !show;
+    _titleBarUnderline.hidden = !show;
+}
+
+-(void) SetTitleBarHeightHint: (double) height
+{
+    _titleBarHeightHint = height;
+
+    [self setFrameSize:self.frame.size];
+}
+
+-(void)setFrameSize:(NSSize)newSize
+{
+    if(_settingSize)
+    {
+        return;
+    }
+
+    _settingSize = true;
+    [super setFrameSize:newSize];
+
+    auto window = (id <AvnWindowProtocol>) [self window];
+
+    // TODO get actual titlebar size
+
+    double height = _titleBarHeightHint == -1 ? [window getExtendedTitleBarHeight] : _titleBarHeightHint;
+
+    NSRect tbar;
+    tbar.origin.x = 0;
+    tbar.origin.y = newSize.height - height;
+    tbar.size.width = newSize.width;
+    tbar.size.height = height;
+
+    [_titleBarMaterial setFrame:tbar];
+    tbar.size.height = height < 1 ? 0 : 1;
+    [_titleBarUnderline setFrame:tbar];
+
+    _settingSize = false;
+}
+@end

+ 80 - 6
native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj

@@ -7,6 +7,24 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		18391068E48EF96E3DB5FDAB /* ResizeScope.mm in Sources */ = {isa = PBXBuildFile; fileRef = 18391E45702740FE9DD69695 /* ResizeScope.mm */; };
+		1839125F057B0A4EB1760058 /* WindowImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 183919BF108EB72A029F7671 /* WindowImpl.mm */; };
+		183914E50CF6D2EFC1667F7C /* WindowInterfaces.h in Headers */ = {isa = PBXBuildFile; fileRef = 18391DB45C7D892E61BF388C /* WindowInterfaces.h */; };
+		1839151F32D1BB1AB51A7BB6 /* AvnPanelWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = 18391884C7476DA4E53A492D /* AvnPanelWindow.mm */; };
+		183916173528EC2737DBE5E1 /* WindowBaseImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 183915BFF0E234CD3604A7CD /* WindowBaseImpl.h */; };
+		1839171DCC651B0638603AC4 /* INSWindowHolder.h in Headers */ = {isa = PBXBuildFile; fileRef = 18391BBB7782C296D424071F /* INSWindowHolder.h */; };
+		1839179A55FC1421BEE83330 /* WindowBaseImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 18391676ECF0E983F4964357 /* WindowBaseImpl.mm */; };
+		183919D91DB9AAB5D700C2EA /* WindowImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 18391CD090AA776E7E841AC9 /* WindowImpl.h */; };
+		18391AA7E0BBA74D184C5734 /* AutoFitContentView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1839166350F32661F3ABD70F /* AutoFitContentView.mm */; };
+		18391AC16726CBC45856233B /* AvnWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1839155B28B20FFB672D29C6 /* AvnWindow.mm */; };
+		18391AC65ADD7DDD33FBE737 /* PopupImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 183910513F396141938832B5 /* PopupImpl.h */; };
+		18391C28BF1823B5464FDD36 /* ResizeScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 1839171D898F9BFC1373631A /* ResizeScope.h */; };
+		18391CF07316F819E76B617C /* IWindowStateChanged.h in Headers */ = {isa = PBXBuildFile; fileRef = 183913C6BFD6856BD42D19FD /* IWindowStateChanged.h */; };
+		18391D4EB311BC7EF8B8C0A6 /* AvnView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1839132D0E2454D911F1D1F9 /* AvnView.mm */; };
+		18391D8CD1756DC858DC1A09 /* PopupImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 18391BB698579F40F1783F31 /* PopupImpl.mm */; };
+		18391E1381E2D5BFD60265A9 /* AutoFitContentView.h in Headers */ = {isa = PBXBuildFile; fileRef = 18391654EF0E7AB3D3AB4071 /* AutoFitContentView.h */; };
+		18391ED5F611FF62C45F196D /* AvnView.h in Headers */ = {isa = PBXBuildFile; fileRef = 18391D1669284AD2EC9E866A /* AvnView.h */; };
+		18391F1E2411C79405A9943A /* WindowProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 1839122E037567BDD1D09DEB /* WindowProtocol.h */; };
 		1A002B9E232135EE00021753 /* app.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A002B9D232135EE00021753 /* app.mm */; };
 		1A1852DC23E05814008F0DED /* deadlock.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A1852DB23E05814008F0DED /* deadlock.mm */; };
 		1A3E5EA823E9E83B00EDE661 /* rendertarget.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */; };
@@ -28,11 +46,30 @@
 		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 */; };
-		AB661C202148286E00291242 /* window.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB661C1F2148286E00291242 /* window.mm */; };
 		AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */; };
+		BC11A5BE2608D58F0017BAD0 /* automation.h in Headers */ = {isa = PBXBuildFile; fileRef = BC11A5BC2608D58F0017BAD0 /* automation.h */; };
+		BC11A5BF2608D58F0017BAD0 /* automation.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC11A5BD2608D58F0017BAD0 /* automation.mm */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
+		183910513F396141938832B5 /* PopupImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopupImpl.h; sourceTree = "<group>"; };
+		1839122E037567BDD1D09DEB /* WindowProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowProtocol.h; sourceTree = "<group>"; };
+		1839132D0E2454D911F1D1F9 /* AvnView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AvnView.mm; sourceTree = "<group>"; };
+		183913C6BFD6856BD42D19FD /* IWindowStateChanged.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IWindowStateChanged.h; sourceTree = "<group>"; };
+		1839155B28B20FFB672D29C6 /* AvnWindow.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AvnWindow.mm; sourceTree = "<group>"; };
+		183915BFF0E234CD3604A7CD /* WindowBaseImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowBaseImpl.h; sourceTree = "<group>"; };
+		18391654EF0E7AB3D3AB4071 /* AutoFitContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoFitContentView.h; sourceTree = "<group>"; };
+		1839166350F32661F3ABD70F /* AutoFitContentView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AutoFitContentView.mm; sourceTree = "<group>"; };
+		18391676ECF0E983F4964357 /* WindowBaseImpl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WindowBaseImpl.mm; sourceTree = "<group>"; };
+		1839171D898F9BFC1373631A /* ResizeScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResizeScope.h; sourceTree = "<group>"; };
+		18391884C7476DA4E53A492D /* AvnPanelWindow.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AvnPanelWindow.mm; sourceTree = "<group>"; };
+		183919BF108EB72A029F7671 /* WindowImpl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WindowImpl.mm; sourceTree = "<group>"; };
+		18391BB698579F40F1783F31 /* PopupImpl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PopupImpl.mm; sourceTree = "<group>"; };
+		18391BBB7782C296D424071F /* INSWindowHolder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INSWindowHolder.h; sourceTree = "<group>"; };
+		18391CD090AA776E7E841AC9 /* WindowImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowImpl.h; sourceTree = "<group>"; };
+		18391D1669284AD2EC9E866A /* AvnView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AvnView.h; sourceTree = "<group>"; };
+		18391DB45C7D892E61BF388C /* WindowInterfaces.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowInterfaces.h; sourceTree = "<group>"; };
+		18391E45702740FE9DD69695 /* ResizeScope.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ResizeScope.mm; sourceTree = "<group>"; };
 		1A002B9D232135EE00021753 /* app.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = app.mm; sourceTree = "<group>"; };
 		1A1852DB23E05814008F0DED /* deadlock.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = deadlock.mm; sourceTree = "<group>"; };
 		1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = rendertarget.mm; sourceTree = "<group>"; };
@@ -46,7 +83,6 @@
 		37A4E71A2178846A00EACBCD /* headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = headers; path = ../../inc; sourceTree = "<group>"; };
 		37A517B22159597E00FBA241 /* Screens.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Screens.mm; sourceTree = "<group>"; };
 		37C09D8721580FE4006A6758 /* SystemDialogs.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SystemDialogs.mm; sourceTree = "<group>"; };
-		37C09D8A21581EF2006A6758 /* window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = window.h; sourceTree = "<group>"; };
 		37DDA9AF219330F8002E132B /* AvnString.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AvnString.mm; sourceTree = "<group>"; };
 		37DDA9B121933371002E132B /* AvnString.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AvnString.h; sourceTree = "<group>"; };
 		37E2330E21583241000CB7E2 /* KeyTransform.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyTransform.mm; sourceTree = "<group>"; };
@@ -60,10 +96,11 @@
 		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; };
-		AB661C1F2148286E00291242 /* window.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = window.mm; sourceTree = "<group>"; };
 		AB661C212148288600291242 /* common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
 		AB7A61EF2147C815003C5833 /* libAvalonia.Native.OSX.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libAvalonia.Native.OSX.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
 		AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = platformthreading.mm; sourceTree = "<group>"; };
+		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>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -97,6 +134,8 @@
 		AB7A61E62147C814003C5833 = {
 			isa = PBXGroup;
 			children = (
+				BC11A5BC2608D58F0017BAD0 /* automation.h */,
+				BC11A5BD2608D58F0017BAD0 /* automation.mm */,
 				1A1852DB23E05814008F0DED /* deadlock.mm */,
 				1A002B9D232135EE00021753 /* app.mm */,
 				37DDA9B121933371002E132B /* AvnString.h */,
@@ -112,8 +151,6 @@
 				AB661C212148288600291242 /* common.h */,
 				379860FE214DA0C000CD0246 /* KeyTransform.h */,
 				37E2330E21583241000CB7E2 /* KeyTransform.mm */,
-				AB661C1F2148286E00291242 /* window.mm */,
-				37C09D8A21581EF2006A6758 /* window.h */,
 				AB00E4F62147CA920032A60A /* main.mm */,
 				37155CE3233C00EB0034DCE9 /* menu.h */,
 				520624B222973F4100C4DCEF /* menu.mm */,
@@ -124,6 +161,24 @@
 				37C09D8721580FE4006A6758 /* SystemDialogs.mm */,
 				AB7A61F02147C815003C5833 /* Products */,
 				AB661C1C2148230E00291242 /* Frameworks */,
+				18391676ECF0E983F4964357 /* WindowBaseImpl.mm */,
+				183915BFF0E234CD3604A7CD /* WindowBaseImpl.h */,
+				18391BBB7782C296D424071F /* INSWindowHolder.h */,
+				183919BF108EB72A029F7671 /* WindowImpl.mm */,
+				18391CD090AA776E7E841AC9 /* WindowImpl.h */,
+				183913C6BFD6856BD42D19FD /* IWindowStateChanged.h */,
+				18391E45702740FE9DD69695 /* ResizeScope.mm */,
+				1839171D898F9BFC1373631A /* ResizeScope.h */,
+				1839132D0E2454D911F1D1F9 /* AvnView.mm */,
+				18391D1669284AD2EC9E866A /* AvnView.h */,
+				1839166350F32661F3ABD70F /* AutoFitContentView.mm */,
+				18391654EF0E7AB3D3AB4071 /* AutoFitContentView.h */,
+				18391884C7476DA4E53A492D /* AvnPanelWindow.mm */,
+				1839122E037567BDD1D09DEB /* WindowProtocol.h */,
+				1839155B28B20FFB672D29C6 /* AvnWindow.mm */,
+				18391DB45C7D892E61BF388C /* WindowInterfaces.h */,
+				18391BB698579F40F1783F31 /* PopupImpl.mm */,
+				183910513F396141938832B5 /* PopupImpl.h */,
 			);
 			sourceTree = "<group>";
 		};
@@ -143,6 +198,17 @@
 			buildActionMask = 2147483647;
 			files = (
 				37155CE4233C00EB0034DCE9 /* menu.h in Headers */,
+				BC11A5BE2608D58F0017BAD0 /* automation.h in Headers */,
+				183916173528EC2737DBE5E1 /* WindowBaseImpl.h in Headers */,
+				1839171DCC651B0638603AC4 /* INSWindowHolder.h in Headers */,
+				183919D91DB9AAB5D700C2EA /* WindowImpl.h in Headers */,
+				18391CF07316F819E76B617C /* IWindowStateChanged.h in Headers */,
+				18391C28BF1823B5464FDD36 /* ResizeScope.h in Headers */,
+				18391ED5F611FF62C45F196D /* AvnView.h in Headers */,
+				18391E1381E2D5BFD60265A9 /* AutoFitContentView.h in Headers */,
+				18391F1E2411C79405A9943A /* WindowProtocol.h in Headers */,
+				183914E50CF6D2EFC1667F7C /* WindowInterfaces.h in Headers */,
+				18391AC65ADD7DDD33FBE737 /* PopupImpl.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -213,6 +279,7 @@
 				AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */,
 				1A3E5EA823E9E83B00EDE661 /* rendertarget.mm in Sources */,
 				1A3E5EAE23E9FB1300EDE661 /* cgl.mm in Sources */,
+				BC11A5BF2608D58F0017BAD0 /* automation.mm in Sources */,
 				37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */,
 				520624B322973F4100C4DCEF /* menu.mm in Sources */,
 				37A517B32159597E00FBA241 /* Screens.mm in Sources */,
@@ -220,7 +287,14 @@
 				1A465D10246AB61600C5858B /* dnd.mm in Sources */,
 				AB00E4F72147CA920032A60A /* main.mm in Sources */,
 				37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */,
-				AB661C202148286E00291242 /* window.mm in Sources */,
+				1839179A55FC1421BEE83330 /* WindowBaseImpl.mm in Sources */,
+				1839125F057B0A4EB1760058 /* WindowImpl.mm in Sources */,
+				18391068E48EF96E3DB5FDAB /* ResizeScope.mm in Sources */,
+				18391D4EB311BC7EF8B8C0A6 /* AvnView.mm in Sources */,
+				18391AA7E0BBA74D184C5734 /* AutoFitContentView.mm in Sources */,
+				1839151F32D1BB1AB51A7BB6 /* AvnPanelWindow.mm in Sources */,
+				18391AC16726CBC45856233B /* AvnWindow.mm in Sources */,
+				18391D8CD1756DC858DC1A09 /* PopupImpl.mm in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 5 - 1
native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/xcshareddata/xcschemes/Avalonia.Native.OSX.xcscheme

@@ -56,10 +56,14 @@
       </MacroExpansion>
       <CommandLineArguments>
          <CommandLineArgument
-            argument = "bin/Debug/netcoreapp3.1/ControlCatalog.NetCore.dll"
+            argument = "bin/Debug/net6.0/ControlCatalog.NetCore.dll"
             isEnabled = "YES">
          </CommandLineArgument>
       </CommandLineArguments>
+      <LocationScenarioReference
+         identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
+         referenceType = "1">
+      </LocationScenarioReference>
    </LaunchAction>
    <ProfileAction
       buildConfiguration = "Release"

+ 11 - 0
native/Avalonia.Native/src/OSX/AvnPanelWindow.mm

@@ -0,0 +1,11 @@
+//
+// Created by Dan Walmsley on 06/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#pragma once
+
+#define IS_NSPANEL
+
+#include "AvnWindow.mm"
+

+ 1 - 0
native/Avalonia.Native/src/OSX/AvnString.h

@@ -14,4 +14,5 @@ extern IAvnStringArray* CreateAvnStringArray(NSArray<NSString*>* array);
 extern IAvnStringArray* CreateAvnStringArray(NSArray<NSURL*>* array);
 extern IAvnStringArray* CreateAvnStringArray(NSString* string);
 extern IAvnString* CreateByteArray(void* data, int len);
+extern NSString* GetNSStringAndRelease(IAvnString* s);
 #endif /* AvnString_h */

+ 16 - 0
native/Avalonia.Native/src/OSX/AvnString.mm

@@ -153,3 +153,19 @@ IAvnString* CreateByteArray(void* data, int len)
 {
     return new AvnStringImpl(data, len);
 }
+
+NSString* GetNSStringAndRelease(IAvnString* s)
+{
+    NSString* result = nil;
+    
+    if (s != nullptr)
+    {
+        char* p;
+        if (s->Pointer((void**)&p) == S_OK && p != nullptr)
+            result = [NSString stringWithUTF8String:p];
+        
+        s->Release();
+    }
+    
+    return result;
+}

+ 27 - 0
native/Avalonia.Native/src/OSX/AvnView.h

@@ -0,0 +1,27 @@
+//
+// Created by Dan Walmsley on 05/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+#pragma once
+#import <Foundation/Foundation.h>
+
+
+#import <Foundation/Foundation.h>
+#import <AppKit/AppKit.h>
+#include "common.h"
+#include "WindowImpl.h"
+#include "KeyTransform.h"
+
+@class AvnAccessibilityElement;
+
+@interface AvnView : NSView<NSTextInputClient, NSDraggingDestination>
+-(AvnView* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent;
+-(NSEvent* _Nonnull) lastMouseDownEvent;
+-(AvnPoint) translateLocalPoint:(AvnPoint)pt;
+-(void) setSwRenderedFrame: (AvnFramebuffer* _Nonnull) fb dispose: (IUnknown* _Nonnull) dispose;
+-(void) onClosed;
+
+-(AvnPlatformResizeReason) getResizeReason;
+-(void) setResizeReason:(AvnPlatformResizeReason)reason;
++ (AvnPoint)toAvnPoint:(CGPoint)p;
+@end

+ 712 - 0
native/Avalonia.Native/src/OSX/AvnView.mm

@@ -0,0 +1,712 @@
+//
+// Created by Dan Walmsley on 05/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#import <AppKit/AppKit.h>
+#include "AvnView.h"
+#include "automation.h"
+#import "WindowInterfaces.h"
+
+@implementation AvnView
+{
+    ComPtr<WindowBaseImpl> _parent;
+    NSTrackingArea* _area;
+    bool _isLeftPressed, _isMiddlePressed, _isRightPressed, _isXButton1Pressed, _isXButton2Pressed;
+    AvnInputModifiers _modifierState;
+    NSEvent* _lastMouseDownEvent;
+    bool _lastKeyHandled;
+    AvnPixelSize _lastPixelSize;
+    NSObject<IRenderTarget>* _renderTarget;
+    AvnPlatformResizeReason _resizeReason;
+    AvnAccessibilityElement* _accessibilityChild;
+}
+
+- (void)onClosed
+{
+    @synchronized (self)
+    {
+        _parent = nullptr;
+    }
+}
+
+- (NSEvent*) lastMouseDownEvent
+{
+    return _lastMouseDownEvent;
+}
+
+- (void) updateRenderTarget
+{
+    [_renderTarget resize:_lastPixelSize withScale:static_cast<float>([[self window] backingScaleFactor])];
+    [self setNeedsDisplayInRect:[self frame]];
+}
+
+-(AvnView*)  initWithParent: (WindowBaseImpl*) parent
+{
+    self = [super init];
+    _renderTarget = parent->renderTarget;
+    [self setWantsLayer:YES];
+    [self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize];
+
+    _parent = parent;
+    _area = nullptr;
+    _lastPixelSize.Height = 100;
+    _lastPixelSize.Width = 100;
+    [self registerForDraggedTypes: @[@"public.data", GetAvnCustomDataType()]];
+
+    _modifierState = AvnInputModifiersNone;
+    return self;
+}
+
+- (BOOL)isFlipped
+{
+    return YES;
+}
+
+- (BOOL)wantsUpdateLayer
+{
+    return YES;
+}
+
+- (void)setLayer:(CALayer *)layer
+{
+    [_renderTarget setNewLayer: layer];
+    [super setLayer: layer];
+}
+
+- (BOOL)isOpaque
+{
+    return YES;
+}
+
+- (BOOL)acceptsFirstResponder
+{
+    return true;
+}
+
+- (BOOL)acceptsFirstMouse:(NSEvent *)event
+{
+    return true;
+}
+
+- (BOOL)canBecomeKeyView
+{
+    return true;
+}
+
+-(void)setFrameSize:(NSSize)newSize
+{
+    [super setFrameSize:newSize];
+
+    if(_area != nullptr)
+    {
+        [self removeTrackingArea:_area];
+        _area = nullptr;
+    }
+
+    if (_parent == nullptr)
+    {
+        return;
+    }
+
+    NSRect rect = NSZeroRect;
+    rect.size = newSize;
+
+    NSTrackingAreaOptions options = NSTrackingActiveAlways | NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingEnabledDuringMouseDrag;
+    _area = [[NSTrackingArea alloc] initWithRect:rect options:options owner:self userInfo:nullptr];
+    [self addTrackingArea:_area];
+
+    _parent->UpdateCursor();
+
+    auto fsize = [self convertSizeToBacking: [self frame].size];
+
+    if(_lastPixelSize.Width != (int)fsize.width || _lastPixelSize.Height != (int)fsize.height)
+    {
+        _lastPixelSize.Width = (int)fsize.width;
+        _lastPixelSize.Height = (int)fsize.height;
+        [self updateRenderTarget];
+
+        auto reason = [self inLiveResize] ? ResizeUser : _resizeReason;
+        _parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height}, reason);
+    }
+}
+
+- (void)updateLayer
+{
+    AvnInsidePotentialDeadlock deadlock;
+    if (_parent == nullptr)
+    {
+        return;
+    }
+
+    _parent->BaseEvents->RunRenderPriorityJobs();
+
+    if (_parent == nullptr)
+    {
+        return;
+    }
+
+    _parent->BaseEvents->Paint();
+}
+
+- (void)drawRect:(NSRect)dirtyRect
+{
+    return;
+}
+
+-(void) setSwRenderedFrame: (AvnFramebuffer*) fb dispose: (IUnknown*) dispose
+{
+    @autoreleasepool {
+        [_renderTarget setSwFrame:fb];
+        dispose->Release();
+    }
+}
+
+- (AvnPoint) translateLocalPoint:(AvnPoint)pt
+{
+    pt.Y = [self bounds].size.height - pt.Y;
+    return pt;
+}
+
++ (AvnPoint)toAvnPoint:(CGPoint)p
+{
+    AvnPoint result;
+
+    result.X = p.x;
+    result.Y = p.y;
+
+    return result;
+}
+
+- (void) viewDidChangeBackingProperties
+{
+    auto fsize = [self convertSizeToBacking: [self frame].size];
+    _lastPixelSize.Width = (int)fsize.width;
+    _lastPixelSize.Height = (int)fsize.height;
+    [self updateRenderTarget];
+
+    if(_parent != nullptr)
+    {
+        _parent->BaseEvents->ScalingChanged([_parent->Window backingScaleFactor]);
+    }
+
+    [super viewDidChangeBackingProperties];
+}
+
+- (bool) ignoreUserInput:(bool)trigerInputWhenDisabled
+{
+    if(_parent == nullptr)
+    {
+        return TRUE;
+    }
+
+    auto parentWindow = _parent->GetWindowProtocol();
+
+    if(parentWindow == nil || ![parentWindow shouldTryToHandleEvents])
+    {
+        if(trigerInputWhenDisabled)
+        {
+            auto window = dynamic_cast<WindowImpl*>(_parent.getRaw());
+
+            if(window != nullptr)
+            {
+                window->WindowEvents->GotInputWhenDisabled();
+            }
+        }
+
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+- (void)mouseEvent:(NSEvent *)event withType:(AvnRawMouseEventType) type
+{
+    bool triggerInputWhenDisabled = type != Move;
+
+    if([self ignoreUserInput: triggerInputWhenDisabled])
+    {
+        return;
+    }
+
+    auto localPoint = [self convertPoint:[event locationInWindow] toView:self];
+    auto avnPoint = [AvnView toAvnPoint:localPoint];
+    auto point = [self translateLocalPoint:avnPoint];
+    AvnVector delta = { 0, 0};
+
+    if(type == Wheel)
+    {
+        auto speed = 5;
+
+        if([event hasPreciseScrollingDeltas])
+        {
+            speed = 50;
+        }
+
+        delta.X = [event scrollingDeltaX] / speed;
+        delta.Y = [event scrollingDeltaY] / speed;
+
+        if(delta.X == 0 && delta.Y == 0)
+        {
+            return;
+        }
+    }
+    else if (type == Magnify)
+    {
+        delta.X = delta.Y = [event magnification];
+    }
+    else if (type == Rotate)
+    {
+        delta.X = delta.Y = [event rotation];
+    }
+    else if (type == Swipe)
+    {
+        delta.X = [event deltaX];
+        delta.Y = [event deltaY];
+    }
+
+    uint32 timestamp = static_cast<uint32>([event timestamp] * 1000);
+    auto modifiers = [self getModifiers:[event modifierFlags]];
+
+    if(type != Move ||
+            (
+                    [self window] != nil &&
+                            (
+                                    [[self window] firstResponder] == nil
+                                            || ![[[self window] firstResponder] isKindOfClass: [NSView class]]
+                            )
+            )
+            )
+        [self becomeFirstResponder];
+
+    if(_parent != nullptr)
+    {
+        _parent->BaseEvents->RawMouseEvent(type, timestamp, modifiers, point, delta);
+    }
+
+    [super mouseMoved:event];
+}
+
+- (BOOL) resignFirstResponder
+{
+    _parent->BaseEvents->LostFocus();
+    return YES;
+}
+
+- (void)mouseMoved:(NSEvent *)event
+{
+    [self mouseEvent:event withType:Move];
+}
+
+- (void)mouseDown:(NSEvent *)event
+{
+    _isLeftPressed = true;
+    _lastMouseDownEvent = event;
+    [self mouseEvent:event withType:LeftButtonDown];
+}
+
+- (void)otherMouseDown:(NSEvent *)event
+{
+    _lastMouseDownEvent = event;
+
+    switch(event.buttonNumber)
+    {
+        case 2:
+        case 3:
+            _isMiddlePressed = true;
+            [self mouseEvent:event withType:MiddleButtonDown];
+            break;
+        case 4:
+            _isXButton1Pressed = true;
+            [self mouseEvent:event withType:XButton1Down];
+            break;
+        case 5:
+            _isXButton2Pressed = true;
+            [self mouseEvent:event withType:XButton2Down];
+            break;
+
+        default:
+            break;
+    }
+}
+
+- (void)rightMouseDown:(NSEvent *)event
+{
+    _isRightPressed = true;
+    _lastMouseDownEvent = event;
+    [self mouseEvent:event withType:RightButtonDown];
+}
+
+- (void)mouseUp:(NSEvent *)event
+{
+    _isLeftPressed = false;
+    [self mouseEvent:event withType:LeftButtonUp];
+}
+
+- (void)otherMouseUp:(NSEvent *)event
+{
+    switch(event.buttonNumber)
+    {
+        case 2:
+        case 3:
+            _isMiddlePressed = false;
+            [self mouseEvent:event withType:MiddleButtonUp];
+            break;
+        case 4:
+            _isXButton1Pressed = false;
+            [self mouseEvent:event withType:XButton1Up];
+            break;
+        case 5:
+            _isXButton2Pressed = false;
+            [self mouseEvent:event withType:XButton2Up];
+            break;
+
+        default:
+            break;
+    }
+}
+
+- (void)rightMouseUp:(NSEvent *)event
+{
+    _isRightPressed = false;
+    [self mouseEvent:event withType:RightButtonUp];
+}
+
+- (void)mouseDragged:(NSEvent *)event
+{
+    [self mouseEvent:event withType:Move];
+    [super mouseDragged:event];
+}
+
+- (void)otherMouseDragged:(NSEvent *)event
+{
+    [self mouseEvent:event withType:Move];
+    [super otherMouseDragged:event];
+}
+
+- (void)rightMouseDragged:(NSEvent *)event
+{
+    [self mouseEvent:event withType:Move];
+    [super rightMouseDragged:event];
+}
+
+- (void)scrollWheel:(NSEvent *)event
+{
+    [self mouseEvent:event withType:Wheel];
+    [super scrollWheel:event];
+}
+
+- (void)magnifyWithEvent:(NSEvent *)event
+{
+    [self mouseEvent:event withType:Magnify];
+    [super magnifyWithEvent:event];
+}
+
+- (void)rotateWithEvent:(NSEvent *)event
+{
+    [self mouseEvent:event withType:Rotate];
+    [super rotateWithEvent:event];
+}
+
+- (void)swipeWithEvent:(NSEvent *)event
+{
+    [self mouseEvent:event withType:Swipe];
+    [super swipeWithEvent:event];
+}
+
+- (void)mouseEntered:(NSEvent *)event
+{
+    [super mouseEntered:event];
+}
+
+- (void)mouseExited:(NSEvent *)event
+{
+    [self mouseEvent:event withType:LeaveWindow];
+    [super mouseExited:event];
+}
+
+- (void) keyboardEvent: (NSEvent *) event withType: (AvnRawKeyEventType)type
+{
+    if([self ignoreUserInput: false])
+    {
+        return;
+    }
+
+    auto key = s_KeyMap[[event keyCode]];
+
+    uint32_t timestamp = static_cast<uint32_t>([event timestamp] * 1000);
+    auto modifiers = [self getModifiers:[event modifierFlags]];
+
+    if(_parent != nullptr)
+    {
+        _lastKeyHandled = _parent->BaseEvents->RawKeyEvent(type, timestamp, modifiers, key);
+    }
+}
+
+- (BOOL)performKeyEquivalent:(NSEvent *)event
+{
+    bool result = _lastKeyHandled;
+
+    _lastKeyHandled = false;
+
+    return result;
+}
+
+- (void)flagsChanged:(NSEvent *)event
+{
+    auto newModifierState = [self getModifiers:[event modifierFlags]];
+
+    bool isAltCurrentlyPressed = (_modifierState & Alt) == Alt;
+    bool isControlCurrentlyPressed = (_modifierState & Control) == Control;
+    bool isShiftCurrentlyPressed = (_modifierState & Shift) == Shift;
+    bool isCommandCurrentlyPressed = (_modifierState & Windows) == Windows;
+
+    bool isAltPressed = (newModifierState & Alt) == Alt;
+    bool isControlPressed = (newModifierState & Control) == Control;
+    bool isShiftPressed = (newModifierState & Shift) == Shift;
+    bool isCommandPressed = (newModifierState & Windows) == Windows;
+
+
+    if (isAltPressed && !isAltCurrentlyPressed)
+    {
+        [self keyboardEvent:event withType:KeyDown];
+    }
+    else if (isAltCurrentlyPressed && !isAltPressed)
+    {
+        [self keyboardEvent:event withType:KeyUp];
+    }
+
+    if (isControlPressed && !isControlCurrentlyPressed)
+    {
+        [self keyboardEvent:event withType:KeyDown];
+    }
+    else if (isControlCurrentlyPressed && !isControlPressed)
+    {
+        [self keyboardEvent:event withType:KeyUp];
+    }
+
+    if (isShiftPressed && !isShiftCurrentlyPressed)
+    {
+        [self keyboardEvent:event withType:KeyDown];
+    }
+    else if(isShiftCurrentlyPressed && !isShiftPressed)
+    {
+        [self keyboardEvent:event withType:KeyUp];
+    }
+
+    if(isCommandPressed && !isCommandCurrentlyPressed)
+    {
+        [self keyboardEvent:event withType:KeyDown];
+    }
+    else if(isCommandCurrentlyPressed && ! isCommandPressed)
+    {
+        [self keyboardEvent:event withType:KeyUp];
+    }
+
+    _modifierState = newModifierState;
+
+    [[self inputContext] handleEvent:event];
+    [super flagsChanged:event];
+}
+
+- (void)keyDown:(NSEvent *)event
+{
+    [self keyboardEvent:event withType:KeyDown];
+    [[self inputContext] handleEvent:event];
+    [super keyDown:event];
+}
+
+- (void)keyUp:(NSEvent *)event
+{
+    [self keyboardEvent:event withType:KeyUp];
+    [super keyUp:event];
+}
+
+- (AvnInputModifiers)getModifiers:(NSEventModifierFlags)mod
+{
+    unsigned int rv = 0;
+
+    if (mod & NSEventModifierFlagControl)
+        rv |= Control;
+    if (mod & NSEventModifierFlagShift)
+        rv |= Shift;
+    if (mod & NSEventModifierFlagOption)
+        rv |= Alt;
+    if (mod & NSEventModifierFlagCommand)
+        rv |= Windows;
+
+    if (_isLeftPressed)
+        rv |= LeftMouseButton;
+    if (_isMiddlePressed)
+        rv |= MiddleMouseButton;
+    if (_isRightPressed)
+        rv |= RightMouseButton;
+    if (_isXButton1Pressed)
+        rv |= XButton1MouseButton;
+    if (_isXButton2Pressed)
+        rv |= XButton2MouseButton;
+
+    return (AvnInputModifiers)rv;
+}
+
+- (BOOL)hasMarkedText
+{
+    return _lastKeyHandled;
+}
+
+- (NSRange)markedRange
+{
+    return NSMakeRange(NSNotFound, 0);
+}
+
+- (NSRange)selectedRange
+{
+    return NSMakeRange(NSNotFound, 0);
+}
+
+- (void)setMarkedText:(id)string selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
+{
+
+}
+
+- (void)unmarkText
+{
+
+}
+
+- (NSArray<NSString *> *)validAttributesForMarkedText
+{
+    return [NSArray new];
+}
+
+- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)range actualRange:(NSRangePointer)actualRange
+{
+    return [NSAttributedString new];
+}
+
+- (void)insertText:(id)string replacementRange:(NSRange)replacementRange
+{
+    if(!_lastKeyHandled)
+    {
+        if(_parent != nullptr)
+        {
+            _lastKeyHandled = _parent->BaseEvents->RawTextInputEvent(0, [string UTF8String]);
+        }
+    }
+}
+
+- (NSUInteger)characterIndexForPoint:(NSPoint)point
+{
+    return 0;
+}
+
+- (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(NSRangePointer)actualRange
+{
+    CGRect result = { 0 };
+
+    return result;
+}
+
+- (NSDragOperation)triggerAvnDragEvent: (AvnDragEventType) type info: (id <NSDraggingInfo>)info
+{
+    auto localPoint = [self convertPoint:[info draggingLocation] toView:self];
+    auto avnPoint = [AvnView toAvnPoint:localPoint];
+    auto point = [self translateLocalPoint:avnPoint];
+    auto modifiers = [self getModifiers:[[NSApp currentEvent] modifierFlags]];
+    NSDragOperation nsop = [info draggingSourceOperationMask];
+
+    auto effects = ConvertDragDropEffects(nsop);
+    int reffects = (int)_parent->BaseEvents
+            ->DragEvent(type, point, modifiers, effects,
+                    CreateClipboard([info draggingPasteboard], nil),
+                    GetAvnDataObjectHandleFromDraggingInfo(info));
+
+    NSDragOperation ret = static_cast<NSDragOperation>(0);
+
+    // Ensure that the managed part didn't add any new effects
+    reffects = (int)effects & reffects;
+
+    // OSX requires exactly one operation
+    if((reffects & (int)AvnDragDropEffects::Copy) != 0)
+        ret = NSDragOperationCopy;
+    else if((reffects & (int)AvnDragDropEffects::Move) != 0)
+        ret = NSDragOperationMove;
+    else if((reffects & (int)AvnDragDropEffects::Link) != 0)
+        ret = NSDragOperationLink;
+    if(ret == 0)
+        ret = NSDragOperationNone;
+    return ret;
+}
+
+- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
+{
+    return [self triggerAvnDragEvent: AvnDragEventType::Enter info:sender];
+}
+
+- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
+{
+    return [self triggerAvnDragEvent: AvnDragEventType::Over info:sender];
+}
+
+- (void)draggingExited:(id <NSDraggingInfo>)sender
+{
+    [self triggerAvnDragEvent: AvnDragEventType::Leave info:sender];
+}
+
+- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
+{
+    return [self triggerAvnDragEvent: AvnDragEventType::Over info:sender] != NSDragOperationNone;
+}
+
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
+{
+    return [self triggerAvnDragEvent: AvnDragEventType::Drop info:sender] != NSDragOperationNone;
+}
+
+- (void)concludeDragOperation:(nullable id <NSDraggingInfo>)sender
+{
+
+}
+
+- (AvnPlatformResizeReason)getResizeReason
+{
+    return _resizeReason;
+}
+
+- (void)setResizeReason:(AvnPlatformResizeReason)reason
+{
+    _resizeReason = reason;
+}
+
+- (AvnAccessibilityElement *) accessibilityChild
+{
+    if (_accessibilityChild == nil)
+    {
+        auto peer = _parent->BaseEvents->GetAutomationPeer();
+
+        if (peer == nil)
+            return nil;
+
+        _accessibilityChild = [AvnAccessibilityElement acquire:peer];
+    }
+
+    return _accessibilityChild;
+}
+
+- (NSArray *)accessibilityChildren
+{
+    auto child = [self accessibilityChild];
+    return NSAccessibilityUnignoredChildrenForOnlyChild(child);
+}
+
+- (id)accessibilityHitTest:(NSPoint)point
+{
+    return [[self accessibilityChild] accessibilityHitTest:point];
+}
+
+- (id)accessibilityFocusedUIElement
+{
+    return [[self accessibilityChild] accessibilityFocusedUIElement];
+}
+
+@end

+ 466 - 0
native/Avalonia.Native/src/OSX/AvnWindow.mm

@@ -0,0 +1,466 @@
+//
+// Created by Dan Walmsley on 06/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+
+#import <AppKit/AppKit.h>
+#import "WindowProtocol.h"
+#import "WindowBaseImpl.h"
+
+#ifdef IS_NSPANEL
+#define BASE_CLASS NSPanel
+#define CLASS_NAME AvnPanel
+#else
+#define BASE_CLASS NSWindow
+#define CLASS_NAME AvnWindow
+#endif
+
+#import <AppKit/AppKit.h>
+#include "common.h"
+#include "menu.h"
+#include "automation.h"
+#include "WindowBaseImpl.h"
+#include "WindowImpl.h"
+#include "AvnView.h"
+#include "WindowInterfaces.h"
+#include "PopupImpl.h"
+
+@implementation CLASS_NAME
+{
+    ComPtr<WindowBaseImpl> _parent;
+    bool _closed;
+    bool _isEnabled;
+    bool _canBecomeKeyWindow;
+    bool _isExtended;
+    AvnMenu* _menu;
+}
+
+-(void) setIsExtended:(bool)value;
+{
+    _isExtended = value;
+}
+
+-(bool) isDialog
+{
+    return _parent->IsDialog();
+}
+
+-(double) getExtendedTitleBarHeight
+{
+    if(_isExtended)
+    {
+        for (id subview in self.contentView.superview.subviews)
+        {
+            if ([subview isKindOfClass:NSClassFromString(@"NSTitlebarContainerView")])
+            {
+                NSView *titlebarView = [subview subviews][0];
+
+                return (double)titlebarView.frame.size.height;
+            }
+        }
+
+        return -1;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+- (void)performClose:(id)sender
+{
+    if([[self delegate] respondsToSelector:@selector(windowShouldClose:)])
+    {
+        if(![[self delegate] windowShouldClose:self]) return;
+    }
+    else if([self respondsToSelector:@selector(windowShouldClose:)])
+    {
+        if(![self windowShouldClose:self]) return;
+    }
+
+    [self close];
+}
+
+- (void)pollModalSession:(nonnull NSModalSession)session
+{
+    auto response = [NSApp runModalSession:session];
+
+    if(response == NSModalResponseContinue)
+    {
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [self pollModalSession:session];
+        });
+    }
+    else if (!_closed)
+    {
+        [self orderOut:self];
+        [NSApp endModalSession:session];
+    }
+}
+
+-(void) showWindowMenuWithAppMenu
+{
+    if(_menu != nullptr)
+    {
+        auto appMenuItem = ::GetAppMenuItem();
+
+        if(appMenuItem != nullptr)
+        {
+            auto appMenu = [appMenuItem menu];
+
+            [appMenu removeItem:appMenuItem];
+
+            [_menu insertItem:appMenuItem atIndex:0];
+
+            [_menu setHasGlobalMenuItem:true];
+        }
+
+        [NSApp setMenu:_menu];
+    }
+    else
+    {
+        [self showAppMenuOnly];
+    }
+}
+
+-(void) showAppMenuOnly
+{
+    auto appMenuItem = ::GetAppMenuItem();
+
+    if(appMenuItem != nullptr)
+    {
+        auto appMenu = ::GetAppMenu();
+
+        auto nativeAppMenu = dynamic_cast<AvnAppMenu*>(appMenu);
+
+        [[appMenuItem menu] removeItem:appMenuItem];
+
+        if(_menu != nullptr)
+        {
+            [_menu setHasGlobalMenuItem:false];
+        }
+
+        [nativeAppMenu->GetNative() addItem:appMenuItem];
+
+        [NSApp setMenu:nativeAppMenu->GetNative()];
+    }
+}
+
+-(void) applyMenu:(AvnMenu *)menu
+{
+    if(menu == nullptr)
+    {
+        menu = [AvnMenu new];
+    }
+
+    _menu = menu;
+}
+
+-(CLASS_NAME*)  initWithParent: (WindowBaseImpl*) parent contentRect: (NSRect)contentRect styleMask: (NSWindowStyleMask)styleMask;
+{
+    // https://jameshfisher.com/2020/07/10/why-is-the-contentrect-of-my-nswindow-ignored/
+    // create nswindow with specific contentRect, otherwise we wont be able to resize the window
+    // until several ms after the window is physically on the screen.
+    self = [super initWithContentRect:contentRect styleMask: styleMask backing:NSBackingStoreBuffered defer:false];
+
+    [self setReleasedWhenClosed:false];
+    _parent = parent;
+    [self setDelegate:self];
+    _closed = false;
+    _isEnabled = true;
+
+    [self backingScaleFactor];
+    [self setOpaque:NO];
+    [self setBackgroundColor: [NSColor clearColor]];
+
+    _isExtended = false;
+
+#ifdef IS_NSPANEL
+    [self setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces|NSWindowCollectionBehaviorFullScreenAuxiliary];
+#endif
+
+    return self;
+}
+
+- (BOOL)windowShouldClose:(NSWindow *)sender
+{
+    auto window = dynamic_cast<WindowImpl*>(_parent.getRaw());
+
+    if(window != nullptr)
+    {
+        return !window->WindowEvents->Closing();
+    }
+
+    return true;
+}
+
+- (void)windowDidChangeBackingProperties:(NSNotification *)notification
+{
+    [self backingScaleFactor];
+}
+
+
+
+- (void)windowWillClose:(NSNotification *)notification
+{
+    _closed = true;
+    if(_parent)
+    {
+        ComPtr<WindowBaseImpl> parent = _parent;
+        _parent = NULL;
+        [self restoreParentWindow];
+        parent->BaseEvents->Closed();
+        [parent->View onClosed];
+    }
+}
+
+-(BOOL)canBecomeKeyWindow
+{
+    if(_canBecomeKeyWindow)
+    {
+        // If the window has a child window being shown as a dialog then don't allow it to become the key window.
+        for(NSWindow* uch in [self childWindows])
+        {
+            if (![uch conformsToProtocol:@protocol(AvnWindowProtocol)])
+            {
+                continue;
+            }
+
+            id <AvnWindowProtocol> ch = (id <AvnWindowProtocol>) uch;
+
+            if(ch.isDialog)
+                return false;
+        }
+
+        return true;
+    }
+    
+    return false;
+}
+
+#ifndef IS_NSPANEL
+-(BOOL)canBecomeMainWindow
+{
+    return true;
+}
+#endif
+
+-(void)setCanBecomeKeyWindow:(bool)value
+{
+    _canBecomeKeyWindow = value;
+}
+
+-(bool)shouldTryToHandleEvents
+{
+    return _isEnabled;
+}
+
+-(void) setEnabled:(bool)enable
+{
+    _isEnabled = enable;
+}
+
+-(void)becomeKeyWindow
+{
+    [self showWindowMenuWithAppMenu];
+
+    if(_parent != nullptr)
+    {
+        _parent->BaseEvents->Activated();
+    }
+
+    [super becomeKeyWindow];
+}
+
+-(void) restoreParentWindow;
+{
+    auto parent = [self parentWindow];
+
+    if(parent != nil)
+    {
+        [parent removeChildWindow:self];
+    }
+}
+
+- (void)windowDidMiniaturize:(NSNotification *)notification
+{
+    auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
+
+    if(parent != nullptr)
+    {
+        parent->WindowStateChanged();
+    }
+}
+
+- (void)windowDidDeminiaturize:(NSNotification *)notification
+{
+    auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
+
+    if(parent != nullptr)
+    {
+        parent->WindowStateChanged();
+    }
+}
+
+- (void)windowDidResize:(NSNotification *)notification
+{
+    auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
+
+    if(parent != nullptr)
+    {
+        parent->WindowStateChanged();
+    }
+}
+
+- (void)windowWillExitFullScreen:(NSNotification *)notification
+{
+    auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
+
+    if(parent != nullptr)
+    {
+        parent->StartStateTransition();
+    }
+}
+
+- (void)windowDidExitFullScreen:(NSNotification *)notification
+{
+    auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
+
+    if(parent != nullptr)
+    {
+        parent->EndStateTransition();
+
+        if(parent->Decorations() != SystemDecorationsFull && parent->WindowState() == Maximized)
+        {
+            NSRect screenRect = [[self screen] visibleFrame];
+            [self setFrame:screenRect display:YES];
+        }
+
+        if(parent->WindowState() == Minimized)
+        {
+            [self miniaturize:nullptr];
+        }
+
+        parent->WindowStateChanged();
+    }
+}
+
+- (void)windowWillEnterFullScreen:(NSNotification *)notification
+{
+    auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
+
+    if(parent != nullptr)
+    {
+        parent->StartStateTransition();
+    }
+}
+
+- (void)windowDidEnterFullScreen:(NSNotification *)notification
+{
+    auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
+
+    if(parent != nullptr)
+    {
+        parent->EndStateTransition();
+        parent->WindowStateChanged();
+    }
+}
+
+- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame
+{
+    return true;
+}
+
+-(void)resignKeyWindow
+{
+    if(_parent)
+        _parent->BaseEvents->Deactivated();
+
+    [self showAppMenuOnly];
+
+    [super resignKeyWindow];
+}
+
+- (void)windowDidMove:(NSNotification *)notification
+{
+    AvnPoint position;
+
+    if(_parent != nullptr)
+    {
+        auto cparent = dynamic_cast<WindowImpl*>(_parent.getRaw());
+
+        if(cparent != nullptr)
+        {
+            if(!cparent->IsShown())
+            {
+                return;
+            }
+
+            if(cparent->WindowState() == Maximized)
+            {
+                cparent->SetWindowState(Normal);
+            }
+        }
+
+        _parent->GetPosition(&position);
+        _parent->BaseEvents->PositionChanged(position);
+    }
+}
+
+- (AvnPoint) translateLocalPoint:(AvnPoint)pt
+{
+    pt.Y = [self frame].size.height - pt.Y;
+    return pt;
+}
+
+- (void)sendEvent:(NSEvent *)event
+{
+    [super sendEvent:event];
+
+    /// This is to detect non-client clicks. This can only be done on Windows... not popups, hence the dynamic_cast.
+    if(_parent != nullptr && dynamic_cast<WindowImpl*>(_parent.getRaw()) != nullptr)
+    {
+        switch(event.type)
+        {
+            case NSEventTypeLeftMouseDown:
+            {
+                AvnView* view = _parent->View;
+                NSPoint windowPoint = [event locationInWindow];
+                NSPoint viewPoint = [view convertPoint:windowPoint fromView:nil];
+
+                if (!NSPointInRect(viewPoint, view.bounds))
+                {
+                    auto avnPoint = [AvnView toAvnPoint:windowPoint];
+                    auto point = [self translateLocalPoint:avnPoint];
+                    AvnVector delta = { 0, 0 };
+
+                    _parent->BaseEvents->RawMouseEvent(NonClientLeftButtonDown, static_cast<uint32>([event timestamp] * 1000), AvnInputModifiersNone, point, delta);
+                }
+            }
+                break;
+
+            case NSEventTypeMouseEntered:
+            {
+                _parent->UpdateCursor();
+            }
+                break;
+
+            case NSEventTypeMouseExited:
+            {
+                [[NSCursor arrowCursor] set];
+            }
+                break;
+
+            default:
+                break;
+        }
+    }
+}
+
+- (void)disconnectParent {
+    _parent = nullptr;
+}
+
+@end
+

+ 17 - 0
native/Avalonia.Native/src/OSX/INSWindowHolder.h

@@ -0,0 +1,17 @@
+//
+// Created by Dan Walmsley on 04/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#ifndef AVALONIA_NATIVE_OSX_INSWINDOWHOLDER_H
+#define AVALONIA_NATIVE_OSX_INSWINDOWHOLDER_H
+
+@class AvnView;
+
+struct INSWindowHolder
+{
+    virtual NSWindow* _Nonnull GetNSWindow () = 0;
+    virtual NSView* _Nonnull GetNSView () = 0;
+};
+
+#endif //AVALONIA_NATIVE_OSX_INSWINDOWHOLDER_H

+ 18 - 0
native/Avalonia.Native/src/OSX/IWindowStateChanged.h

@@ -0,0 +1,18 @@
+//
+// Created by Dan Walmsley on 04/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#ifndef AVALONIA_NATIVE_OSX_IWINDOWSTATECHANGED_H
+#define AVALONIA_NATIVE_OSX_IWINDOWSTATECHANGED_H
+
+struct IWindowStateChanged
+{
+    virtual void WindowStateChanged () = 0;
+    virtual void StartStateTransition () = 0;
+    virtual void EndStateTransition () = 0;
+    virtual SystemDecorations Decorations () = 0;
+    virtual AvnWindowState WindowState () = 0;
+};
+
+#endif //AVALONIA_NATIVE_OSX_IWINDOWSTATECHANGED_H

+ 9 - 0
native/Avalonia.Native/src/OSX/PopupImpl.h

@@ -0,0 +1,9 @@
+//
+// Created by Dan Walmsley on 06/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#ifndef AVALONIA_NATIVE_OSX_POPUPIMPL_H
+#define AVALONIA_NATIVE_OSX_POPUPIMPL_H
+
+#endif //AVALONIA_NATIVE_OSX_POPUPIMPL_H

+ 61 - 0
native/Avalonia.Native/src/OSX/PopupImpl.mm

@@ -0,0 +1,61 @@
+//
+// Created by Dan Walmsley on 06/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#include "WindowInterfaces.h"
+#include "AvnView.h"
+#include "WindowImpl.h"
+#include "automation.h"
+#include "menu.h"
+#include "common.h"
+#import "WindowBaseImpl.h"
+#import "WindowProtocol.h"
+#import <AppKit/AppKit.h>
+#include "PopupImpl.h"
+
+class PopupImpl : public virtual WindowBaseImpl, public IAvnPopup
+{
+private:
+    BEGIN_INTERFACE_MAP()
+    INHERIT_INTERFACE_MAP(WindowBaseImpl)
+    INTERFACE_MAP_ENTRY(IAvnPopup, IID_IAvnPopup)
+    END_INTERFACE_MAP()
+    virtual ~PopupImpl(){}
+    ComPtr<IAvnWindowEvents> WindowEvents;
+    PopupImpl(IAvnWindowEvents* events, IAvnGlContext* gl) : WindowBaseImpl(events, gl)
+    {
+        WindowEvents = events;
+    }
+protected:
+    virtual NSWindowStyleMask GetStyle() override
+    {
+        return NSWindowStyleMaskBorderless;
+    }
+    
+    virtual void OnInitialiseNSWindow () override
+    {
+        [Window setLevel:NSPopUpMenuWindowLevel];
+    }
+
+public:
+    virtual bool ShouldTakeFocusOnShow() override
+    {
+        return false;
+    }
+
+    virtual HRESULT Show(bool activate, bool isDialog) override
+    {
+        return WindowBaseImpl::Show(activate, true);
+    }
+};
+
+
+extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events, IAvnGlContext* gl)
+{
+    @autoreleasepool
+    {
+        IAvnPopup* ptr = dynamic_cast<IAvnPopup*>(new PopupImpl(events, gl));
+        return ptr;
+    }
+}

+ 24 - 0
native/Avalonia.Native/src/OSX/ResizeScope.h

@@ -0,0 +1,24 @@
+//
+// Created by Dan Walmsley on 04/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#ifndef AVALONIA_NATIVE_OSX_RESIZESCOPE_H
+#define AVALONIA_NATIVE_OSX_RESIZESCOPE_H
+
+#include "avalonia-native.h"
+
+@class AvnView;
+
+class ResizeScope
+{
+public:
+    ResizeScope(AvnView* _Nonnull view, AvnPlatformResizeReason reason);
+
+    ~ResizeScope();
+private:
+    AvnView* _Nonnull _view;
+    AvnPlatformResizeReason _restore;
+};
+
+#endif //AVALONIA_NATIVE_OSX_RESIZESCOPE_H

+ 18 - 0
native/Avalonia.Native/src/OSX/ResizeScope.mm

@@ -0,0 +1,18 @@
+//
+// Created by Dan Walmsley on 04/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#import <AppKit/AppKit.h>
+#include "ResizeScope.h"
+#include "AvnView.h"
+
+ResizeScope::ResizeScope(AvnView *view, AvnPlatformResizeReason reason) {
+    _view = view;
+    _restore = [view getResizeReason];
+    [view setResizeReason:reason];
+}
+
+ResizeScope::~ResizeScope() {
+    [_view setResizeReason:_restore];
+}

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

@@ -1,5 +1,5 @@
 #include "common.h"
-#include "window.h"
+#include "INSWindowHolder.h"
 
 class SystemDialogs : public ComSingleObject<IAvnSystemDialogs, &IID_IAvnSystemDialogs>
 {

+ 136 - 0
native/Avalonia.Native/src/OSX/WindowBaseImpl.h

@@ -0,0 +1,136 @@
+//
+// Created by Dan Walmsley on 04/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#ifndef AVALONIA_NATIVE_OSX_WINDOWBASEIMPL_H
+#define AVALONIA_NATIVE_OSX_WINDOWBASEIMPL_H
+
+#include "rendertarget.h"
+#include "INSWindowHolder.h"
+
+@class AutoFitContentView;
+@class AvnMenu;
+@protocol AvnWindowProtocol;
+
+class WindowBaseImpl : public virtual ComObject,
+                       public virtual IAvnWindowBase,
+                       public INSWindowHolder {
+
+public:
+    FORWARD_IUNKNOWN()
+
+BEGIN_INTERFACE_MAP()
+        INTERFACE_MAP_ENTRY(IAvnWindowBase, IID_IAvnWindowBase)
+    END_INTERFACE_MAP()
+
+    virtual ~WindowBaseImpl();
+
+    WindowBaseImpl(IAvnWindowBaseEvents *events, IAvnGlContext *gl);
+
+    virtual HRESULT ObtainNSWindowHandle(void **ret) override;
+
+    virtual HRESULT ObtainNSWindowHandleRetained(void **ret) override;
+
+    virtual HRESULT ObtainNSViewHandle(void **ret) override;
+
+    virtual HRESULT ObtainNSViewHandleRetained(void **ret) override;
+
+    virtual NSWindow *GetNSWindow() override;
+
+    virtual NSView *GetNSView() override;
+
+    virtual HRESULT Show(bool activate, bool isDialog) override;
+
+    virtual bool IsShown ();
+
+    virtual bool ShouldTakeFocusOnShow();
+
+    virtual HRESULT Hide() override;
+
+    virtual HRESULT Activate() override;
+
+    virtual HRESULT SetTopMost(bool value) override;
+
+    virtual HRESULT Close() override;
+
+    virtual HRESULT GetClientSize(AvnSize *ret) override;
+
+    virtual HRESULT GetFrameSize(AvnSize *ret) override;
+
+    virtual HRESULT GetScaling(double *ret) override;
+
+    virtual HRESULT SetMinMaxSize(AvnSize minSize, AvnSize maxSize) override;
+
+    virtual HRESULT Resize(double x, double y, AvnPlatformResizeReason reason) override;
+
+    virtual HRESULT Invalidate(__attribute__((unused)) AvnRect rect) override;
+
+    virtual HRESULT SetMainMenu(IAvnMenu *menu) override;
+
+    virtual HRESULT BeginMoveDrag() override;
+
+    virtual HRESULT BeginResizeDrag(__attribute__((unused)) AvnWindowEdge edge) override;
+
+    virtual HRESULT GetPosition(AvnPoint *ret) override;
+
+    virtual HRESULT SetPosition(AvnPoint point) override;
+
+    virtual HRESULT PointToClient(AvnPoint point, AvnPoint *ret) override;
+
+    virtual HRESULT PointToScreen(AvnPoint point, AvnPoint *ret) override;
+
+    virtual HRESULT ThreadSafeSetSwRenderedFrame(AvnFramebuffer *fb, IUnknown *dispose) override;
+
+    virtual HRESULT SetCursor(IAvnCursor *cursor) override;
+
+    virtual void UpdateCursor();
+
+    virtual HRESULT CreateGlRenderTarget(IAvnGlSurfaceRenderTarget **ppv) override;
+
+    virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost **retOut) override;
+
+    virtual HRESULT SetBlurEnabled(bool enable) override;
+
+    virtual HRESULT BeginDragAndDropOperation(AvnDragDropEffects effects, AvnPoint point,
+            IAvnClipboard *clipboard, IAvnDndResultCallback *cb,
+            void *sourceHandle) override;
+
+    virtual bool IsDialog();
+
+    id<AvnWindowProtocol> GetWindowProtocol ();
+
+protected:
+    virtual NSWindowStyleMask GetStyle();
+
+    void UpdateStyle();
+                           
+    virtual void OnInitialiseNSWindow ();
+
+private:
+    void CreateNSWindow (bool isDialog);
+    void CleanNSWindow ();
+    void InitialiseNSWindow ();
+
+    NSCursor *cursor;
+    ComPtr<IAvnGlContext> _glContext;
+    bool hasPosition;
+    NSSize lastSize;
+    NSSize lastMinSize;
+    NSSize lastMaxSize;
+    AvnMenu* lastMenu;
+    bool _inResize;
+
+protected:
+    AvnPoint lastPositionSet;
+    AutoFitContentView *StandardContainer;
+    bool _shown;
+
+public:
+    NSObject <IRenderTarget> *renderTarget;
+    NSWindow * Window;
+    ComPtr<IAvnWindowBaseEvents> BaseEvents;
+    AvnView *View;
+};
+
+#endif //AVALONIA_NATIVE_OSX_WINDOWBASEIMPL_H

+ 618 - 0
native/Avalonia.Native/src/OSX/WindowBaseImpl.mm

@@ -0,0 +1,618 @@
+//
+// Created by Dan Walmsley on 04/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#import <AppKit/AppKit.h>
+#include "common.h"
+#include "AvnView.h"
+#include "menu.h"
+#include "automation.h"
+#include "cursor.h"
+#include "ResizeScope.h"
+#include "AutoFitContentView.h"
+#import "WindowProtocol.h"
+#import "WindowInterfaces.h"
+#include "WindowBaseImpl.h"
+
+
+WindowBaseImpl::~WindowBaseImpl() {
+    View = nullptr;
+    Window = nullptr;
+}
+
+WindowBaseImpl::WindowBaseImpl(IAvnWindowBaseEvents *events, IAvnGlContext *gl) {
+    _shown = false;
+    _inResize = false;
+    BaseEvents = events;
+    _glContext = gl;
+    renderTarget = [[IOSurfaceRenderTarget alloc] initWithOpenGlContext:gl];
+    View = [[AvnView alloc] initWithParent:this];
+    StandardContainer = [[AutoFitContentView new] initWithContent:View];
+
+    lastPositionSet = { 0, 0 };
+    hasPosition = false;
+    lastSize = NSSize { 100, 100 };
+    lastMaxSize = NSSize { CGFLOAT_MAX, CGFLOAT_MAX};
+    lastMinSize = NSSize { 0, 0 };
+
+    Window = nullptr;
+    lastMenu = nullptr;
+}
+
+HRESULT WindowBaseImpl::ObtainNSViewHandle(void **ret) {
+    START_COM_CALL;
+
+    if (ret == nullptr) {
+        return E_POINTER;
+    }
+
+    *ret = (__bridge void *) View;
+
+    return S_OK;
+}
+
+HRESULT WindowBaseImpl::ObtainNSViewHandleRetained(void **ret) {
+    START_COM_CALL;
+
+    if (ret == nullptr) {
+        return E_POINTER;
+    }
+
+    *ret = (__bridge_retained void *) View;
+
+    return S_OK;
+}
+
+NSWindow *WindowBaseImpl::GetNSWindow() {
+    return Window;
+}
+
+NSView *WindowBaseImpl::GetNSView() {
+    return View;
+}
+
+HRESULT WindowBaseImpl::ObtainNSWindowHandleRetained(void **ret) {
+    START_COM_CALL;
+
+    if (ret == nullptr) {
+        return E_POINTER;
+    }
+
+    *ret = (__bridge_retained void *) Window;
+
+    return S_OK;
+}
+
+HRESULT WindowBaseImpl::Show(bool activate, bool isDialog) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        CreateNSWindow(isDialog);
+        InitialiseNSWindow();
+
+        if(hasPosition)
+        {
+            SetPosition(lastPositionSet);
+        } else
+        {
+            [Window center];
+        }
+
+        UpdateStyle();
+
+        if (ShouldTakeFocusOnShow() && activate) {
+            [Window orderFront:Window];
+            [Window makeKeyAndOrderFront:Window];
+            [Window makeFirstResponder:View];
+            [NSApp activateIgnoringOtherApps:YES];
+        } else {
+            [Window orderFront:Window];
+        }
+
+        _shown = true;
+
+        return S_OK;
+    }
+}
+
+bool WindowBaseImpl::IsShown ()
+{
+    return _shown;
+}
+
+bool WindowBaseImpl::ShouldTakeFocusOnShow() {
+    return true;
+}
+
+HRESULT WindowBaseImpl::ObtainNSWindowHandle(void **ret) {
+    START_COM_CALL;
+
+    if (ret == nullptr) {
+        return E_POINTER;
+    }
+
+    *ret = (__bridge void *) Window;
+
+    return S_OK;
+}
+
+HRESULT WindowBaseImpl::Hide() {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        if (Window != nullptr) {
+            [Window orderOut:Window];
+
+            [GetWindowProtocol() restoreParentWindow];
+        }
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowBaseImpl::Activate() {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        if (Window != nullptr) {
+            [Window makeKeyAndOrderFront:nil];
+            [NSApp activateIgnoringOtherApps:YES];
+        }
+    }
+
+    return S_OK;
+}
+
+HRESULT WindowBaseImpl::SetTopMost(bool value) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        [Window setLevel:value ? NSFloatingWindowLevel : NSNormalWindowLevel];
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowBaseImpl::Close() {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        if (Window != nullptr) {
+            auto window = Window;
+            Window = nullptr;
+
+            try {
+                // Seems to throw sometimes on application exit.
+                [window close];
+            }
+            catch (NSException *) {}
+        }
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowBaseImpl::GetClientSize(AvnSize *ret) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        if (ret == nullptr)
+            return E_POINTER;
+
+        ret->Width = lastSize.width;
+        ret->Height = lastSize.height;
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowBaseImpl::GetFrameSize(AvnSize *ret) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        if (ret == nullptr)
+            return E_POINTER;
+
+        if(Window != nullptr){
+            auto frame = [Window frame];
+            ret->Width = frame.size.width;
+            ret->Height = frame.size.height;
+        }
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowBaseImpl::GetScaling(double *ret) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        if (ret == nullptr)
+            return E_POINTER;
+
+        if (Window == nullptr) {
+            *ret = 1;
+            return S_OK;
+        }
+
+        *ret = [Window backingScaleFactor];
+        return S_OK;
+    }
+}
+
+HRESULT WindowBaseImpl::SetMinMaxSize(AvnSize minSize, AvnSize maxSize) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        lastMinSize = ToNSSize(minSize);
+        lastMaxSize = ToNSSize(maxSize);
+
+        if(Window != nullptr) {
+            [Window setContentMinSize:lastMinSize];
+            [Window setContentMaxSize:lastMaxSize];
+        }
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowBaseImpl::Resize(double x, double y, AvnPlatformResizeReason reason) {
+    if (_inResize) {
+        return S_OK;
+    }
+
+    _inResize = true;
+
+    START_COM_CALL;
+    auto resizeBlock = ResizeScope(View, reason);
+
+    @autoreleasepool {
+        auto maxSize = lastMaxSize;
+        auto minSize = lastMinSize;
+
+        if (x < minSize.width) {
+            x = minSize.width;
+        }
+
+        if (y < minSize.height) {
+            y = minSize.height;
+        }
+
+        if (x > maxSize.width) {
+            x = maxSize.width;
+        }
+
+        if (y > maxSize.height) {
+            y = maxSize.height;
+        }
+
+        @try {
+            lastSize = NSSize {x, y};
+
+            if (!_shown) {
+                BaseEvents->Resized(AvnSize{x, y}, reason);
+            }
+
+            if(Window != nullptr) {
+                [Window setContentSize:lastSize];
+                [Window invalidateShadow];
+            }
+        }
+        @finally {
+            _inResize = false;
+        }
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowBaseImpl::Invalidate(__attribute__((unused)) AvnRect rect) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        [View setNeedsDisplayInRect:[View frame]];
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowBaseImpl::SetMainMenu(IAvnMenu *menu) {
+    START_COM_CALL;
+
+    auto nativeMenu = dynamic_cast<AvnAppMenu *>(menu);
+
+    lastMenu = nativeMenu->GetNative();
+
+    if(Window != nullptr) {
+        [GetWindowProtocol() applyMenu:lastMenu];
+
+        if ([Window isKeyWindow]) {
+            [GetWindowProtocol() showWindowMenuWithAppMenu];
+        }
+    }
+
+    return S_OK;
+}
+
+HRESULT WindowBaseImpl::BeginMoveDrag() {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        auto lastEvent = [View lastMouseDownEvent];
+
+        if (lastEvent == nullptr) {
+            return S_OK;
+        }
+
+        [Window performWindowDragWithEvent:lastEvent];
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowBaseImpl::BeginResizeDrag(__attribute__((unused)) AvnWindowEdge edge) {
+    START_COM_CALL;
+
+    return S_OK;
+}
+
+HRESULT WindowBaseImpl::GetPosition(AvnPoint *ret) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        if (ret == nullptr) {
+            return E_POINTER;
+        }
+
+        if(Window != nullptr) {
+            auto frame = [Window frame];
+
+            ret->X = frame.origin.x;
+            ret->Y = frame.origin.y + frame.size.height;
+
+            *ret = ConvertPointY(*ret);
+        } else
+        {
+            *ret = lastPositionSet;
+        }
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowBaseImpl::SetPosition(AvnPoint point) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        lastPositionSet = point;
+        hasPosition = true;
+
+        if(Window != nullptr) {
+            [Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(point))];
+        }
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowBaseImpl::PointToClient(AvnPoint point, AvnPoint *ret) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        if (ret == nullptr) {
+            return E_POINTER;
+        }
+
+        point = ConvertPointY(point);
+        NSRect convertRect = [Window convertRectFromScreen:NSMakeRect(point.X, point.Y, 0.0, 0.0)];
+        auto viewPoint = NSMakePoint(convertRect.origin.x, convertRect.origin.y);
+
+        *ret = [View translateLocalPoint:ToAvnPoint(viewPoint)];
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowBaseImpl::PointToScreen(AvnPoint point, AvnPoint *ret) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        if (ret == nullptr) {
+            return E_POINTER;
+        }
+
+        auto cocoaViewPoint = ToNSPoint([View translateLocalPoint:point]);
+        NSRect convertRect = [Window convertRectToScreen:NSMakeRect(cocoaViewPoint.x, cocoaViewPoint.y, 0.0, 0.0)];
+        auto cocoaScreenPoint = NSPointFromCGPoint(NSMakePoint(convertRect.origin.x, convertRect.origin.y));
+        *ret = ConvertPointY(ToAvnPoint(cocoaScreenPoint));
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowBaseImpl::ThreadSafeSetSwRenderedFrame(AvnFramebuffer *fb, IUnknown *dispose) {
+    START_COM_CALL;
+
+    [View setSwRenderedFrame:fb dispose:dispose];
+    return S_OK;
+}
+
+HRESULT WindowBaseImpl::SetCursor(IAvnCursor *cursor) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        Cursor *avnCursor = dynamic_cast<Cursor *>(cursor);
+        this->cursor = avnCursor->GetNative();
+        UpdateCursor();
+
+        if (avnCursor->IsHidden()) {
+            [NSCursor hide];
+        } else {
+            [NSCursor unhide];
+        }
+
+        return S_OK;
+    }
+}
+
+void WindowBaseImpl::UpdateCursor() {
+    if (cursor != nil) {
+        [cursor set];
+    }
+}
+
+HRESULT WindowBaseImpl::CreateGlRenderTarget(IAvnGlSurfaceRenderTarget **ppv) {
+    START_COM_CALL;
+
+    if (View == NULL)
+        return E_FAIL;
+    *ppv = [renderTarget createSurfaceRenderTarget];
+    return static_cast<HRESULT>(*ppv == nil ? E_FAIL : S_OK);
+}
+
+HRESULT WindowBaseImpl::CreateNativeControlHost(IAvnNativeControlHost **retOut) {
+    START_COM_CALL;
+
+    if (View == NULL)
+        return E_FAIL;
+    *retOut = ::CreateNativeControlHost(View);
+    return S_OK;
+}
+
+HRESULT WindowBaseImpl::SetBlurEnabled(bool enable) {
+    START_COM_CALL;
+
+    [StandardContainer ShowBlur:enable];
+
+    return S_OK;
+}
+
+HRESULT WindowBaseImpl::BeginDragAndDropOperation(AvnDragDropEffects effects, AvnPoint point, IAvnClipboard *clipboard, IAvnDndResultCallback *cb, void *sourceHandle) {
+    START_COM_CALL;
+
+    auto item = TryGetPasteboardItem(clipboard);
+    [item setString:@"" forType:GetAvnCustomDataType()];
+    if (item == nil)
+        return E_INVALIDARG;
+    if (View == NULL)
+        return E_FAIL;
+
+    auto nsevent = [NSApp currentEvent];
+    auto nseventType = [nsevent type];
+
+    // If current event isn't a mouse one (probably due to malfunctioning user app)
+    // attempt to forge a new one
+    if (!((nseventType >= NSEventTypeLeftMouseDown && nseventType <= NSEventTypeMouseExited)
+            || (nseventType >= NSEventTypeOtherMouseDown && nseventType <= NSEventTypeOtherMouseDragged))) {
+        NSRect convertRect = [Window convertRectToScreen:NSMakeRect(point.X, point.Y, 0.0, 0.0)];
+        auto nspoint = NSMakePoint(convertRect.origin.x, convertRect.origin.y);
+        CGPoint cgpoint = NSPointToCGPoint(nspoint);
+        auto cgevent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, cgpoint, kCGMouseButtonLeft);
+        nsevent = [NSEvent eventWithCGEvent:cgevent];
+        CFRelease(cgevent);
+    }
+
+    auto dragItem = [[NSDraggingItem alloc] initWithPasteboardWriter:item];
+
+    auto dragItemImage = [NSImage imageNamed:NSImageNameMultipleDocuments];
+    NSRect dragItemRect = {(float) point.X, (float) point.Y, [dragItemImage size].width, [dragItemImage size].height};
+    [dragItem setDraggingFrame:dragItemRect contents:dragItemImage];
+
+    int op = 0;
+    int ieffects = (int) effects;
+    if ((ieffects & (int) AvnDragDropEffects::Copy) != 0)
+        op |= NSDragOperationCopy;
+    if ((ieffects & (int) AvnDragDropEffects::Link) != 0)
+        op |= NSDragOperationLink;
+    if ((ieffects & (int) AvnDragDropEffects::Move) != 0)
+        op |= NSDragOperationMove;
+    [View beginDraggingSessionWithItems:@[dragItem] event:nsevent
+                                 source:CreateDraggingSource((NSDragOperation) op, cb, sourceHandle)];
+    return S_OK;
+}
+
+bool WindowBaseImpl::IsDialog() {
+    return false;
+}
+
+NSWindowStyleMask WindowBaseImpl::GetStyle() {
+    return NSWindowStyleMaskBorderless;
+}
+
+void WindowBaseImpl::UpdateStyle() {
+    [Window setStyleMask:GetStyle()];
+}
+
+void WindowBaseImpl::CleanNSWindow() {
+    if(Window != nullptr) {
+        [GetWindowProtocol() disconnectParent];
+        [Window close];
+        Window = nullptr;
+    }
+}
+
+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()];
+        }
+    } else {
+        if (![Window isKindOfClass:[AvnWindow class]]) {
+            CleanNSWindow();
+
+            Window = [[AvnWindow alloc] initWithParent:this contentRect:NSRect{0, 0, lastSize} styleMask:GetStyle()];
+        }
+    }
+}
+
+void WindowBaseImpl::OnInitialiseNSWindow()
+{
+    
+}
+
+void WindowBaseImpl::InitialiseNSWindow() {
+    if(Window != nullptr) {
+        [Window setContentView:StandardContainer];
+        [Window setStyleMask:NSWindowStyleMaskBorderless];
+        [Window setBackingType:NSBackingStoreBuffered];
+
+        [Window setContentSize:lastSize];
+        [Window setContentMinSize:lastMinSize];
+        [Window setContentMaxSize:lastMaxSize];
+
+        [Window setOpaque:false];
+        
+        [Window invalidateShadow];
+
+        if (lastMenu != nullptr) {
+            [GetWindowProtocol() applyMenu:lastMenu];
+
+            if ([Window isKeyWindow]) {
+                [GetWindowProtocol() showWindowMenuWithAppMenu];
+            }
+        }
+        
+        OnInitialiseNSWindow();
+    }
+}
+
+id <AvnWindowProtocol> WindowBaseImpl::GetWindowProtocol() {
+    if(Window == nullptr)
+    {
+        return nullptr;
+    }
+
+    return (id <AvnWindowProtocol>) Window;
+}
+
+extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events, IAvnGlContext* gl)
+{
+    @autoreleasepool
+    {
+        IAvnWindow* ptr = (IAvnWindow*)new WindowImpl(events, gl);
+        return ptr;
+    }
+}

+ 101 - 0
native/Avalonia.Native/src/OSX/WindowImpl.h

@@ -0,0 +1,101 @@
+//
+// Created by Dan Walmsley on 04/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#ifndef AVALONIA_NATIVE_OSX_WINDOWIMPL_H
+#define AVALONIA_NATIVE_OSX_WINDOWIMPL_H
+
+#import "WindowBaseImpl.h"
+#include "IWindowStateChanged.h"
+
+class WindowImpl : public virtual WindowBaseImpl, public virtual IAvnWindow, public IWindowStateChanged
+{
+private:
+    bool _canResize;
+    bool _fullScreenActive;
+    SystemDecorations _decorations;
+    AvnWindowState _lastWindowState;
+    AvnWindowState _actualWindowState;
+    bool _inSetWindowState;
+    NSRect _preZoomSize;
+    bool _transitioningWindowState;
+    bool _isClientAreaExtended;
+    bool _isDialog;
+    AvnExtendClientAreaChromeHints _extendClientHints;
+
+    FORWARD_IUNKNOWN()
+BEGIN_INTERFACE_MAP()
+        INHERIT_INTERFACE_MAP(WindowBaseImpl)
+        INTERFACE_MAP_ENTRY(IAvnWindow, IID_IAvnWindow)
+    END_INTERFACE_MAP()
+    virtual ~WindowImpl()
+    {
+    }
+
+    ComPtr<IAvnWindowEvents> WindowEvents;
+
+    WindowImpl(IAvnWindowEvents* events, IAvnGlContext* gl);
+
+    void HideOrShowTrafficLights ();
+
+    virtual HRESULT Show (bool activate, bool isDialog) override;
+
+    virtual HRESULT SetEnabled (bool enable) override;
+
+    virtual HRESULT SetParent (IAvnWindow* parent) override;
+
+    void StartStateTransition () override ;
+
+    void EndStateTransition () override ;
+
+    SystemDecorations Decorations () override ;
+
+    AvnWindowState WindowState () override ;
+
+    void WindowStateChanged () override ;
+
+    bool UndecoratedIsMaximized ();
+
+    bool IsZoomed ();
+
+    void DoZoom();
+
+    virtual HRESULT SetCanResize(bool value) override;
+
+    virtual HRESULT SetDecorations(SystemDecorations value) override;
+
+    virtual HRESULT SetTitle (char* utf8title) override;
+
+    virtual HRESULT SetTitleBarColor(AvnColor color) override;
+
+    virtual HRESULT GetWindowState (AvnWindowState*ret) override;
+
+    virtual HRESULT TakeFocusFromChildren () override;
+
+    virtual HRESULT SetExtendClientArea (bool enable) override;
+
+    virtual HRESULT SetExtendClientAreaHints (AvnExtendClientAreaChromeHints hints) override;
+
+    virtual HRESULT GetExtendTitleBarHeight (double*ret) override;
+
+    virtual HRESULT SetExtendTitleBarHeight (double value) override;
+
+    void EnterFullScreenMode ();
+
+    void ExitFullScreenMode ();
+
+    virtual HRESULT SetWindowState (AvnWindowState state) override;
+
+    virtual bool IsDialog() override;
+    
+    virtual void OnInitialiseNSWindow() override;
+
+protected:
+    virtual NSWindowStyleMask GetStyle() override;
+
+private:
+    NSString *_lastTitle;
+};
+
+#endif //AVALONIA_NATIVE_OSX_WINDOWIMPL_H

+ 554 - 0
native/Avalonia.Native/src/OSX/WindowImpl.mm

@@ -0,0 +1,554 @@
+//
+// Created by Dan Walmsley on 04/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#import <AppKit/AppKit.h>
+#include "AutoFitContentView.h"
+#include "AvnView.h"
+#include "automation.h"
+#include "WindowProtocol.h"
+
+WindowImpl::WindowImpl(IAvnWindowEvents *events, IAvnGlContext *gl) : WindowBaseImpl(events, gl) {
+    _isClientAreaExtended = false;
+    _extendClientHints = AvnDefaultChrome;
+    _fullScreenActive = false;
+    _canResize = true;
+    _decorations = SystemDecorationsFull;
+    _transitioningWindowState = false;
+    _inSetWindowState = false;
+    _lastWindowState = Normal;
+    _actualWindowState = Normal;
+    _lastTitle = @"";
+    WindowEvents = events;
+}
+
+void WindowImpl::HideOrShowTrafficLights() {
+    if (Window == nil) {
+        return;
+    }
+
+    for (id subview in Window.contentView.superview.subviews) {
+        if ([subview isKindOfClass:NSClassFromString(@"NSTitlebarContainerView")]) {
+            NSView *titlebarView = [subview subviews][0];
+            for (id button in titlebarView.subviews) {
+                if ([button isKindOfClass:[NSButton class]]) {
+                    if (_isClientAreaExtended) {
+                        auto wantsChrome = (_extendClientHints & AvnSystemChrome) || (_extendClientHints & AvnPreferSystemChrome);
+
+                        [button setHidden:!wantsChrome];
+                    } else {
+                        [button setHidden:(_decorations != SystemDecorationsFull)];
+                    }
+
+                    [button setWantsLayer:true];
+                }
+            }
+        }
+    }
+}
+
+void WindowImpl::OnInitialiseNSWindow(){
+    [GetWindowProtocol() setCanBecomeKeyWindow:true];
+    [Window disableCursorRects];
+    [Window setTabbingMode:NSWindowTabbingModeDisallowed];
+    [Window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
+
+    [Window setTitle:_lastTitle];
+    
+    if(_isClientAreaExtended)
+    {
+        [GetWindowProtocol() setIsExtended:true];
+        SetExtendClientArea(true);
+    }
+}
+
+HRESULT WindowImpl::Show(bool activate, bool isDialog) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        _isDialog = isDialog;
+
+        WindowBaseImpl::Show(activate, isDialog);
+
+        HideOrShowTrafficLights();
+
+        return SetWindowState(_lastWindowState);
+    }
+}
+
+HRESULT WindowImpl::SetEnabled(bool enable) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        [GetWindowProtocol() setEnabled:enable];
+        return S_OK;
+    }
+}
+
+HRESULT WindowImpl::SetParent(IAvnWindow *parent) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        if (parent == nullptr)
+            return E_POINTER;
+
+        auto cparent = dynamic_cast<WindowImpl *>(parent);
+        if (cparent == nullptr)
+            return E_INVALIDARG;
+
+        // If one tries to show a child window with a minimized parent window, then the parent window will be
+        // restored but macOS isn't kind enough to *tell* us that, so the window will be left in a non-interactive
+        // state. Detect this and explicitly restore the parent window ourselves to avoid this situation.
+        if (cparent->WindowState() == Minimized)
+            cparent->SetWindowState(Normal);
+
+        [Window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
+        [cparent->Window addChildWindow:Window ordered:NSWindowAbove];
+
+        UpdateStyle();
+
+        return S_OK;
+    }
+}
+
+void WindowImpl::StartStateTransition() {
+    _transitioningWindowState = true;
+}
+
+void WindowImpl::EndStateTransition() {
+    _transitioningWindowState = false;
+}
+
+SystemDecorations WindowImpl::Decorations() {
+    return _decorations;
+}
+
+AvnWindowState WindowImpl::WindowState() {
+    return _lastWindowState;
+}
+
+void WindowImpl::WindowStateChanged() {
+    if (_shown && !_inSetWindowState && !_transitioningWindowState) {
+        AvnWindowState state;
+        GetWindowState(&state);
+
+        if (_lastWindowState != state) {
+            if (_isClientAreaExtended) {
+                if (_lastWindowState == FullScreen) {
+                    // we exited fs.
+                    if (_extendClientHints & AvnOSXThickTitleBar) {
+                        Window.toolbar = [NSToolbar new];
+                        Window.toolbar.showsBaselineSeparator = false;
+                    }
+
+                    [Window setTitlebarAppearsTransparent:true];
+
+                    [StandardContainer setFrameSize:StandardContainer.frame.size];
+                } else if (state == FullScreen) {
+                    // we entered fs.
+                    if (_extendClientHints & AvnOSXThickTitleBar) {
+                        Window.toolbar = nullptr;
+                    }
+
+                    [Window setTitlebarAppearsTransparent:false];
+
+                    [StandardContainer setFrameSize:StandardContainer.frame.size];
+                }
+            }
+
+            _lastWindowState = state;
+            _actualWindowState = state;
+            WindowEvents->WindowStateChanged(state);
+        }
+    }
+}
+
+bool WindowImpl::UndecoratedIsMaximized() {
+    auto windowSize = [Window frame];
+    auto available = [Window screen].visibleFrame;
+    return CGRectEqualToRect(windowSize, available);
+}
+
+bool WindowImpl::IsZoomed() {
+    return _decorations == SystemDecorationsFull ? [Window isZoomed] : UndecoratedIsMaximized();
+}
+
+void WindowImpl::DoZoom() {
+    switch (_decorations) {
+        case SystemDecorationsNone:
+        case SystemDecorationsBorderOnly:
+            [Window setFrame:[Window screen].visibleFrame display:true];
+            break;
+
+
+        case SystemDecorationsFull:
+            [Window performZoom:Window];
+            break;
+    }
+}
+
+HRESULT WindowImpl::SetCanResize(bool value) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        _canResize = value;
+        UpdateStyle();
+        return S_OK;
+    }
+}
+
+HRESULT WindowImpl::SetDecorations(SystemDecorations value) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        auto currentWindowState = _lastWindowState;
+        _decorations = value;
+
+        if (_fullScreenActive) {
+            return S_OK;
+        }
+
+        UpdateStyle();
+
+        HideOrShowTrafficLights();
+
+        switch (_decorations) {
+            case SystemDecorationsNone:
+                [Window setHasShadow:NO];
+                [Window setTitleVisibility:NSWindowTitleHidden];
+                [Window setTitlebarAppearsTransparent:YES];
+
+                if (currentWindowState == Maximized) {
+                    if (!UndecoratedIsMaximized()) {
+                        DoZoom();
+                    }
+                }
+                break;
+
+            case SystemDecorationsBorderOnly:
+                [Window setHasShadow:YES];
+                [Window setTitleVisibility:NSWindowTitleHidden];
+                [Window setTitlebarAppearsTransparent:YES];
+
+                if (currentWindowState == Maximized) {
+                    if (!UndecoratedIsMaximized()) {
+                        DoZoom();
+                    }
+                }
+                break;
+
+            case SystemDecorationsFull:
+                [Window setHasShadow:YES];
+                [Window setTitleVisibility:NSWindowTitleVisible];
+                [Window setTitlebarAppearsTransparent:NO];
+                [Window setTitle:_lastTitle];
+
+                if (currentWindowState == Maximized) {
+                    auto newFrame = [Window contentRectForFrameRect:[Window frame]].size;
+
+                    [View setFrameSize:newFrame];
+                }
+                break;
+        }
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowImpl::SetTitle(char *utf8title) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        _lastTitle = [NSString stringWithUTF8String:(const char *) utf8title];
+        [Window setTitle:_lastTitle];
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowImpl::SetTitleBarColor(AvnColor color) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        float a = (float) color.Alpha / 255.0f;
+        float r = (float) color.Red / 255.0f;
+        float g = (float) color.Green / 255.0f;
+        float b = (float) color.Blue / 255.0f;
+
+        auto nscolor = [NSColor colorWithSRGBRed:r green:g blue:b alpha:a];
+
+        // Based on the titlebar color we have to choose either light or dark
+        // OSX doesnt let you set a foreground color for titlebar.
+        if ((r * 0.299 + g * 0.587 + b * 0.114) > 186.0f / 255.0f) {
+            [Window setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantLight]];
+        } else {
+            [Window setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]];
+        }
+
+        [Window setTitlebarAppearsTransparent:true];
+        [Window setBackgroundColor:nscolor];
+    }
+
+    return S_OK;
+}
+
+HRESULT WindowImpl::GetWindowState(AvnWindowState *ret) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        if (ret == nullptr) {
+            return E_POINTER;
+        }
+
+        if (([Window styleMask] & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen) {
+            *ret = FullScreen;
+            return S_OK;
+        }
+
+        if ([Window isMiniaturized]) {
+            *ret = Minimized;
+            return S_OK;
+        }
+
+        if (IsZoomed()) {
+            *ret = Maximized;
+            return S_OK;
+        }
+
+        *ret = Normal;
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowImpl::TakeFocusFromChildren() {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        if (Window == nil)
+            return S_OK;
+        if ([Window isKeyWindow])
+            [Window makeFirstResponder:View];
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowImpl::SetExtendClientArea(bool enable) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        _isClientAreaExtended = enable;
+
+        if(Window != nullptr) {
+            if (enable) {
+                Window.titleVisibility = NSWindowTitleHidden;
+
+                [Window setTitlebarAppearsTransparent:true];
+
+                auto wantsTitleBar = (_extendClientHints & AvnSystemChrome) || (_extendClientHints & AvnPreferSystemChrome);
+
+                if (wantsTitleBar) {
+                    [StandardContainer ShowTitleBar:true];
+                } else {
+                    [StandardContainer ShowTitleBar:false];
+                }
+
+                if (_extendClientHints & AvnOSXThickTitleBar) {
+                    Window.toolbar = [NSToolbar new];
+                    Window.toolbar.showsBaselineSeparator = false;
+                } else {
+                    Window.toolbar = nullptr;
+                }
+            } else {
+                Window.titleVisibility = NSWindowTitleVisible;
+                Window.toolbar = nullptr;
+                [Window setTitlebarAppearsTransparent:false];
+                View.layer.zPosition = 0;
+            }
+
+            [GetWindowProtocol() setIsExtended:enable];
+
+            HideOrShowTrafficLights();
+
+            UpdateStyle();
+        }
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowImpl::SetExtendClientAreaHints(AvnExtendClientAreaChromeHints hints) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        _extendClientHints = hints;
+
+        SetExtendClientArea(_isClientAreaExtended);
+        return S_OK;
+    }
+}
+
+HRESULT WindowImpl::GetExtendTitleBarHeight(double *ret) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        if (ret == nullptr) {
+            return E_POINTER;
+        }
+
+        *ret = [GetWindowProtocol() getExtendedTitleBarHeight];
+
+        return S_OK;
+    }
+}
+
+HRESULT WindowImpl::SetExtendTitleBarHeight(double value) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        [StandardContainer SetTitleBarHeightHint:value];
+        return S_OK;
+    }
+}
+
+void WindowImpl::EnterFullScreenMode() {
+    _fullScreenActive = true;
+
+    [Window setTitle:_lastTitle];
+    [Window toggleFullScreen:nullptr];
+}
+
+void WindowImpl::ExitFullScreenMode() {
+    [Window toggleFullScreen:nullptr];
+
+    _fullScreenActive = false;
+
+    SetDecorations(_decorations);
+}
+
+HRESULT WindowImpl::SetWindowState(AvnWindowState state) {
+    START_COM_CALL;
+
+    @autoreleasepool {
+        auto currentState = _actualWindowState;
+        _lastWindowState = state;
+
+        if (Window == nullptr) {
+            return S_OK;
+        }
+
+        if (_actualWindowState == state) {
+            return S_OK;
+        }
+
+        _inSetWindowState = true;
+
+        if (currentState == Normal) {
+            _preZoomSize = [Window frame];
+        }
+
+        if (_shown) {
+            switch (state) {
+                case Maximized:
+                    if (currentState == FullScreen) {
+                        ExitFullScreenMode();
+                    }
+
+                    lastPositionSet.X = 0;
+                    lastPositionSet.Y = 0;
+
+                    if ([Window isMiniaturized]) {
+                        [Window deminiaturize:Window];
+                    }
+
+                    if (!IsZoomed()) {
+                        DoZoom();
+                    }
+                    break;
+
+                case Minimized:
+                    if (currentState == FullScreen) {
+                        ExitFullScreenMode();
+                    } else {
+                        [Window miniaturize:Window];
+                    }
+                    break;
+
+                case FullScreen:
+                    if ([Window isMiniaturized]) {
+                        [Window deminiaturize:Window];
+                    }
+
+                    EnterFullScreenMode();
+                    break;
+
+                case Normal:
+                    if ([Window isMiniaturized]) {
+                        [Window deminiaturize:Window];
+                    }
+
+                    if (currentState == FullScreen) {
+                        ExitFullScreenMode();
+                    }
+
+                    if (IsZoomed()) {
+                        if (_decorations == SystemDecorationsFull) {
+                            DoZoom();
+                        } else {
+                            [Window setFrame:_preZoomSize display:true];
+                            auto newFrame = [Window contentRectForFrameRect:[Window frame]].size;
+
+                            [View setFrameSize:newFrame];
+                        }
+
+                    }
+                    break;
+            }
+
+            _actualWindowState = _lastWindowState;
+            WindowEvents->WindowStateChanged(_actualWindowState);
+        }
+
+
+        _inSetWindowState = false;
+
+        return S_OK;
+    }
+}
+
+bool WindowImpl::IsDialog() {
+    return _isDialog;
+}
+
+NSWindowStyleMask WindowImpl::GetStyle() {
+    unsigned long s = this->_isDialog ? NSWindowStyleMaskDocModalWindow : NSWindowStyleMaskBorderless;
+
+    switch (_decorations) {
+        case SystemDecorationsNone:
+            s = s | NSWindowStyleMaskFullSizeContentView;
+            break;
+
+        case SystemDecorationsBorderOnly:
+            s = s | NSWindowStyleMaskTitled | NSWindowStyleMaskFullSizeContentView;
+            break;
+
+        case SystemDecorationsFull:
+            s = s | NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskBorderless;
+
+            if (_canResize) {
+                s = s | NSWindowStyleMaskResizable;
+            }
+            break;
+    }
+
+    if ([Window parentWindow] == nullptr) {
+        s |= NSWindowStyleMaskMiniaturizable;
+    }
+
+    if (_isClientAreaExtended) {
+        s |= NSWindowStyleMaskFullSizeContentView | NSWindowStyleMaskTexturedBackground;
+    }
+    return s;
+}

+ 17 - 0
native/Avalonia.Native/src/OSX/WindowInterfaces.h

@@ -0,0 +1,17 @@
+//
+// Created by Dan Walmsley on 06/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <AppKit/AppKit.h>
+#include "WindowProtocol.h"
+#include "WindowBaseImpl.h"
+
+@interface AvnWindow : NSWindow <AvnWindowProtocol, NSWindowDelegate>
+-(AvnWindow* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent contentRect: (NSRect)contentRect styleMask: (NSWindowStyleMask)styleMask;
+@end
+
+@interface AvnPanel : NSPanel <AvnWindowProtocol, NSWindowDelegate>
+-(AvnPanel* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent contentRect: (NSRect)contentRect styleMask: (NSWindowStyleMask)styleMask;
+@end

+ 27 - 0
native/Avalonia.Native/src/OSX/WindowProtocol.h

@@ -0,0 +1,27 @@
+//
+// Created by Dan Walmsley on 06/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#pragma once
+
+#import <AppKit/AppKit.h>
+
+@class AvnMenu;
+
+@protocol AvnWindowProtocol
+-(void) pollModalSession: (NSModalSession _Nonnull) session;
+-(void) restoreParentWindow;
+-(bool) shouldTryToHandleEvents;
+-(void) setEnabled: (bool) enable;
+-(void) showAppMenuOnly;
+-(void) showWindowMenuWithAppMenu;
+-(void) applyMenu:(AvnMenu* _Nullable)menu;
+
+-(double) getExtendedTitleBarHeight;
+-(void) setIsExtended:(bool)value;
+-(void) disconnectParent;
+-(bool) isDialog;
+
+-(void) setCanBecomeKeyWindow:(bool)value;
+@end

+ 5 - 12
native/Avalonia.Native/src/OSX/app.mm

@@ -73,22 +73,15 @@ ComPtr<IAvnApplicationEvents> _events;
     _isHandlingSendEvent = true;
     @try {
         [super sendEvent: event];
+        if ([event type] == NSEventTypeKeyUp && ([event modifierFlags] & NSEventModifierFlagCommand))
+        {
+            [[self keyWindow] sendEvent:event];
+        }
+        
     } @finally {
         _isHandlingSendEvent = oldHandling;
     }
 }
-
-// This is needed for certain embedded controls
-- (BOOL) isHandlingSendEvent
-{
-    return _isHandlingSendEvent;
-}
-
-- (void)setHandlingSendEvent:(BOOL)handlingSendEvent
-{
-    _isHandlingSendEvent = handlingSendEvent;
-}
-
 @end
 
 extern void InitializeAvnApp(IAvnApplicationEvents* events)

+ 12 - 0
native/Avalonia.Native/src/OSX/automation.h

@@ -0,0 +1,12 @@
+#pragma once
+
+#import <Cocoa/Cocoa.h>
+NS_ASSUME_NONNULL_BEGIN
+
+class IAvnAutomationPeer;
+
+@interface AvnAccessibilityElement : NSAccessibilityElement
++ (AvnAccessibilityElement *) acquire:(IAvnAutomationPeer *) peer;
+@end
+
+NS_ASSUME_NONNULL_END

+ 497 - 0
native/Avalonia.Native/src/OSX/automation.mm

@@ -0,0 +1,497 @@
+#include "common.h"
+#include "automation.h"
+#include "AvnString.h"
+#include "INSWindowHolder.h"
+#include "AvnView.h"
+
+@interface AvnAccessibilityElement (Events)
+- (void) raiseChildrenChanged;
+@end
+
+@interface AvnRootAccessibilityElement : AvnAccessibilityElement
+- (AvnView *) ownerView;
+- (AvnRootAccessibilityElement *) initWithPeer:(IAvnAutomationPeer *) peer owner:(AvnView*) owner;
+- (void) raiseFocusChanged;
+@end
+
+class AutomationNode : public ComSingleObject<IAvnAutomationNode, &IID_IAvnAutomationNode>
+{
+public:
+    FORWARD_IUNKNOWN()
+
+    AutomationNode(AvnAccessibilityElement* owner)
+    {
+        _owner = owner;
+    }
+    
+    AvnAccessibilityElement* GetOwner()
+    {
+        return _owner;
+    }
+    
+    virtual void Dispose() override
+    {
+        _owner = nil;
+    }
+    
+    virtual void ChildrenChanged () override
+    {
+        [_owner raiseChildrenChanged];
+    }
+    
+    virtual void PropertyChanged (AvnAutomationProperty property) override
+    {
+        
+    }
+    
+    virtual void FocusChanged () override
+    {
+        [(AvnRootAccessibilityElement*)_owner raiseFocusChanged];
+    }
+    
+private:
+    __strong AvnAccessibilityElement* _owner;
+};
+
+@implementation AvnAccessibilityElement
+{
+    IAvnAutomationPeer* _peer;
+    AutomationNode* _node;
+    NSMutableArray* _children;
+}
+
++ (AvnAccessibilityElement *)acquire:(IAvnAutomationPeer *)peer
+{
+    if (peer == nullptr)
+        return nil;
+    
+    auto instance = peer->GetNode();
+    
+    if (instance != nullptr)
+        return dynamic_cast<AutomationNode*>(instance)->GetOwner();
+    
+    if (peer->IsRootProvider())
+    {
+        auto window = peer->RootProvider_GetWindow();
+        auto holder = dynamic_cast<INSWindowHolder*>(window);
+        auto view = holder->GetNSView();
+        return [[AvnRootAccessibilityElement alloc] initWithPeer:peer owner:view];
+    }
+    else
+    {
+        return [[AvnAccessibilityElement alloc] initWithPeer:peer];
+    }
+}
+
+- (AvnAccessibilityElement *)initWithPeer:(IAvnAutomationPeer *)peer
+{
+    self = [super init];
+    _peer = peer;
+    _node = new AutomationNode(self);
+    _peer->SetNode(_node);
+    return self;
+}
+
+- (void)dealloc
+{
+    if (_node)
+        delete _node;
+    _node = nullptr;
+}
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@"%@ '%@' (%p)",
+        GetNSStringAndRelease(_peer->GetClassName()),
+        GetNSStringAndRelease(_peer->GetName()),
+        _peer];
+}
+
+- (IAvnAutomationPeer *)peer
+{
+    return _peer;
+}
+
+- (BOOL)isAccessibilityElement
+{
+    return _peer->IsControlElement();
+}
+
+- (NSAccessibilityRole)accessibilityRole
+{
+    auto controlType = _peer->GetAutomationControlType();
+    
+    switch (controlType) {
+        case AutomationButton: return NSAccessibilityButtonRole;
+        case AutomationCalendar: return NSAccessibilityGridRole;
+        case AutomationCheckBox: return NSAccessibilityCheckBoxRole;
+        case AutomationComboBox: return NSAccessibilityPopUpButtonRole;
+        case AutomationComboBoxItem: return NSAccessibilityMenuItemRole;
+        case AutomationEdit: return NSAccessibilityTextFieldRole;
+        case AutomationHyperlink: return NSAccessibilityLinkRole;
+        case AutomationImage: return NSAccessibilityImageRole;
+        case AutomationListItem: return NSAccessibilityRowRole;
+        case AutomationList: return NSAccessibilityTableRole;
+        case AutomationMenu: return NSAccessibilityMenuBarRole;
+        case AutomationMenuBar: return NSAccessibilityMenuBarRole;
+        case AutomationMenuItem: return NSAccessibilityMenuItemRole;
+        case AutomationProgressBar: return NSAccessibilityProgressIndicatorRole;
+        case AutomationRadioButton: return NSAccessibilityRadioButtonRole;
+        case AutomationScrollBar: return NSAccessibilityScrollBarRole;
+        case AutomationSlider: return NSAccessibilitySliderRole;
+        case AutomationSpinner: return NSAccessibilityIncrementorRole;
+        case AutomationStatusBar: return NSAccessibilityTableRole;
+        case AutomationTab: return NSAccessibilityTabGroupRole;
+        case AutomationTabItem: return NSAccessibilityRadioButtonRole;
+        case AutomationText: return NSAccessibilityStaticTextRole;
+        case AutomationToolBar: return NSAccessibilityToolbarRole;
+        case AutomationToolTip: return NSAccessibilityPopoverRole;
+        case AutomationTree: return NSAccessibilityOutlineRole;
+        case AutomationTreeItem: return NSAccessibilityCellRole;
+        case AutomationCustom: return NSAccessibilityUnknownRole;
+        case AutomationGroup: return NSAccessibilityGroupRole;
+        case AutomationThumb: return NSAccessibilityHandleRole;
+        case AutomationDataGrid: return NSAccessibilityGridRole;
+        case AutomationDataItem: return NSAccessibilityCellRole;
+        case AutomationDocument: return NSAccessibilityStaticTextRole;
+        case AutomationSplitButton: return NSAccessibilityPopUpButtonRole;
+        case AutomationWindow: return NSAccessibilityWindowRole;
+        case AutomationPane: return NSAccessibilityGroupRole;
+        case AutomationHeader: return NSAccessibilityGroupRole;
+        case AutomationHeaderItem:  return NSAccessibilityButtonRole;
+        case AutomationTable: return NSAccessibilityTableRole;
+        case AutomationTitleBar: return NSAccessibilityGroupRole;
+        // Treat unknown roles as generic group container items. Returning
+        // NSAccessibilityUnknownRole is also possible but makes the screen
+       // reader focus on the item instead of passing focus to child items.
+        default: return NSAccessibilityGroupRole;
+    }
+}
+
+- (NSString *)accessibilityIdentifier
+{
+    return GetNSStringAndRelease(_peer->GetAutomationId());
+}
+
+- (NSString *)accessibilityTitle
+{
+    // StaticText exposes its text via the value property.
+    if (_peer->GetAutomationControlType() != AutomationText)
+    {
+        return GetNSStringAndRelease(_peer->GetName());
+    }
+    
+    return [super accessibilityTitle];
+}
+
+- (id)accessibilityValue
+{
+    if (_peer->IsRangeValueProvider())
+    {
+        return [NSNumber numberWithDouble:_peer->RangeValueProvider_GetValue()];
+    }
+    else if (_peer->IsToggleProvider())
+    {
+        switch (_peer->ToggleProvider_GetToggleState()) {
+            case 0: return [NSNumber numberWithBool:NO];
+            case 1: return [NSNumber numberWithBool:YES];
+            default: return [NSNumber numberWithInt:2];
+        }
+    }
+    else if (_peer->IsValueProvider())
+    {
+        return GetNSStringAndRelease(_peer->ValueProvider_GetValue());
+    }
+    else if (_peer->GetAutomationControlType() == AutomationText)
+    {
+        return GetNSStringAndRelease(_peer->GetName());
+    }
+
+    return [super accessibilityValue];
+}
+
+- (id)accessibilityMinValue
+{
+    if (_peer->IsRangeValueProvider())
+    {
+        return [NSNumber numberWithDouble:_peer->RangeValueProvider_GetMinimum()];
+    }
+    
+    return [super accessibilityMinValue];
+}
+
+- (id)accessibilityMaxValue
+{
+    if (_peer->IsRangeValueProvider())
+    {
+        return [NSNumber numberWithDouble:_peer->RangeValueProvider_GetMaximum()];
+    }
+    
+    return [super accessibilityMaxValue];
+}
+
+- (BOOL)isAccessibilityEnabled
+{
+    return _peer->IsEnabled();
+}
+
+- (BOOL)isAccessibilityFocused
+{
+    return _peer->HasKeyboardFocus();
+}
+
+- (NSArray *)accessibilityChildren
+{
+    if (_children == nullptr && _peer != nullptr)
+        [self recalculateChildren];
+    return _children;
+}
+
+- (NSRect)accessibilityFrame
+{
+    id topLevel = [self accessibilityTopLevelUIElement];
+    auto result = NSZeroRect;
+
+    if ([topLevel isKindOfClass:[AvnRootAccessibilityElement class]])
+    {
+        auto root = (AvnRootAccessibilityElement*)topLevel;
+        auto view = [root ownerView];
+        
+        if (view)
+        {
+            auto window = [view window];
+            auto bounds = ToNSRect(_peer->GetBoundingRectangle());
+            auto windowBounds = [view convertRect:bounds toView:nil];
+            auto screenBounds = [window convertRectToScreen:windowBounds];
+            result = screenBounds;
+        }
+    }
+
+    return result;
+}
+
+- (id)accessibilityParent
+{
+    auto parentPeer = _peer->GetParent();
+    return parentPeer ? [AvnAccessibilityElement acquire:parentPeer] : [NSApplication sharedApplication];
+}
+
+- (id)accessibilityTopLevelUIElement
+{
+    auto rootPeer = _peer->GetRootPeer();
+    return [AvnAccessibilityElement acquire:rootPeer];
+}
+
+- (id)accessibilityWindow
+{
+    id topLevel = [self accessibilityTopLevelUIElement];
+    return [topLevel isKindOfClass:[NSWindow class]] ? topLevel : nil;
+}
+
+- (BOOL)isAccessibilityExpanded
+{
+    if (!_peer->IsExpandCollapseProvider())
+        return NO;
+    return _peer->ExpandCollapseProvider_GetIsExpanded();
+}
+
+- (void)setAccessibilityExpanded:(BOOL)accessibilityExpanded
+{
+    if (!_peer->IsExpandCollapseProvider())
+        return;
+    if (accessibilityExpanded)
+        _peer->ExpandCollapseProvider_Expand();
+    else
+        _peer->ExpandCollapseProvider_Collapse();
+}
+
+- (BOOL)accessibilityPerformPress
+{
+    if (_peer->IsInvokeProvider())
+    {
+        _peer->InvokeProvider_Invoke();
+    }
+    else if (_peer->IsExpandCollapseProvider())
+    {
+        _peer->ExpandCollapseProvider_Expand();
+    }
+    else if (_peer->IsToggleProvider())
+    {
+        _peer->ToggleProvider_Toggle();
+    }
+    return YES;
+}
+
+- (BOOL)accessibilityPerformIncrement
+{
+    if (!_peer->IsRangeValueProvider())
+        return NO;
+    auto value = _peer->RangeValueProvider_GetValue();
+    value += _peer->RangeValueProvider_GetSmallChange();
+    _peer->RangeValueProvider_SetValue(value);
+    return YES;
+}
+
+- (BOOL)accessibilityPerformDecrement
+{
+    if (!_peer->IsRangeValueProvider())
+        return NO;
+    auto value = _peer->RangeValueProvider_GetValue();
+    value -= _peer->RangeValueProvider_GetSmallChange();
+    _peer->RangeValueProvider_SetValue(value);
+    return YES;
+}
+
+- (BOOL)accessibilityPerformShowMenu
+{
+    if (!_peer->IsExpandCollapseProvider())
+        return NO;
+    _peer->ExpandCollapseProvider_Expand();
+    return YES;
+}
+
+- (BOOL)isAccessibilitySelected
+{
+    if (_peer->IsSelectionItemProvider())
+        return _peer->SelectionItemProvider_IsSelected();
+    return NO;
+}
+
+- (BOOL)isAccessibilitySelectorAllowed:(SEL)selector
+{
+    if (selector == @selector(accessibilityPerformShowMenu))
+    {
+        return _peer->IsExpandCollapseProvider() && _peer->ExpandCollapseProvider_GetShowsMenu();
+    }
+    else if (selector == @selector(isAccessibilityExpanded))
+    {
+        return _peer->IsExpandCollapseProvider();
+    }
+    else if (selector == @selector(accessibilityPerformPress))
+    {
+        return _peer->IsInvokeProvider() || _peer->IsExpandCollapseProvider() || _peer->IsToggleProvider();
+    }
+    else if (selector == @selector(accessibilityPerformIncrement) ||
+             selector == @selector(accessibilityPerformDecrement) ||
+             selector == @selector(accessibilityMinValue) ||
+             selector == @selector(accessibilityMaxValue))
+    {
+        return _peer->IsRangeValueProvider();
+    }
+    
+    return [super isAccessibilitySelectorAllowed:selector];
+}
+
+- (void)raiseChildrenChanged
+{
+    auto changed = _children ? [NSMutableSet setWithArray:_children] : [NSMutableSet set];
+
+    [self recalculateChildren];
+    
+    if (_children)
+        [changed addObjectsFromArray:_children];
+
+    NSAccessibilityPostNotificationWithUserInfo(
+        self,
+        NSAccessibilityLayoutChangedNotification,
+        @{ NSAccessibilityUIElementsKey: [changed allObjects]});
+}
+
+- (void)raisePropertyChanged
+{
+}
+
+- (void)setAccessibilityFocused:(BOOL)accessibilityFocused
+{
+    if (accessibilityFocused)
+        _peer->SetFocus();
+}
+
+- (void)recalculateChildren
+{
+    auto childPeers = _peer->GetChildren();
+    auto childCount = childPeers != nullptr ? childPeers->GetCount() : 0;
+
+    if (childCount > 0)
+    {
+        _children = [[NSMutableArray alloc] initWithCapacity:childCount];
+        
+        for (int i = 0; i < childCount; ++i)
+        {
+            IAvnAutomationPeer* child;
+            
+            if (childPeers->Get(i, &child) == S_OK)
+            {
+                auto element = [AvnAccessibilityElement acquire:child];
+                [_children addObject:element];
+            }
+        }
+    }
+    else
+    {
+        _children = nil;
+    }
+}
+
+@end
+
+@implementation AvnRootAccessibilityElement
+{
+    AvnView* _owner;
+}
+
+- (AvnRootAccessibilityElement *)initWithPeer:(IAvnAutomationPeer *)peer owner:(AvnView *)owner
+{
+    self = [super initWithPeer:peer];
+    _owner = owner;
+
+    // Seems we need to raise a focus changed notification here if we have focus
+    auto focusedPeer = [self peer]->RootProvider_GetFocus();
+    id focused = [AvnAccessibilityElement acquire:focusedPeer];
+
+    if (focused)
+        NSAccessibilityPostNotification(focused, NSAccessibilityFocusedUIElementChangedNotification);
+    
+    return self;
+}
+
+- (AvnView *)ownerView
+{
+    return _owner;
+}
+
+- (id)accessibilityFocusedUIElement
+{
+    auto focusedPeer = [self peer]->RootProvider_GetFocus();
+    return [AvnAccessibilityElement acquire:focusedPeer];
+}
+
+- (id)accessibilityHitTest:(NSPoint)point
+{
+    auto clientPoint = [[_owner window] convertPointFromScreen:point];
+    auto localPoint = [_owner translateLocalPoint:ToAvnPoint(clientPoint)];
+    auto hit = [self peer]->RootProvider_GetPeerFromPoint(localPoint);
+    return [AvnAccessibilityElement acquire:hit];
+}
+
+- (id)accessibilityParent
+{
+    return _owner;
+}
+
+- (void)raiseFocusChanged
+{
+    id focused = [self accessibilityFocusedUIElement];
+    NSAccessibilityPostNotification(focused, NSAccessibilityFocusedUIElementChangedNotification);
+}
+
+// Although this method is marked as deprecated we get runtime warnings if we don't handle it.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+- (void)accessibilityPerformAction:(NSAccessibilityActionName)action
+{
+    [_owner accessibilityPerformAction:action];
+}
+#pragma clang diagnostic pop
+
+@end

+ 2 - 2
native/Avalonia.Native/src/OSX/common.h

@@ -27,7 +27,7 @@ extern IAvnMenuItem* CreateAppMenuItem();
 extern IAvnMenuItem* CreateAppMenuItemSeparator();
 extern IAvnApplicationCommands* CreateApplicationCommands();
 extern IAvnNativeControlHost* CreateNativeControlHost(NSView* parent);
-extern void SetAppMenu (NSString* appName, IAvnMenu* appMenu);
+extern void SetAppMenu(IAvnMenu *menu);
 extern void SetServicesMenu (IAvnMenu* menu);
 extern IAvnMenu* GetAppMenu ();
 extern NSMenuItem* GetAppMenuItem ();
@@ -35,9 +35,9 @@ extern NSMenuItem* GetAppMenuItem ();
 extern void InitializeAvnApp(IAvnApplicationEvents* events);
 extern NSApplicationActivationPolicy AvnDesiredActivationPolicy;
 extern NSPoint ToNSPoint (AvnPoint p);
+extern NSRect ToNSRect (AvnRect r);
 extern AvnPoint ToAvnPoint (NSPoint p);
 extern AvnPoint ConvertPointY (AvnPoint p);
-extern CGFloat PrimaryDisplayHeight();
 extern NSSize ToNSSize (AvnSize s);
 #ifdef DEBUG
 #define NSDebugLog(...) NSLog(__VA_ARGS__)

+ 3 - 0
native/Avalonia.Native/src/OSX/controlhost.mm

@@ -36,7 +36,10 @@ public:
     virtual void DestroyDefaultChild(void* child) override
     {
         // ARC will release the object for us
+        #pragma clang diagnostic push
+        #pragma clang diagnostic ignored "-Wunused-value"
         (__bridge_transfer NSView*) child;
+        #pragma clang diagnostic pop
     }
 };
 

+ 0 - 1
native/Avalonia.Native/src/OSX/cursor.mm

@@ -1,6 +1,5 @@
 #include "common.h"
 #include "cursor.h"
-#include <map>
 
 class CursorFactory : public ComSingleObject<IAvnCursorFactory, &IID_IAvnCursorFactory>
 {

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

@@ -335,14 +335,14 @@ public:
             return S_OK;
         }
     }
-    
+        
     virtual HRESULT SetAppMenu (IAvnMenu* appMenu) override
     {
         START_COM_CALL;
         
         @autoreleasepool
         {
-            ::SetAppMenu(s_appTitle, appMenu);
+            ::SetAppMenu(appMenu);
             return S_OK;
         }
     }
@@ -400,6 +400,15 @@ NSPoint ToNSPoint (AvnPoint p)
     return result;
 }
 
+NSRect ToNSRect (AvnRect r)
+{
+    return NSRect
+    {
+        NSPoint { r.X, r.Y },
+        NSSize { r.Width, r.Height }
+    };
+}
+
 AvnPoint ToAvnPoint (NSPoint p)
 {
     AvnPoint result;
@@ -418,7 +427,3 @@ AvnPoint ConvertPointY (AvnPoint p)
     return p;
 }
 
-CGFloat PrimaryDisplayHeight()
-{
-  return NSMaxY([[[NSScreen screens] firstObject] frame]);
-}

+ 0 - 1
native/Avalonia.Native/src/OSX/menu.h

@@ -31,7 +31,6 @@ private:
     NSMenuItem* _native; // here we hold a pointer to an AvnMenuItem
     IAvnActionCallback* _callback;
     IAvnPredicateCallback* _predicate;
-    bool _isSeparator;
     bool _isCheckable;
     
 public:

+ 2 - 4
native/Avalonia.Native/src/OSX/menu.mm

@@ -1,7 +1,6 @@
 
 #include "common.h"
 #include "menu.h"
-#include "window.h"
 #include "KeyTransform.h"
 #include <CoreFoundation/CoreFoundation.h>
 #include <Carbon/Carbon.h> /* For kVK_ constants, and TIS functions. */
@@ -74,8 +73,7 @@
 AvnAppMenuItem::AvnAppMenuItem(bool isSeparator)
 {
     _isCheckable = false;
-    _isSeparator = isSeparator;
-    
+
     if(isSeparator)
     {
         _native = [NSMenuItem separatorItem];
@@ -460,7 +458,7 @@ extern IAvnMenuItem* CreateAppMenuItemSeparator()
 static IAvnMenu* s_appMenu = nullptr;
 static NSMenuItem* s_appMenuItem = nullptr;
 
-extern void SetAppMenu (NSString* appName, IAvnMenu* menu)
+extern void SetAppMenu(IAvnMenu *menu)
 {
     s_appMenu = menu;
     

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

@@ -1,14 +1,10 @@
 #include "common.h"
 #include "rendertarget.h"
-#import <IOSurface/IOSurface.h>
 #import <IOSurface/IOSurfaceObjC.h>
 #import <QuartzCore/QuartzCore.h>
 
-#include <OpenGL/CGLIOSurface.h>
-#include <OpenGL/OpenGL.h>
 #include <OpenGL/glext.h>
 #include <OpenGL/gl3.h>
-#include <OpenGL/gl3ext.h>
 
 @interface IOSurfaceHolder : NSObject
 @end

+ 0 - 76
native/Avalonia.Native/src/OSX/window.h

@@ -1,76 +0,0 @@
-#ifndef window_h
-#define window_h
-
-class WindowBaseImpl;
-
-@interface AvnView : NSView<NSTextInputClient, NSDraggingDestination>
--(AvnView* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent;
--(NSEvent* _Nonnull) lastMouseDownEvent;
--(AvnPoint) translateLocalPoint:(AvnPoint)pt;
--(void) setSwRenderedFrame: (AvnFramebuffer* _Nonnull) fb dispose: (IUnknown* _Nonnull) dispose;
--(void) onClosed;
--(AvnPixelSize) getPixelSize;
--(AvnPlatformResizeReason) getResizeReason;
--(void) setResizeReason:(AvnPlatformResizeReason)reason;
-+ (AvnPoint)toAvnPoint:(CGPoint)p;
-@end
-
-@interface AutoFitContentView : NSView
--(AutoFitContentView* _Nonnull) initWithContent: (NSView* _Nonnull) content;
--(void) ShowTitleBar: (bool) show;
--(void) SetTitleBarHeightHint: (double) height;
--(void) SetContent: (NSView* _Nonnull) content;
--(void) ShowBlur: (bool) show;
-@end
-
-@interface AvnWindow : NSWindow <NSWindowDelegate>
-+(void) closeAll;
--(AvnWindow* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent;
--(void) setCanBecomeKeyAndMain;
--(void) pollModalSession: (NSModalSession _Nonnull) session;
--(void) restoreParentWindow;
--(bool) shouldTryToHandleEvents;
--(void) setEnabled: (bool) enable;
--(void) showAppMenuOnly;
--(void) showWindowMenuWithAppMenu;
--(void) applyMenu:(NSMenu* _Nullable)menu;
--(double) getScaling;
--(double) getExtendedTitleBarHeight;
--(void) setIsExtended:(bool)value;
--(bool) isDialog;
-@end
-
-struct INSWindowHolder
-{
-    virtual AvnWindow* _Nonnull GetNSWindow () = 0;
-};
-
-struct IWindowStateChanged
-{
-    virtual void WindowStateChanged () = 0;
-    virtual void StartStateTransition () = 0;
-    virtual void EndStateTransition () = 0;
-    virtual SystemDecorations Decorations () = 0;
-    virtual AvnWindowState WindowState () = 0;
-};
-
-class ResizeScope
-{
-public:
-    ResizeScope(AvnView* _Nonnull view, AvnPlatformResizeReason reason)
-    {
-        _view = view;
-        _restore = [view getResizeReason];
-        [view setResizeReason:reason];
-    }
-    
-    ~ResizeScope()
-    {
-        [_view setResizeReason:_restore];
-    }
-private:
-    AvnView* _Nonnull _view;
-    AvnPlatformResizeReason _restore;
-};
-
-#endif /* window_h */

+ 0 - 2529
native/Avalonia.Native/src/OSX/window.mm

@@ -1,2529 +0,0 @@
-#include "common.h"
-#include "window.h"
-#include "KeyTransform.h"
-#include "cursor.h"
-#include "menu.h"
-#include <OpenGL/gl.h>
-#include "rendertarget.h"
-
-class WindowBaseImpl : public virtual ComSingleObject<IAvnWindowBase, &IID_IAvnWindowBase>, public INSWindowHolder
-{
-private:
-    NSCursor* cursor;
-
-public:
-    FORWARD_IUNKNOWN()
-    virtual ~WindowBaseImpl()
-    {
-        View = NULL;
-        Window = NULL;
-    }
-    AutoFitContentView* StandardContainer;
-    AvnView* View;
-    AvnWindow* Window;
-    ComPtr<IAvnWindowBaseEvents> BaseEvents;
-    ComPtr<IAvnGlContext> _glContext;
-    NSObject<IRenderTarget>* renderTarget;
-    AvnPoint lastPositionSet;
-    NSString* _lastTitle;
-    IAvnMenu* _mainMenu;
-    
-    bool _shown;
-    bool _inResize;
-    
-    WindowBaseImpl(IAvnWindowBaseEvents* events, IAvnGlContext* gl)
-    {
-        _shown = false;
-        _inResize = false;
-        _mainMenu = nullptr;
-        BaseEvents = events;
-        _glContext = gl;
-        renderTarget = [[IOSurfaceRenderTarget alloc] initWithOpenGlContext: gl];
-        View = [[AvnView alloc] initWithParent:this];
-        StandardContainer = [[AutoFitContentView new] initWithContent:View];
-
-        Window = [[AvnWindow alloc] initWithParent:this];
-        [Window setContentView: StandardContainer];
-        
-        lastPositionSet.X = 100;
-        lastPositionSet.Y = 100;
-        _lastTitle = @"";
-        
-        [Window setStyleMask:NSWindowStyleMaskBorderless];
-        [Window setBackingType:NSBackingStoreBuffered];
-        
-        [Window setOpaque:false];
-    }
-    
-    virtual HRESULT ObtainNSWindowHandle(void** ret) override
-    {
-        START_COM_CALL;
-        
-        if (ret == nullptr)
-        {
-            return E_POINTER;
-        }
-        
-        *ret =  (__bridge void*)Window;
-        
-        return S_OK;
-    }
-    
-    virtual HRESULT ObtainNSWindowHandleRetained(void** ret) override
-    {
-        START_COM_CALL;
-        
-        if (ret == nullptr)
-        {
-            return E_POINTER;
-        }
-        
-        *ret =  (__bridge_retained void*)Window;
-        
-        return S_OK;
-    }
-    
-    virtual HRESULT ObtainNSViewHandle(void** ret) override
-    {
-        START_COM_CALL;
-        
-        if (ret == nullptr)
-        {
-            return E_POINTER;
-        }
-        
-        *ret =  (__bridge void*)View;
-        
-        return S_OK;
-    }
-    
-    virtual HRESULT ObtainNSViewHandleRetained(void** ret) override
-    {
-        START_COM_CALL;
-        
-        if (ret == nullptr)
-        {
-            return E_POINTER;
-        }
-        
-        *ret =  (__bridge_retained void*)View;
-        
-        return S_OK;
-    }
-    
-    virtual AvnWindow* GetNSWindow() override
-    {
-        return Window;
-    }
-    
-    virtual HRESULT Show(bool activate, bool isDialog) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            SetPosition(lastPositionSet);
-            UpdateStyle();
-            
-            [Window setTitle:_lastTitle];
-            
-            if(ShouldTakeFocusOnShow() && activate)
-            {
-                [Window orderFront: Window];
-                [Window makeKeyAndOrderFront:Window];
-                [Window makeFirstResponder:View];
-                [NSApp activateIgnoringOtherApps:YES];
-            }
-            else
-            {
-                [Window orderFront: Window];
-            }
-            
-            _shown = true;
-            
-            return S_OK;
-        }
-    }
-    
-    virtual bool ShouldTakeFocusOnShow()
-    {
-        return true;
-    }
-    
-    virtual HRESULT Hide () override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if(Window != nullptr)
-            {
-                [Window orderOut:Window];
-                [Window restoreParentWindow];
-            }
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT Activate () override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if(Window != nullptr)
-            {
-                [Window makeKeyAndOrderFront:nil];
-                [NSApp activateIgnoringOtherApps:YES];
-            }
-        }
-        
-        return S_OK;
-    }
-    
-    virtual HRESULT SetTopMost (bool value) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            [Window setLevel: value ? NSFloatingWindowLevel : NSNormalWindowLevel];
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT Close() override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if (Window != nullptr)
-            {
-                auto window = Window;
-                Window = nullptr;
-                
-                try{
-                    // Seems to throw sometimes on application exit.
-                    [window close];
-                }
-                catch(NSException*){}
-            }
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT GetClientSize(AvnSize* ret) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if(ret == nullptr)
-                return E_POINTER;
-            
-            auto frame = [View frame];
-            ret->Width = frame.size.width;
-            ret->Height = frame.size.height;
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT GetFrameSize(AvnSize* ret) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if(ret == nullptr)
-                return E_POINTER;
-            
-            auto frame = [Window frame];
-            ret->Width = frame.size.width;
-            ret->Height = frame.size.height;
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT GetScaling (double* ret) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if(ret == nullptr)
-                return E_POINTER;
-            
-            if(Window == nullptr)
-            {
-                *ret = 1;
-                return S_OK;
-            }
-            
-            *ret = [Window backingScaleFactor];
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT SetMinMaxSize (AvnSize minSize, AvnSize maxSize) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            [Window setMinSize: ToNSSize(minSize)];
-            [Window setMaxSize: ToNSSize(maxSize)];
-        
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT Resize(double x, double y, AvnPlatformResizeReason reason) override
-    {
-        if(_inResize)
-        {
-            return S_OK;
-        }
-        
-        _inResize = true;
-        
-        START_COM_CALL;
-        auto resizeBlock = ResizeScope(View, reason);
-        
-        @autoreleasepool
-        {
-            auto maxSize = [Window maxSize];
-            auto minSize = [Window minSize];
-            
-            if (x < minSize.width)
-            {
-                x = minSize.width;
-            }
-            
-            if (y < minSize.height)
-            {
-                y = minSize.height;
-            }
-            
-            if (x > maxSize.width)
-            {
-                x = maxSize.width;
-            }
-            
-            if (y > maxSize.height)
-            {
-                y = maxSize.height;
-            }
-            
-            @try
-            {
-                if(!_shown)
-                {
-                    BaseEvents->Resized(AvnSize{x,y}, reason);
-                }
-                
-                [Window setContentSize:NSSize{x,y}];
-                [Window invalidateShadow];
-            }
-            @finally
-            {
-                _inResize = false;
-            }
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT Invalidate (AvnRect rect) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            [View setNeedsDisplayInRect:[View frame]];
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT SetMainMenu(IAvnMenu* menu) override
-    {
-        START_COM_CALL;
-        
-        _mainMenu = menu;
-        
-        auto nativeMenu = dynamic_cast<AvnAppMenu*>(menu);
-        
-        auto nsmenu = nativeMenu->GetNative();
-        
-        [Window applyMenu:nsmenu];
-        
-        if ([Window isKeyWindow])
-        {
-            [Window showWindowMenuWithAppMenu];
-        }
-        
-        return S_OK;
-    }
-    
-    virtual HRESULT BeginMoveDrag () override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            auto lastEvent = [View lastMouseDownEvent];
-            
-            if(lastEvent == nullptr)
-            {
-                return S_OK;
-            }
-            
-            [Window performWindowDragWithEvent:lastEvent];
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT BeginResizeDrag (AvnWindowEdge edge) override
-    {
-        START_COM_CALL;
-        
-        return S_OK;
-    }
-    
-    virtual HRESULT GetPosition (AvnPoint* ret) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if(ret == nullptr)
-            {
-                return E_POINTER;
-            }
-            
-            auto frame = [Window frame];
-            
-            ret->X = frame.origin.x;
-            ret->Y = frame.origin.y + frame.size.height;
-            
-            *ret = ConvertPointY(*ret);
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT SetPosition (AvnPoint point) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            lastPositionSet = point;
-            [Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(point))];
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT PointToClient (AvnPoint point, AvnPoint* ret) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if(ret == nullptr)
-            {
-                return E_POINTER;
-            }
-            
-            point = ConvertPointY(point);
-            auto viewPoint = [Window convertScreenToBase:ToNSPoint(point)];
-            
-            *ret = [View translateLocalPoint:ToAvnPoint(viewPoint)];
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT PointToScreen (AvnPoint point, AvnPoint* ret) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if(ret == nullptr)
-            {
-                return E_POINTER;
-            }
-            
-            auto cocoaViewPoint =  ToNSPoint([View translateLocalPoint:point]);
-            auto cocoaScreenPoint = [Window convertBaseToScreen:cocoaViewPoint];
-            *ret = ConvertPointY(ToAvnPoint(cocoaScreenPoint));
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT ThreadSafeSetSwRenderedFrame(AvnFramebuffer* fb, IUnknown* dispose) override
-    {
-        START_COM_CALL;
-        
-        [View setSwRenderedFrame: fb dispose: dispose];
-        return S_OK;
-    }
-    
-    virtual HRESULT SetCursor(IAvnCursor* cursor) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            Cursor* avnCursor = dynamic_cast<Cursor*>(cursor);
-            this->cursor = avnCursor->GetNative();
-            UpdateCursor();
-            
-            if(avnCursor->IsHidden())
-            {
-                [NSCursor hide];
-            }
-            else
-            {
-                [NSCursor unhide];
-            }
-            
-            return S_OK;
-        }
-    }
-
-    virtual void UpdateCursor()
-    {
-        if (cursor != nil)
-        {
-            [cursor set];
-        }
-    }
-    
-    virtual HRESULT CreateGlRenderTarget(IAvnGlSurfaceRenderTarget** ppv) override
-    {
-        START_COM_CALL;
-        
-        if(View == NULL)
-            return E_FAIL;
-        *ppv = [renderTarget createSurfaceRenderTarget];
-        return *ppv == nil ? E_FAIL : S_OK;
-    }
-    
-    virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost** retOut) override
-    {
-        START_COM_CALL;
-        
-        if(View == NULL)
-            return E_FAIL;
-        *retOut = ::CreateNativeControlHost(View);
-        return S_OK;
-    }
-    
-    virtual HRESULT SetBlurEnabled (bool enable) override
-    {
-        START_COM_CALL;
-        
-        [StandardContainer ShowBlur:enable];
-        
-        return S_OK;
-    }
-    
-    virtual HRESULT BeginDragAndDropOperation(AvnDragDropEffects effects, AvnPoint point,
-                                              IAvnClipboard* clipboard, IAvnDndResultCallback* cb,
-                                              void* sourceHandle) override
-    {
-        START_COM_CALL;
-        
-        auto item = TryGetPasteboardItem(clipboard);
-        [item setString:@"" forType:GetAvnCustomDataType()];
-        if(item == nil)
-            return E_INVALIDARG;
-        if(View == NULL)
-            return E_FAIL;
-        
-        auto nsevent = [NSApp currentEvent];
-        auto nseventType = [nsevent type];
-        
-        // If current event isn't a mouse one (probably due to malfunctioning user app)
-        // attempt to forge a new one
-        if(!((nseventType >= NSEventTypeLeftMouseDown && nseventType <= NSEventTypeMouseExited)
-           || (nseventType >= NSEventTypeOtherMouseDown && nseventType <= NSEventTypeOtherMouseDragged)))
-        {
-            auto nspoint = [Window convertBaseToScreen: ToNSPoint(point)];
-            CGPoint cgpoint = NSPointToCGPoint(nspoint);
-            auto cgevent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, cgpoint, kCGMouseButtonLeft);
-            nsevent = [NSEvent eventWithCGEvent: cgevent];
-            CFRelease(cgevent);
-        }
-        
-        auto dragItem = [[NSDraggingItem alloc] initWithPasteboardWriter: item];
-        
-        auto dragItemImage = [NSImage imageNamed:NSImageNameMultipleDocuments];
-        NSRect dragItemRect = {(float)point.X, (float)point.Y, [dragItemImage size].width, [dragItemImage size].height};
-        [dragItem setDraggingFrame: dragItemRect contents: dragItemImage];
-        
-        int op = 0; int ieffects = (int)effects;
-        if((ieffects & (int)AvnDragDropEffects::Copy) != 0)
-            op |= NSDragOperationCopy;
-        if((ieffects & (int)AvnDragDropEffects::Link) != 0)
-            op |= NSDragOperationLink;
-        if((ieffects & (int)AvnDragDropEffects::Move) != 0)
-            op |= NSDragOperationMove;
-        [View beginDraggingSessionWithItems: @[dragItem] event: nsevent
-                                     source: CreateDraggingSource((NSDragOperation) op, cb, sourceHandle)];
-        return S_OK;
-    }
-
-    virtual bool IsDialog()
-    {
-        return false;
-    }
-    
-protected:
-    virtual NSWindowStyleMask GetStyle()
-    {
-        return NSWindowStyleMaskBorderless;
-    }
-    
-    void UpdateStyle()
-    {
-        [Window setStyleMask: GetStyle()];
-    }
-    
-public:
-    virtual void OnResized ()
-    {
-        
-    }
-};
-
-class WindowImpl : public virtual WindowBaseImpl, public virtual IAvnWindow, public IWindowStateChanged
-{
-private:
-    bool _canResize;
-    bool _fullScreenActive;
-    SystemDecorations _decorations;
-    AvnWindowState _lastWindowState;
-    AvnWindowState _actualWindowState;
-    bool _inSetWindowState;
-    NSRect _preZoomSize;
-    bool _transitioningWindowState;
-    bool _isClientAreaExtended;
-    bool _isDialog;
-    AvnExtendClientAreaChromeHints _extendClientHints;
-    
-    FORWARD_IUNKNOWN()
-    BEGIN_INTERFACE_MAP()
-    INHERIT_INTERFACE_MAP(WindowBaseImpl)
-    INTERFACE_MAP_ENTRY(IAvnWindow, IID_IAvnWindow)
-    END_INTERFACE_MAP()
-    virtual ~WindowImpl()
-    {
-    }
-    
-    ComPtr<IAvnWindowEvents> WindowEvents;
-    WindowImpl(IAvnWindowEvents* events, IAvnGlContext* gl) : WindowBaseImpl(events, gl)
-    {
-        _isClientAreaExtended = false;
-        _extendClientHints = AvnDefaultChrome;
-        _fullScreenActive = false;
-        _canResize = true;
-        _decorations = SystemDecorationsFull;
-        _transitioningWindowState = false;
-        _inSetWindowState = false;
-        _lastWindowState = Normal;
-        _actualWindowState = Normal;
-        WindowEvents = events;
-        [Window setCanBecomeKeyAndMain];
-        [Window disableCursorRects];
-        [Window setTabbingMode:NSWindowTabbingModeDisallowed];
-        [Window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
-    }
-    
-    void HideOrShowTrafficLights ()
-    {
-        if (Window == nil)
-        {
-            return;
-        }
-        
-        for (id subview in Window.contentView.superview.subviews) {
-            if ([subview isKindOfClass:NSClassFromString(@"NSTitlebarContainerView")]) {
-                NSView *titlebarView = [subview subviews][0];
-                for (id button in titlebarView.subviews) {
-                    if ([button isKindOfClass:[NSButton class]])
-                    {
-                        if(_isClientAreaExtended)
-                        {
-                            auto wantsChrome = (_extendClientHints & AvnSystemChrome) || (_extendClientHints & AvnPreferSystemChrome);
-                            
-                            [button setHidden: !wantsChrome];
-                        }
-                        else
-                        {
-                            [button setHidden: (_decorations != SystemDecorationsFull)];
-                        }
-                        
-                        [button setWantsLayer:true];
-                    }
-                }
-            }
-        }
-    }
-    
-    virtual HRESULT Show (bool activate, bool isDialog) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            _isDialog = isDialog;
-            WindowBaseImpl::Show(activate, isDialog);
-            
-            HideOrShowTrafficLights();
-            
-            return SetWindowState(_lastWindowState);
-        }
-    }
-    
-    virtual HRESULT SetEnabled (bool enable) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            [Window setEnabled:enable];
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT SetParent (IAvnWindow* parent) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if(parent == nullptr)
-                return E_POINTER;
-
-            auto cparent = dynamic_cast<WindowImpl*>(parent);
-            if(cparent == nullptr)
-                return E_INVALIDARG;
-            
-            // If one tries to show a child window with a minimized parent window, then the parent window will be
-            // restored but MacOS isn't kind enough to *tell* us that, so the window will be left in a non-interactive
-            // state. Detect this and explicitly restore the parent window ourselves to avoid this situation.
-            if (cparent->WindowState() == Minimized)
-                cparent->SetWindowState(Normal);
-            
-            [Window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
-            [cparent->Window addChildWindow:Window ordered:NSWindowAbove];
-            
-            UpdateStyle();
-            
-            return S_OK;
-        }
-    }
-    
-    void StartStateTransition () override
-    {
-        _transitioningWindowState = true;
-    }
-    
-    void EndStateTransition () override
-    {
-        _transitioningWindowState = false;
-    }
-    
-    SystemDecorations Decorations () override
-    {
-        return _decorations;
-    }
-    
-    AvnWindowState WindowState () override
-    {
-        return _lastWindowState;
-    }
-    
-    void WindowStateChanged () override
-    {
-        if(_shown && !_inSetWindowState && !_transitioningWindowState)
-        {
-            AvnWindowState state;
-            GetWindowState(&state);
-            
-            if(_lastWindowState != state)
-            {
-                if(_isClientAreaExtended)
-                {
-                    if(_lastWindowState == FullScreen)
-                    {
-                        // we exited fs.
-                       if(_extendClientHints & AvnOSXThickTitleBar)
-                       {
-                          Window.toolbar = [NSToolbar new];
-                          Window.toolbar.showsBaselineSeparator = false;
-                       }
-
-                       [Window setTitlebarAppearsTransparent:true];
-
-                       [StandardContainer setFrameSize: StandardContainer.frame.size];
-                    }
-                    else if(state == FullScreen)
-                    {
-                        // we entered fs.
-                        if(_extendClientHints & AvnOSXThickTitleBar)
-                        {
-                            Window.toolbar = nullptr;
-                        }
-                       
-                        [Window setTitlebarAppearsTransparent:false];
-                        
-                        [StandardContainer setFrameSize: StandardContainer.frame.size];
-                    }
-                }
-                
-                _lastWindowState = state;
-                _actualWindowState = state;
-                WindowEvents->WindowStateChanged(state);
-            }
-        }
-    }
-    
-    bool UndecoratedIsMaximized ()
-    {
-        auto windowSize = [Window frame];
-        auto available = [Window screen].visibleFrame;
-        return CGRectEqualToRect(windowSize, available);
-    }
-    
-    bool IsZoomed ()
-    {
-        return _decorations == SystemDecorationsFull ? [Window isZoomed] : UndecoratedIsMaximized();
-    }
-    
-    void DoZoom()
-    {
-        switch (_decorations)
-        {
-            case SystemDecorationsNone:
-            case SystemDecorationsBorderOnly:
-                [Window setFrame:[Window screen].visibleFrame display:true];
-                break;
-
-            
-            case SystemDecorationsFull:
-                [Window performZoom:Window];
-                break;
-        }
-    }
-    
-    virtual HRESULT SetCanResize(bool value) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            _canResize = value;
-            UpdateStyle();
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT SetDecorations(SystemDecorations value) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            auto currentWindowState = _lastWindowState;
-            _decorations = value;
-            
-            if(_fullScreenActive)
-            {
-                return S_OK;
-            }
-            
-            UpdateStyle();
-            
-            HideOrShowTrafficLights();
-
-            switch (_decorations)
-            {
-                case SystemDecorationsNone:
-                    [Window setHasShadow:NO];
-                    [Window setTitleVisibility:NSWindowTitleHidden];
-                    [Window setTitlebarAppearsTransparent:YES];
-                    
-                    if(currentWindowState == Maximized)
-                    {
-                        if(!UndecoratedIsMaximized())
-                        {
-                            DoZoom();
-                        }
-                    }
-                    break;
-
-                case SystemDecorationsBorderOnly:
-                    [Window setHasShadow:YES];
-                    [Window setTitleVisibility:NSWindowTitleHidden];
-                    [Window setTitlebarAppearsTransparent:YES];
-                    
-                    if(currentWindowState == Maximized)
-                    {
-                        if(!UndecoratedIsMaximized())
-                        {
-                            DoZoom();
-                        }
-                    }
-                    break;
-
-                case SystemDecorationsFull:
-                    [Window setHasShadow:YES];
-                    [Window setTitleVisibility:NSWindowTitleVisible];
-                    [Window setTitlebarAppearsTransparent:NO];
-                    [Window setTitle:_lastTitle];
-                    
-                    if(currentWindowState == Maximized)
-                    {
-                        auto newFrame = [Window contentRectForFrameRect:[Window frame]].size;
-                        
-                        [View setFrameSize:newFrame];
-                    }
-                    break;
-            }
-
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT SetTitle (char* utf8title) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            _lastTitle = [NSString stringWithUTF8String:(const char*)utf8title];
-            [Window setTitle:_lastTitle];
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT SetTitleBarColor(AvnColor color) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            float a = (float)color.Alpha / 255.0f;
-            float r = (float)color.Red / 255.0f;
-            float g = (float)color.Green / 255.0f;
-            float b = (float)color.Blue / 255.0f;
-            
-            auto nscolor = [NSColor colorWithSRGBRed:r green:g blue:b alpha:a];
-            
-            // Based on the titlebar color we have to choose either light or dark
-            // OSX doesnt let you set a foreground color for titlebar.
-            if ((r*0.299 + g*0.587 + b*0.114) > 186.0f / 255.0f)
-            {
-                [Window setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantLight]];
-            }
-            else
-            {
-                [Window setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]];
-            }
-            
-            [Window setTitlebarAppearsTransparent:true];
-            [Window setBackgroundColor:nscolor];
-        }
-        
-        return S_OK;
-    }
-    
-    virtual HRESULT GetWindowState (AvnWindowState*ret) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if(ret == nullptr)
-            {
-                return E_POINTER;
-            }
-            
-            if(([Window styleMask] & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen)
-            {
-                *ret = FullScreen;
-                return S_OK;
-            }
-            
-            if([Window isMiniaturized])
-            {
-                *ret = Minimized;
-                return S_OK;
-            }
-            
-            if(IsZoomed())
-            {
-                *ret = Maximized;
-                return S_OK;
-            }
-            
-            *ret = Normal;
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT TakeFocusFromChildren () override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if(Window == nil)
-                return S_OK;
-            if([Window isKeyWindow])
-                [Window makeFirstResponder: View];
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT SetExtendClientArea (bool enable) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            _isClientAreaExtended = enable;
-            
-            if(enable)
-            {
-                Window.titleVisibility = NSWindowTitleHidden;
-                
-                [Window setTitlebarAppearsTransparent:true];
-                
-                auto wantsTitleBar = (_extendClientHints & AvnSystemChrome) || (_extendClientHints & AvnPreferSystemChrome);
-                
-                if (wantsTitleBar)
-                {
-                    [StandardContainer ShowTitleBar:true];
-                }
-                else
-                {
-                    [StandardContainer ShowTitleBar:false];
-                }
-                
-                if(_extendClientHints & AvnOSXThickTitleBar)
-                {
-                    Window.toolbar = [NSToolbar new];
-                    Window.toolbar.showsBaselineSeparator = false;
-                }
-                else
-                {
-                    Window.toolbar = nullptr;
-                }
-            }
-            else
-            {
-                Window.titleVisibility = NSWindowTitleVisible;
-                Window.toolbar = nullptr;
-                [Window setTitlebarAppearsTransparent:false];
-                View.layer.zPosition = 0;
-            }
-            
-            [Window setIsExtended:enable];
-            
-            HideOrShowTrafficLights();
-            
-            UpdateStyle();
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT SetExtendClientAreaHints (AvnExtendClientAreaChromeHints hints) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            _extendClientHints = hints;
-            
-            SetExtendClientArea(_isClientAreaExtended);
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT GetExtendTitleBarHeight (double*ret) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if(ret == nullptr)
-            {
-                return E_POINTER;
-            }
-            
-            *ret = [Window getExtendedTitleBarHeight];
-            
-            return S_OK;
-        }
-    }
-    
-    virtual HRESULT SetExtendTitleBarHeight (double value) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            [StandardContainer SetTitleBarHeightHint:value];
-            return S_OK;
-        }
-    }
-    
-    void EnterFullScreenMode ()
-    {
-        _fullScreenActive = true;
-        
-        [Window setTitle:_lastTitle];
-        [Window toggleFullScreen:nullptr];
-    }
-    
-    void ExitFullScreenMode ()
-    {
-        [Window toggleFullScreen:nullptr];
-        
-        _fullScreenActive = false;
-        
-        SetDecorations(_decorations);
-    }
-    
-    virtual HRESULT SetWindowState (AvnWindowState state) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if(Window == nullptr)
-            {
-                return  S_OK;
-            }
-            
-            if(_actualWindowState == state)
-            {
-                return S_OK;
-            }
-            
-            _inSetWindowState = true;
-            
-            auto currentState = _actualWindowState;
-            _lastWindowState = state;
-            
-            if(currentState == Normal)
-            {
-                _preZoomSize = [Window frame];
-            }
-            
-            if(_shown)
-            {
-                switch (state) {
-                    case Maximized:
-                        if(currentState == FullScreen)
-                        {
-                            ExitFullScreenMode();
-                        }
-                        
-                        lastPositionSet.X = 0;
-                        lastPositionSet.Y = 0;
-                        
-                        if([Window isMiniaturized])
-                        {
-                            [Window deminiaturize:Window];
-                        }
-                        
-                        if(!IsZoomed())
-                        {
-                            DoZoom();
-                        }
-                        break;
-                        
-                    case Minimized:
-                        if(currentState == FullScreen)
-                        {
-                            ExitFullScreenMode();
-                        }
-                        else
-                        {
-                            [Window miniaturize:Window];
-                        }
-                        break;
-                        
-                    case FullScreen:
-                        if([Window isMiniaturized])
-                        {
-                            [Window deminiaturize:Window];
-                        }
-                        
-                        EnterFullScreenMode();
-                        break;
-                        
-                    case Normal:
-                        if([Window isMiniaturized])
-                        {
-                            [Window deminiaturize:Window];
-                        }
-                        
-                        if(currentState == FullScreen)
-                        {
-                            ExitFullScreenMode();
-                        }
-                        
-                        if(IsZoomed())
-                        {
-                            if(_decorations == SystemDecorationsFull)
-                            {
-                                DoZoom();
-                            }
-                            else
-                            {
-                                [Window setFrame:_preZoomSize display:true];
-                                auto newFrame = [Window contentRectForFrameRect:[Window frame]].size;
-                                
-                                [View setFrameSize:newFrame];
-                            }
-                            
-                        }
-                        break;
-                }
-                
-                _actualWindowState = _lastWindowState;
-                WindowEvents->WindowStateChanged(_actualWindowState);
-            }
-            
-            
-            _inSetWindowState = false;
-            
-            return S_OK;
-        }
-    }
-
-    virtual void OnResized () override
-    {
-        if(_shown && !_inSetWindowState && !_transitioningWindowState)
-        {
-            WindowStateChanged();
-        }
-    }
-    
-    virtual bool IsDialog() override
-    {
-        return _isDialog;
-    }
-    
-protected:
-    virtual NSWindowStyleMask GetStyle() override
-    {
-        unsigned long s = NSWindowStyleMaskBorderless;
-
-        switch (_decorations)
-        {
-            case SystemDecorationsNone:
-                s = s | NSWindowStyleMaskFullSizeContentView;
-                break;
-
-            case SystemDecorationsBorderOnly:
-                s = s | NSWindowStyleMaskTitled | NSWindowStyleMaskFullSizeContentView;
-                break;
-
-            case SystemDecorationsFull:
-                s = s | NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskBorderless;
-                
-                if(_canResize)
-                {
-                    s = s | NSWindowStyleMaskResizable;
-                }
-                break;
-        }
-
-        if([Window parentWindow] == nullptr)
-        {
-            s |= NSWindowStyleMaskMiniaturizable;
-        }
-        
-        if(_isClientAreaExtended)
-        {
-            s |= NSWindowStyleMaskFullSizeContentView | NSWindowStyleMaskTexturedBackground;
-        }
-        return s;
-    }
-};
-
-NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode, NSRunLoopCommonModes, NSConnectionReplyMode, nil];
-
-@implementation AutoFitContentView
-{
-    NSVisualEffectView* _titleBarMaterial;
-    NSBox* _titleBarUnderline;
-    NSView* _content;
-    NSVisualEffectView* _blurBehind;
-    double _titleBarHeightHint;
-    bool _settingSize;
-}
-
--(AutoFitContentView* _Nonnull) initWithContent:(NSView *)content
-{
-    _titleBarHeightHint = -1;
-    _content = content;
-    _settingSize = false;
-
-    [self setAutoresizesSubviews:true];
-    [self setWantsLayer:true];
-    
-    _titleBarMaterial = [NSVisualEffectView new];
-    [_titleBarMaterial setBlendingMode:NSVisualEffectBlendingModeWithinWindow];
-    [_titleBarMaterial setMaterial:NSVisualEffectMaterialTitlebar];
-    [_titleBarMaterial setWantsLayer:true];
-    _titleBarMaterial.hidden = true;
-    
-    _titleBarUnderline = [NSBox new];
-    _titleBarUnderline.boxType = NSBoxSeparator;
-    _titleBarUnderline.fillColor = [NSColor underPageBackgroundColor];
-    _titleBarUnderline.hidden = true;
-    
-    [self addSubview:_titleBarMaterial];
-    [self addSubview:_titleBarUnderline];
-    
-    _blurBehind = [NSVisualEffectView new];
-    [_blurBehind setBlendingMode:NSVisualEffectBlendingModeBehindWindow];
-    [_blurBehind setMaterial:NSVisualEffectMaterialLight];
-    [_blurBehind setWantsLayer:true];
-    _blurBehind.hidden = true;
-    
-    [_blurBehind setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
-    [_content setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
-    
-    [self addSubview:_blurBehind];
-    [self addSubview:_content];
-    
-    [self setWantsLayer:true];
-    return self;
-}
-
--(void) ShowBlur:(bool)show
-{
-    _blurBehind.hidden = !show;
-}
-
--(void) ShowTitleBar: (bool) show
-{
-    _titleBarMaterial.hidden = !show;
-    _titleBarUnderline.hidden = !show;
-}
-
--(void) SetTitleBarHeightHint: (double) height
-{
-    _titleBarHeightHint = height;
-    
-    [self setFrameSize:self.frame.size];
-}
-
--(void)setFrameSize:(NSSize)newSize
-{
-    if(_settingSize)
-    {
-        return;
-    }
-    
-    _settingSize = true;
-    [super setFrameSize:newSize];
-    
-    auto window = objc_cast<AvnWindow>([self window]);
-    
-    // TODO get actual titlebar size
-    
-    double height = _titleBarHeightHint == -1 ? [window getExtendedTitleBarHeight] : _titleBarHeightHint;
-    
-    NSRect tbar;
-    tbar.origin.x = 0;
-    tbar.origin.y = newSize.height - height;
-    tbar.size.width = newSize.width;
-    tbar.size.height = height;
-    
-    [_titleBarMaterial setFrame:tbar];
-    tbar.size.height = height < 1 ? 0 : 1;
-    [_titleBarUnderline setFrame:tbar];
-
-    _settingSize = false;
-}
-
--(void) SetContent: (NSView* _Nonnull) content
-{
-    if(content != nullptr)
-    {
-        [content removeFromSuperview];
-        [self addSubview:content];
-        _content = content;
-    }
-}
-@end
-
-@implementation AvnView
-{
-    ComPtr<WindowBaseImpl> _parent;
-    ComPtr<IUnknown> _swRenderedFrame;
-    AvnFramebuffer _swRenderedFrameBuffer;
-    bool _queuedDisplayFromThread;
-    NSTrackingArea* _area;
-    bool _isLeftPressed, _isMiddlePressed, _isRightPressed, _isXButton1Pressed, _isXButton2Pressed, _isMouseOver;
-    AvnInputModifiers _modifierState;
-    NSEvent* _lastMouseDownEvent;
-    bool _lastKeyHandled;
-    AvnPixelSize _lastPixelSize;
-    NSObject<IRenderTarget>* _renderTarget;
-    AvnPlatformResizeReason _resizeReason;
-}
-
-- (void)onClosed
-{
-    @synchronized (self)
-    {
-        _parent = nullptr;
-    }
-}
-
--(AvnPixelSize) getPixelSize
-{
-    return _lastPixelSize;
-}
-
-- (NSEvent*) lastMouseDownEvent
-{
-    return _lastMouseDownEvent;
-}
-
-- (void) updateRenderTarget
-{
-    [_renderTarget resize:_lastPixelSize withScale: [[self window] backingScaleFactor]];
-    [self setNeedsDisplayInRect:[self frame]];
-}
-
--(AvnView*)  initWithParent: (WindowBaseImpl*) parent
-{
-    self = [super init];
-    _renderTarget = parent->renderTarget;
-    [self setWantsLayer:YES];
-    [self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize];
-    
-    _parent = parent;
-    _area = nullptr;
-    _lastPixelSize.Height = 100;
-    _lastPixelSize.Width = 100;
-    [self registerForDraggedTypes: @[@"public.data", GetAvnCustomDataType()]];
-    
-    _modifierState = AvnInputModifiersNone;
-    return self;
-}
-
-- (BOOL)isFlipped
-{
-    return YES;
-}
-
-- (BOOL)wantsUpdateLayer
-{
-    return YES;
-}
-
-- (void)setLayer:(CALayer *)layer
-{
-    [_renderTarget setNewLayer: layer];
-    [super setLayer: layer];
-}
-
-- (BOOL)isOpaque
-{
-    return YES;
-}
-
-- (BOOL)acceptsFirstResponder
-{
-    return true;
-}
-
-- (BOOL)acceptsFirstMouse:(NSEvent *)event
-{
-    return true;
-}
-
-- (BOOL)canBecomeKeyView
-{
-    return true;
-}
-
--(void)setFrameSize:(NSSize)newSize
-{
-    [super setFrameSize:newSize];
-    
-    if(_area != nullptr)
-    {
-        [self removeTrackingArea:_area];
-        _area = nullptr;
-    }
-
-    if (_parent == nullptr)
-    {
-        return;
-    }
-
-    NSRect rect = NSZeroRect;
-    rect.size = newSize;
-    
-    NSTrackingAreaOptions options = NSTrackingActiveAlways | NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingEnabledDuringMouseDrag;
-    _area = [[NSTrackingArea alloc] initWithRect:rect options:options owner:self userInfo:nullptr];
-    [self addTrackingArea:_area];
-    
-    _parent->UpdateCursor();
-    
-    auto fsize = [self convertSizeToBacking: [self frame].size];
-    
-    if(_lastPixelSize.Width != (int)fsize.width || _lastPixelSize.Height != (int)fsize.height)
-    {
-        _lastPixelSize.Width = (int)fsize.width;
-        _lastPixelSize.Height = (int)fsize.height;
-        [self updateRenderTarget];
-    
-        auto reason = [self inLiveResize] ? ResizeUser : _resizeReason;
-        _parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height}, reason);
-    }
-}
-
-- (void)updateLayer
-{
-    AvnInsidePotentialDeadlock deadlock;
-    if (_parent == nullptr)
-    {
-        return;
-    }
-    
-    _parent->BaseEvents->RunRenderPriorityJobs();
-    
-    if (_parent == nullptr)
-    {
-        return;
-    }
-        
-    _parent->BaseEvents->Paint();
-}
-
-- (void)drawRect:(NSRect)dirtyRect
-{
-    return;
-}
-
--(void) setSwRenderedFrame: (AvnFramebuffer*) fb dispose: (IUnknown*) dispose
-{
-    @autoreleasepool {
-        [_renderTarget setSwFrame:fb];
-        dispose->Release();
-    }
-}
-
-- (AvnPoint) translateLocalPoint:(AvnPoint)pt
-{
-    pt.Y = [self bounds].size.height - pt.Y;
-    return pt;
-}
-
-+ (AvnPoint)toAvnPoint:(CGPoint)p
-{
-    AvnPoint result;
-    
-    result.X = p.x;
-    result.Y = p.y;
-    
-    return result;
-}
-
-- (void) viewDidChangeBackingProperties
-{
-    auto fsize = [self convertSizeToBacking: [self frame].size];
-    _lastPixelSize.Width = (int)fsize.width;
-    _lastPixelSize.Height = (int)fsize.height;
-    [self updateRenderTarget];
-    
-    if(_parent != nullptr)
-    {
-        _parent->BaseEvents->ScalingChanged([_parent->Window backingScaleFactor]);
-    }
-    
-    [super viewDidChangeBackingProperties];
-}
-
-- (bool) ignoreUserInput:(bool)trigerInputWhenDisabled
-{
-    auto parentWindow = objc_cast<AvnWindow>([self window]);
-    
-    if(parentWindow == nil || ![parentWindow shouldTryToHandleEvents])
-    {
-        if(trigerInputWhenDisabled)
-        {
-            auto window = dynamic_cast<WindowImpl*>(_parent.getRaw());
-            
-            if(window != nullptr)
-            {
-                window->WindowEvents->GotInputWhenDisabled();
-            }
-        }
-        
-        return TRUE;
-    }
-    
-    return FALSE;
-}
-
-- (void)mouseEvent:(NSEvent *)event withType:(AvnRawMouseEventType) type
-{
-    bool triggerInputWhenDisabled = type != Move;
-    
-    if([self ignoreUserInput: triggerInputWhenDisabled])
-    {
-        return;
-    }
-    
-    auto localPoint = [self convertPoint:[event locationInWindow] toView:self];
-    auto avnPoint = [AvnView toAvnPoint:localPoint];
-    auto point = [self translateLocalPoint:avnPoint];
-    AvnVector delta;
-    
-    if(type == Wheel)
-    {
-        auto speed = 5;
-        
-        if([event hasPreciseScrollingDeltas])
-        {
-            speed = 50;
-        }
-        
-        delta.X = [event scrollingDeltaX] / speed;
-        delta.Y = [event scrollingDeltaY] / speed;
-        
-        if(delta.X == 0 && delta.Y == 0)
-        {
-            return;
-        }
-    }
-    else if (type == Magnify)
-    {
-        delta.X = delta.Y = [event magnification];
-    }
-    else if (type == Rotate)
-    {
-        delta.X = delta.Y = [event rotation];
-    }
-    else if (type == Swipe)
-    {
-        delta.X = [event deltaX];
-        delta.Y = [event deltaY];
-    }
-    
-    auto timestamp = [event timestamp] * 1000;
-    auto modifiers = [self getModifiers:[event modifierFlags]];
-    
-    if(type != AvnRawMouseEventType::Move ||
-       (
-           [self window] != nil &&
-           (
-                [[self window] firstResponder] == nil
-                || ![[[self window] firstResponder] isKindOfClass: [NSView class]]
-           )
-       )
-    )
-        [self becomeFirstResponder];
-    
-    if(_parent != nullptr)
-    {
-        _parent->BaseEvents->RawMouseEvent(type, timestamp, modifiers, point, delta);
-    }
-    
-    [super mouseMoved:event];
-}
-
-- (BOOL) resignFirstResponder
-{
-    _parent->BaseEvents->LostFocus();
-    return YES;
-}
-
-- (void)mouseMoved:(NSEvent *)event
-{
-    [self mouseEvent:event withType:Move];
-}
-
-- (void)mouseDown:(NSEvent *)event
-{
-    _isLeftPressed = true;
-    _lastMouseDownEvent = event;
-    [self mouseEvent:event withType:LeftButtonDown];
-}
-
-- (void)otherMouseDown:(NSEvent *)event
-{
-    _lastMouseDownEvent = event;
-
-    switch(event.buttonNumber)
-    {
-        case 2:
-        case 3:
-            _isMiddlePressed = true;
-            [self mouseEvent:event withType:MiddleButtonDown];
-            break;
-        case 4:
-            _isXButton1Pressed = true;
-            [self mouseEvent:event withType:XButton1Down];
-            break;
-        case 5:
-            _isXButton2Pressed = true;
-            [self mouseEvent:event withType:XButton2Down];
-            break;
-    }
-}
-
-- (void)rightMouseDown:(NSEvent *)event
-{
-    _isRightPressed = true;
-    _lastMouseDownEvent = event;
-    [self mouseEvent:event withType:RightButtonDown];
-}
-
-- (void)mouseUp:(NSEvent *)event
-{
-    _isLeftPressed = false;
-    [self mouseEvent:event withType:LeftButtonUp];
-}
-
-- (void)otherMouseUp:(NSEvent *)event
-{
-    switch(event.buttonNumber)
-    {
-        case 2:
-        case 3:
-            _isMiddlePressed = false;
-            [self mouseEvent:event withType:MiddleButtonUp];
-            break;
-        case 4:
-            _isXButton1Pressed = false;
-            [self mouseEvent:event withType:XButton1Up];
-            break;
-        case 5:
-            _isXButton2Pressed = false;
-            [self mouseEvent:event withType:XButton2Up];
-            break;
-    }
-}
-
-- (void)rightMouseUp:(NSEvent *)event
-{
-    _isRightPressed = false;
-    [self mouseEvent:event withType:RightButtonUp];
-}
-
-- (void)mouseDragged:(NSEvent *)event
-{
-    [self mouseEvent:event withType:Move];
-    [super mouseDragged:event];
-}
-
-- (void)otherMouseDragged:(NSEvent *)event
-{
-    [self mouseEvent:event withType:Move];
-    [super otherMouseDragged:event];
-}
-
-- (void)rightMouseDragged:(NSEvent *)event
-{
-    [self mouseEvent:event withType:Move];
-    [super rightMouseDragged:event];
-}
-
-- (void)scrollWheel:(NSEvent *)event
-{
-    [self mouseEvent:event withType:Wheel];
-    [super scrollWheel:event];
-}
-
-- (void)magnifyWithEvent:(NSEvent *)event
-{
-    [self mouseEvent:event withType:Magnify];
-    [super magnifyWithEvent:event];
-}
-
-- (void)rotateWithEvent:(NSEvent *)event
-{
-    [self mouseEvent:event withType:Rotate];
-    [super rotateWithEvent:event];
-}
-
-- (void)swipeWithEvent:(NSEvent *)event
-{
-    [self mouseEvent:event withType:Swipe];
-    [super swipeWithEvent:event];
-}
-
-- (void)mouseEntered:(NSEvent *)event
-{
-    _isMouseOver = true;
-    [super mouseEntered:event];
-}
-
-- (void)mouseExited:(NSEvent *)event
-{
-    _isMouseOver = false;
-    [self mouseEvent:event withType:LeaveWindow];
-    [super mouseExited:event];
-} 
-
-- (void) keyboardEvent: (NSEvent *) event withType: (AvnRawKeyEventType)type
-{
-    if([self ignoreUserInput: false])
-    {
-        return;
-    }
-    
-    auto key = s_KeyMap[[event keyCode]];
-    
-    auto timestamp = [event timestamp] * 1000;
-    auto modifiers = [self getModifiers:[event modifierFlags]];
-     
-    if(_parent != nullptr)
-    {
-        _lastKeyHandled = _parent->BaseEvents->RawKeyEvent(type, timestamp, modifiers, key);
-    }
-}
-
-- (BOOL)performKeyEquivalent:(NSEvent *)event
-{
-    bool result = _lastKeyHandled;
-    
-    _lastKeyHandled = false;
-    
-    return result;
-}
-
-- (void)flagsChanged:(NSEvent *)event
-{
-    auto newModifierState = [self getModifiers:[event modifierFlags]];
-    
-    bool isAltCurrentlyPressed = (_modifierState & Alt) == Alt;
-    bool isControlCurrentlyPressed = (_modifierState & Control) == Control;
-    bool isShiftCurrentlyPressed = (_modifierState & Shift) == Shift;
-    bool isCommandCurrentlyPressed = (_modifierState & Windows) == Windows;
-    
-    bool isAltPressed = (newModifierState & Alt) == Alt;
-    bool isControlPressed = (newModifierState & Control) == Control;
-    bool isShiftPressed = (newModifierState & Shift) == Shift;
-    bool isCommandPressed = (newModifierState & Windows) == Windows;
-    
-    
-    if (isAltPressed && !isAltCurrentlyPressed)
-    {
-        [self keyboardEvent:event withType:KeyDown];
-    }
-    else if (isAltCurrentlyPressed && !isAltPressed)
-    {
-        [self keyboardEvent:event withType:KeyUp];
-    }
-    
-    if (isControlPressed && !isControlCurrentlyPressed)
-    {
-        [self keyboardEvent:event withType:KeyDown];
-    }
-    else if (isControlCurrentlyPressed && !isControlPressed)
-    {
-        [self keyboardEvent:event withType:KeyUp];
-    }
-    
-    if (isShiftPressed && !isShiftCurrentlyPressed)
-    {
-        [self keyboardEvent:event withType:KeyDown];
-    }
-    else if(isShiftCurrentlyPressed && !isShiftPressed)
-    {
-        [self keyboardEvent:event withType:KeyUp];
-    }
-    
-    if(isCommandPressed && !isCommandCurrentlyPressed)
-    {
-        [self keyboardEvent:event withType:KeyDown];
-    }
-    else if(isCommandCurrentlyPressed && ! isCommandPressed)
-    {
-        [self keyboardEvent:event withType:KeyUp];
-    }
-    
-    _modifierState = newModifierState;
-    
-    [[self inputContext] handleEvent:event];
-    [super flagsChanged:event];
-}
-
-- (void)keyDown:(NSEvent *)event
-{
-    [self keyboardEvent:event withType:KeyDown];
-    [[self inputContext] handleEvent:event];
-    [super keyDown:event];
-}
-
-- (void)keyUp:(NSEvent *)event
-{
-    [self keyboardEvent:event withType:KeyUp];
-    [super keyUp:event];
-}
-
-- (AvnInputModifiers)getModifiers:(NSEventModifierFlags)mod
-{
-    unsigned int rv = 0;
-    
-    if (mod & NSEventModifierFlagControl)
-        rv |= Control;
-    if (mod & NSEventModifierFlagShift)
-        rv |= Shift;
-    if (mod & NSEventModifierFlagOption)
-        rv |= Alt;
-    if (mod & NSEventModifierFlagCommand)
-        rv |= Windows;
-    
-    if (_isLeftPressed)
-        rv |= LeftMouseButton;
-    if (_isMiddlePressed)
-        rv |= MiddleMouseButton;
-    if (_isRightPressed)
-        rv |= RightMouseButton;
-    if (_isXButton1Pressed)
-        rv |= XButton1MouseButton;
-    if (_isXButton2Pressed)
-        rv |= XButton2MouseButton;
-    
-    return (AvnInputModifiers)rv;
-}
-
-- (BOOL)hasMarkedText
-{
-    return _lastKeyHandled;
-}
-
-- (NSRange)markedRange
-{
-    return NSMakeRange(NSNotFound, 0);
-}
-
-- (NSRange)selectedRange
-{
-    return NSMakeRange(NSNotFound, 0);
-}
-
-- (void)setMarkedText:(id)string selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
-{
-    
-}
-
-- (void)unmarkText
-{
-    
-}
-
-- (NSArray<NSString *> *)validAttributesForMarkedText
-{
-    return [NSArray new];
-}
-
-- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)range actualRange:(NSRangePointer)actualRange
-{
-    return [NSAttributedString new];
-}
-
-- (void)insertText:(id)string replacementRange:(NSRange)replacementRange
-{
-    if(!_lastKeyHandled)
-    {
-        if(_parent != nullptr)
-        {
-            _lastKeyHandled = _parent->BaseEvents->RawTextInputEvent(0, [string UTF8String]);
-        }
-    }
-}
-
-- (NSUInteger)characterIndexForPoint:(NSPoint)point
-{
-    return 0;
-}
-
-- (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(NSRangePointer)actualRange
-{
-    CGRect result;
-    
-    return result;
-}
-
-- (NSDragOperation)triggerAvnDragEvent: (AvnDragEventType) type info: (id <NSDraggingInfo>)info
-{
-    auto localPoint = [self convertPoint:[info draggingLocation] toView:self];
-    auto avnPoint = [AvnView toAvnPoint:localPoint];
-    auto point = [self translateLocalPoint:avnPoint];
-    auto modifiers = [self getModifiers:[[NSApp currentEvent] modifierFlags]];
-    NSDragOperation nsop = [info draggingSourceOperationMask];
-   
-        auto effects = ConvertDragDropEffects(nsop);
-    int reffects = (int)_parent->BaseEvents
-    ->DragEvent(type, point, modifiers, effects,
-                CreateClipboard([info draggingPasteboard], nil),
-                GetAvnDataObjectHandleFromDraggingInfo(info));
-    
-    NSDragOperation ret = 0;
-    
-    // Ensure that the managed part didn't add any new effects
-    reffects = (int)effects & (int)reffects;
-    
-    // OSX requires exactly one operation
-    if((reffects & (int)AvnDragDropEffects::Copy) != 0)
-        ret = NSDragOperationCopy;
-    else if((reffects & (int)AvnDragDropEffects::Move) != 0)
-        ret = NSDragOperationMove;
-    else if((reffects & (int)AvnDragDropEffects::Link) != 0)
-        ret = NSDragOperationLink;
-    if(ret == 0)
-        ret = NSDragOperationNone;
-    return ret;
-}
-
-- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
-{
-    return [self triggerAvnDragEvent: AvnDragEventType::Enter info:sender];
-}
-
-- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
-{
-    return [self triggerAvnDragEvent: AvnDragEventType::Over info:sender];
-}
-
-- (void)draggingExited:(id <NSDraggingInfo>)sender
-{
-    [self triggerAvnDragEvent: AvnDragEventType::Leave info:sender];
-}
-
-- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
-{
-    return [self triggerAvnDragEvent: AvnDragEventType::Over info:sender] != NSDragOperationNone;
-}
-
-- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
-{
-    return [self triggerAvnDragEvent: AvnDragEventType::Drop info:sender] != NSDragOperationNone;
-}
-
-- (void)concludeDragOperation:(nullable id <NSDraggingInfo>)sender
-{
-    
-}
-
-- (AvnPlatformResizeReason)getResizeReason
-{
-    return _resizeReason;
-}
-
-- (void)setResizeReason:(AvnPlatformResizeReason)reason
-{
-    _resizeReason = reason;
-}
-
-@end
-
-
-@implementation AvnWindow
-{
-    ComPtr<WindowBaseImpl> _parent;
-    bool _canBecomeKeyAndMain;
-    bool _closed;
-    bool _isEnabled;
-    bool _isExtended;
-    AvnMenu* _menu;
-    double _lastScaling;
-}
-
--(void) setIsExtended:(bool)value;
-{
-    _isExtended = value;
-}
-
--(bool) isDialog
-{
-    return _parent->IsDialog();
-}
-
--(double) getScaling
-{
-    return _lastScaling;
-}
-
--(double) getExtendedTitleBarHeight
-{
-    if(_isExtended)
-    {
-        for (id subview in self.contentView.superview.subviews)
-        {
-            if ([subview isKindOfClass:NSClassFromString(@"NSTitlebarContainerView")])
-            {
-                NSView *titlebarView = [subview subviews][0];
-
-                return (double)titlebarView.frame.size.height;
-            }
-        }
-
-        return -1;
-    }
-    else
-    {
-        return 0;
-    }
-}
-
-+(void)closeAll
-{
-    [[NSApplication sharedApplication] terminate:self];
-}
-
-- (void)performClose:(id)sender
-{
-    if([[self delegate] respondsToSelector:@selector(windowShouldClose:)])
-    {
-        if(![[self delegate] windowShouldClose:self]) return;
-    }
-    else if([self respondsToSelector:@selector(windowShouldClose:)])
-    {
-        if(![self windowShouldClose:self]) return;
-    }
-
-    [self close];
-}
-
-- (void)pollModalSession:(nonnull NSModalSession)session
-{
-    auto response = [NSApp runModalSession:session];
-    
-    if(response == NSModalResponseContinue)
-    {
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [self pollModalSession:session];
-        });
-    }
-    else if (!_closed)
-    {
-        [self orderOut:self];
-        [NSApp endModalSession:session];
-    }
-}
-
--(void) showWindowMenuWithAppMenu
-{
-    if(_menu != nullptr)
-    {
-        auto appMenuItem = ::GetAppMenuItem();
-        
-        if(appMenuItem != nullptr)
-        {
-            auto appMenu = [appMenuItem menu];
-            
-            [appMenu removeItem:appMenuItem];
-            
-            [_menu insertItem:appMenuItem atIndex:0];
-            
-            [_menu setHasGlobalMenuItem:true];
-        }
-        
-        [NSApp setMenu:_menu];
-    }
-    else
-    {
-        [self showAppMenuOnly];
-    }
-}
-
--(void) showAppMenuOnly
-{
-    auto appMenuItem = ::GetAppMenuItem();
-    
-    if(appMenuItem != nullptr)
-    {
-        auto appMenu = ::GetAppMenu();
-        
-        auto nativeAppMenu = dynamic_cast<AvnAppMenu*>(appMenu);
-        
-        [[appMenuItem menu] removeItem:appMenuItem];
-        
-        if(_menu != nullptr)
-        {
-            [_menu setHasGlobalMenuItem:false];
-        }
-        
-        [nativeAppMenu->GetNative() addItem:appMenuItem];
-        
-        [NSApp setMenu:nativeAppMenu->GetNative()];
-    }
-    else
-    {
-        [NSApp setMenu:nullptr];
-    }
-}
-
--(void) applyMenu:(AvnMenu *)menu
-{
-    if(menu == nullptr)
-    {
-        menu = [AvnMenu new];
-    }
-    
-    _menu = menu;
-}
-
--(void) setCanBecomeKeyAndMain
-{
-    _canBecomeKeyAndMain = true;
-}
-
--(AvnWindow*)  initWithParent: (WindowBaseImpl*) parent
-{
-    self = [super init];
-    [self setReleasedWhenClosed:false];
-    _parent = parent;
-    [self setDelegate:self];
-    _closed = false;
-    _isEnabled = true;
-    
-    _lastScaling = [self backingScaleFactor];
-    [self setOpaque:NO];
-    [self setBackgroundColor: [NSColor clearColor]];
-    _isExtended = false;
-    return self;
-}
-
-- (BOOL)windowShouldClose:(NSWindow *)sender
-{
-    auto window = dynamic_cast<WindowImpl*>(_parent.getRaw());
-    
-    if(window != nullptr)
-    {
-        return !window->WindowEvents->Closing();
-    }
-    
-    return true;
-}
-
-- (void)windowDidChangeBackingProperties:(NSNotification *)notification
-{
-    _lastScaling = [self backingScaleFactor];
-}
-
-- (void)windowWillClose:(NSNotification *)notification
-{
-    _closed = true;
-    if(_parent)
-    {
-        ComPtr<WindowBaseImpl> parent = _parent;
-        _parent = NULL;
-        [self restoreParentWindow];
-        parent->BaseEvents->Closed();
-        [parent->View onClosed];
-    }
-}
-
--(BOOL)canBecomeKeyWindow
-{
-    if (_canBecomeKeyAndMain)
-    {
-        // If the window has a child window being shown as a dialog then don't allow it to become the key window.
-        for(NSWindow* uch in [self childWindows])
-        {
-            auto ch = objc_cast<AvnWindow>(uch);
-            if(ch == nil)
-                continue;
-            if (ch.isDialog)
-                return false;
-        }
-        
-        return true;
-    }
-    
-    return false;
-}
-
--(BOOL)canBecomeMainWindow
-{
-    return _canBecomeKeyAndMain;
-}
-
--(bool)shouldTryToHandleEvents
-{
-    return _isEnabled;
-}
-
--(void) setEnabled:(bool)enable
-{
-    _isEnabled = enable;
-}
-
--(void)becomeKeyWindow
-{
-    [self showWindowMenuWithAppMenu];
-    
-    if(_parent != nullptr)
-    {
-        _parent->BaseEvents->Activated();
-    }
-
-    [super becomeKeyWindow];
-}
-
--(void) restoreParentWindow;
-{
-    auto parent = objc_cast<AvnWindow>([self parentWindow]);
-    if(parent != nil)
-    {
-        [parent removeChildWindow:self];
-    }
-}
-
-- (void)windowDidMiniaturize:(NSNotification *)notification
-{
-    auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
-    
-    if(parent != nullptr)
-    {
-        parent->WindowStateChanged();
-    }
-}
-
-- (void)windowDidDeminiaturize:(NSNotification *)notification
-{
-    auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
-    
-    if(parent != nullptr)
-    {
-        parent->WindowStateChanged();
-    }
-}
-
-- (void)windowDidResize:(NSNotification *)notification
-{
-    auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
-    
-    if(parent != nullptr)
-    {
-        parent->WindowStateChanged();
-    }
-}
-
-- (void)windowWillExitFullScreen:(NSNotification *)notification
-{
-    auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
-    
-    if(parent != nullptr)
-    {
-        parent->StartStateTransition();
-    }
-}
-
-- (void)windowDidExitFullScreen:(NSNotification *)notification
-{
-    auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
-    
-    if(parent != nullptr)
-    {
-        parent->EndStateTransition();
-        
-        if(parent->Decorations() != SystemDecorationsFull && parent->WindowState() == Maximized)
-        {
-            NSRect screenRect = [[self screen] visibleFrame];
-            [self setFrame:screenRect display:YES];
-        }
-        
-        if(parent->WindowState() == Minimized)
-        {
-            [self miniaturize:nullptr];
-        }
-        
-        parent->WindowStateChanged();
-    }
-}
-
-- (void)windowWillEnterFullScreen:(NSNotification *)notification
-{
-    auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
-    
-    if(parent != nullptr)
-    {
-        parent->StartStateTransition();
-    }
-}
-
-- (void)windowDidEnterFullScreen:(NSNotification *)notification
-{
-    auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
-    
-    if(parent != nullptr)
-    {
-        parent->EndStateTransition();
-        parent->WindowStateChanged();
-    }
-}
-
-- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame
-{
-    return true;
-}
-
--(void)resignKeyWindow
-{
-    if(_parent)
-        _parent->BaseEvents->Deactivated();
-    
-    [self showAppMenuOnly];
-    
-    [super resignKeyWindow];
-}
-
-- (void)windowDidMove:(NSNotification *)notification
-{
-    AvnPoint position;
-    
-    if(_parent != nullptr)
-    {
-        _parent->GetPosition(&position);
-        _parent->BaseEvents->PositionChanged(position);
-    }
-}
-
-- (AvnPoint) translateLocalPoint:(AvnPoint)pt
-{
-    pt.Y = [self frame].size.height - pt.Y;
-    return pt;
-}
-
-- (void)sendEvent:(NSEvent *)event
-{
-    [super sendEvent:event];
-    
-    /// This is to detect non-client clicks. This can only be done on Windows... not popups, hence the dynamic_cast.
-    if(_parent != nullptr && dynamic_cast<WindowImpl*>(_parent.getRaw()) != nullptr)
-    {
-        switch(event.type)
-        {
-            case NSEventTypeLeftMouseDown:
-            {
-                AvnView* view = _parent->View;
-                NSPoint windowPoint = [event locationInWindow];
-                NSPoint viewPoint = [view convertPoint:windowPoint fromView:nil];
-                
-                if (!NSPointInRect(viewPoint, view.bounds))
-                {
-                    auto avnPoint = [AvnView toAvnPoint:windowPoint];
-                    auto point = [self translateLocalPoint:avnPoint];
-                    AvnVector delta;
-                   
-                    _parent->BaseEvents->RawMouseEvent(NonClientLeftButtonDown, [event timestamp] * 1000, AvnInputModifiersNone, point, delta);
-                }
-            }
-            break;
-                
-            case NSEventTypeMouseEntered:
-            {
-                _parent->UpdateCursor();
-            }
-            break;
-                
-            case NSEventTypeMouseExited:
-            {
-                [[NSCursor arrowCursor] set];
-            }
-            break;
-                
-            default:
-                break;
-        }
-    }
-}
-@end
-
-class PopupImpl : public virtual WindowBaseImpl, public IAvnPopup
-{
-private:
-    BEGIN_INTERFACE_MAP()
-    INHERIT_INTERFACE_MAP(WindowBaseImpl)
-    INTERFACE_MAP_ENTRY(IAvnPopup, IID_IAvnPopup)
-    END_INTERFACE_MAP()
-    virtual ~PopupImpl(){}
-    ComPtr<IAvnWindowEvents> WindowEvents;
-    PopupImpl(IAvnWindowEvents* events, IAvnGlContext* gl) : WindowBaseImpl(events, gl)
-    {
-        WindowEvents = events;
-        [Window setLevel:NSPopUpMenuWindowLevel];
-    }
-protected:
-    virtual NSWindowStyleMask GetStyle() override
-    {
-        return NSWindowStyleMaskBorderless;
-    }
-    
-    virtual HRESULT Resize(double x, double y, AvnPlatformResizeReason reason) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if (Window != nullptr)
-            {
-                [Window setContentSize:NSSize{x, y}];
-            
-                [Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(lastPositionSet))];
-            }
-            
-            return S_OK;
-        }
-    }
-public:
-    virtual bool ShouldTakeFocusOnShow() override
-    {
-        return false;
-    }
-};
-
-extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events, IAvnGlContext* gl)
-{
-    @autoreleasepool
-    {
-        IAvnPopup* ptr = dynamic_cast<IAvnPopup*>(new PopupImpl(events, gl));
-        return ptr;
-    }
-}
-
-extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events, IAvnGlContext* gl)
-{
-    @autoreleasepool
-    {
-        IAvnWindow* ptr = (IAvnWindow*)new WindowImpl(events, gl);
-        return ptr;
-    }
-}

+ 1 - 6
nukebuild/Build.cs

@@ -214,19 +214,14 @@ partial class Build : NukeBuild
         .DependsOn(Compile)
         .Executes(() =>
         {
-            RunCoreTest("Avalonia.Animation.UnitTests");
             RunCoreTest("Avalonia.Base.UnitTests");
             RunCoreTest("Avalonia.Controls.UnitTests");
             RunCoreTest("Avalonia.Controls.DataGrid.UnitTests");
-            RunCoreTest("Avalonia.Input.UnitTests");
-            RunCoreTest("Avalonia.Interactivity.UnitTests");
-            RunCoreTest("Avalonia.Layout.UnitTests");
             RunCoreTest("Avalonia.Markup.UnitTests");
             RunCoreTest("Avalonia.Markup.Xaml.UnitTests");
-            RunCoreTest("Avalonia.Styling.UnitTests");
-            RunCoreTest("Avalonia.Visuals.UnitTests");
             RunCoreTest("Avalonia.Skia.UnitTests");
             RunCoreTest("Avalonia.ReactiveUI.UnitTests");
+            RunCoreTest("Avalonia.PlatformSupport.UnitTests");
         });
 
     Target RunRenderTests => _ => _

+ 1 - 2
nukebuild/_build.csproj

@@ -8,11 +8,10 @@
     <IsPackable>False</IsPackable>
     <NoWarn>CS0649;CS0169</NoWarn>
   </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="JetBrains.dotMemoryUnit" Version="3.0.20171219.105559" />
     <PackageReference Include="vswhere" Version="2.6.7" Condition=" '$(OS)' == 'Windows_NT' " />
     <PackageReference Include="ILRepack.NETStandard" Version="2.0.4" />
     <PackageReference Include="MicroCom.CodeGenerator" Version="0.10.4" />

+ 0 - 5
nukebuild/numerge.config

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

+ 3 - 1
packages/Avalonia/Avalonia.csproj

@@ -8,7 +8,9 @@
       <ProjectReference Include="../../src/Avalonia.Remote.Protocol/Avalonia.Remote.Protocol.csproj" />
       <ProjectReference Include="../../src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj" >
         <PrivateAssets>all</PrivateAssets>
-      </ProjectReference>  
+        <SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
+        <SetTargetFramework>TargetFramework=netstandard2.0</SetTargetFramework>
+      </ProjectReference>
   </ItemGroup>
 
   <PropertyGroup>

+ 2 - 2
readme.md

@@ -1,11 +1,11 @@
 [![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 />
-[![NuGet](https://img.shields.io/nuget/v/Avalonia.svg)](https://www.nuget.org/packages/Avalonia) [![downloads](https://img.shields.io/nuget/dt/avalonia)](https://www.nuget.org/packages/Avalonia) [![MyGet](https://img.shields.io/myget/avalonia-ci/vpre/Avalonia.svg?label=myget)](https://www.myget.org/gallery/avalonia-ci) ![Size](https://img.shields.io/github/repo-size/avaloniaui/avalonia.svg) 
+[![NuGet](https://img.shields.io/nuget/v/Avalonia.svg)](https://www.nuget.org/packages/Avalonia) [![downloads](https://img.shields.io/nuget/dt/avalonia)](https://www.nuget.org/packages/Avalonia)  ![Size](https://img.shields.io/github/repo-size/avaloniaui/avalonia.svg) 
 
 ## 📖 About 
 
-Avalonia is a cross-platform UI framework for dotnet, providing a flexible styling system and supporting a wide range of Operating Systems such as Windows, Linux, MacOs. Avalonia is mature and production ready. We also have in beta release support for iOS, Android and in early stages support for browser via WASM.
+Avalonia is a cross-platform UI framework for dotnet, providing a flexible styling system and supporting a wide range of Operating Systems such as Windows, Linux, macOS. Avalonia is mature and production ready. We also have in beta release support for iOS, Android and in early stages support for browser via WASM.
 
 ![image](https://user-images.githubusercontent.com/4672627/152126443-932966cf-57e7-4e77-9be6-62463a66b9f8.png)
 

+ 1 - 0
samples/BindingDemo/BindingDemo.csproj

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

+ 17 - 2
samples/ControlCatalog.Android/ControlCatalog.Android.csproj

@@ -23,10 +23,25 @@
     <DebugSymbols>True</DebugSymbols>
     <RunAOTCompilation>True</RunAOTCompilation>
     <EnableLLVM>True</EnableLLVM>
+    <AndroidEnableProfiledAot>True</AndroidEnableProfiledAot>
   </PropertyGroup>
-  
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <EmbedAssembliesIntoApk>False</EmbedAssembliesIntoApk>
+    <RunAOTCompilation>False</RunAOTCompilation>
+  </PropertyGroup>
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
+    <EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Xamarin.AndroidX.AppCompat" Version="1.3.1.3" />
+    <PackageReference Include="Xamarin.AndroidX.Lifecycle.ViewModel" Version="2.3.1.3" />
+  </ItemGroup>
+
   <ItemGroup>
     <ProjectReference Include="..\..\src\Android\Avalonia.Android\Avalonia.Android.csproj" />
     <ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" />
   </ItemGroup>
-</Project>
+</Project>

+ 5 - 8
samples/ControlCatalog.Android/MainActivity.cs

@@ -1,19 +1,16 @@
 using Android.App;
-using Android.OS;
 using Android.Content.PM;
+using Avalonia;
 using Avalonia.Android;
 
 namespace ControlCatalog.Android
 {
-    [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance)]
-    public class MainActivity : AvaloniaActivity
+    [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
+    public class MainActivity : AvaloniaActivity<App>
     {
-        protected override void OnCreate(Bundle? savedInstanceState)
+        protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
         {
-            base.OnCreate(savedInstanceState);
-
-            Content = new MainView();
+            return base.CustomizeAppBuilder(builder);
         }
     }
 }
-

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

@@ -4,7 +4,7 @@
   <style name="MyTheme">
   </style>
 
-  <style name="MyTheme.NoActionBar">
+  <style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.NoActionBar">
     <item name="android:windowActionBar">false</item>
     <item name="android:windowNoTitle">true</item>
   </style>

+ 0 - 10
samples/ControlCatalog.Android/SplashActivity.cs

@@ -1,9 +1,6 @@
 using Android.App;
 using Android.Content;
 using Android.OS;
-using Application = Android.App.Application;
-
-using Avalonia;
 
 namespace ControlCatalog.Android
 {
@@ -19,13 +16,6 @@ namespace ControlCatalog.Android
         {
             base.OnResume();
 
-            if (Avalonia.Application.Current == null)
-            {
-                AppBuilder.Configure<App>()
-                    .UseAndroid()
-                    .SetupWithoutStarting();
-            }
-
             StartActivity(new Intent(Application.Context, typeof(MainActivity)));
         }
     }

+ 14 - 0
samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj

@@ -6,7 +6,14 @@
     <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
   </PropertyGroup>
 
+  <PropertyGroup Condition="'$(RunNativeAotCompilation)' == 'true'">
+    <IlcTrimMetadata>true</IlcTrimMetadata>
+    <RestoreAdditionalProjectSources>https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json</RestoreAdditionalProjectSources>
+    <NativeAotCompilerVersion>7.0.0-*</NativeAotCompilerVersion>
+  </PropertyGroup>
+
   <ItemGroup>
+    <ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
     <ProjectReference Include="..\..\src\Avalonia.Headless.Vnc\Avalonia.Headless.Vnc.csproj" />
     <ProjectReference Include="..\..\src\Avalonia.Dialogs\Avalonia.Dialogs.csproj" />
     <ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" />
@@ -15,6 +22,13 @@
     <PackageReference Include="Avalonia.Angle.Windows.Natives" Version="2.1.0.2020091801" />
   </ItemGroup>
 
+  <ItemGroup Condition="'$(RunNativeAotCompilation)' == 'true'">
+    <PackageReference Include="Microsoft.DotNet.ILCompiler" Version="$(NativeAotCompilerVersion)" />
+    <!-- Cross-compilation for Windows x64-arm64 and Linux x64-arm64 -->
+    <PackageReference Condition="'$(RuntimeIdentifier)'=='win-arm64'" Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="$(NativeAotCompilerVersion)" />
+    <PackageReference Condition="'$(RuntimeIdentifier)'=='linux-arm64'" Include="runtime.linux-x64.Microsoft.DotNet.ILCompiler" Version="$(NativeAotCompilerVersion)" />
+  </ItemGroup>
+
   <PropertyGroup>
     <!-- For Microsoft.CodeAnalysis -->
     <SatelliteResourceLanguages>en</SatelliteResourceLanguages>

+ 7 - 1
samples/ControlCatalog.NetCore/Program.cs

@@ -117,7 +117,13 @@ namespace ControlCatalog.NetCore
                     EnableMultitouch = true
                 })
                 .UseSkia()
-                .UseManagedSystemDialogs()
+                .AfterSetup(builder =>
+                {
+                    builder.Instance!.AttachDevTools(new Avalonia.Diagnostics.DevToolsOptions()
+                    {
+                        StartupScreenIndex = 1,
+                    });
+                })
                 .LogToTrace();
 
         static void SilenceConsole()

+ 29 - 13
samples/ControlCatalog.Web/ControlCatalog.Web.csproj

@@ -1,15 +1,14 @@
 <Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
   <PropertyGroup>
     <TargetFramework>net6.0</TargetFramework>
-    <MSBuildEnableWorkloadResolver>false</MSBuildEnableWorkloadResolver>
     <Nullable>enable</Nullable>
-    <WasmBuildNative>True</WasmBuildNative>
+    <!--Temporal hack that fixes compilation in VS-->
+    <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
+    <EmccTotalMemory>16777216</EmccTotalMemory>
+    <BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport>
+    <BlazorWebAssemblyPreserveCollationData>false</BlazorWebAssemblyPreserveCollationData>
   </PropertyGroup>
 
-  <ItemGroup>
-    <BlazorLinkerDescriptor Include="LinkerConfig.xml" />
-  </ItemGroup>
-
   <!-- In debug, make builds faster by reducing optimizations -->
   <PropertyGroup Condition="'$(Configuration)' == 'Debug'">
     <WasmNativeStrip>false</WasmNativeStrip>
@@ -23,19 +22,36 @@
     <EmccCompileOptimizationFlag>-O3</EmccCompileOptimizationFlag>
     <EmccLinkOptimizationFlag>-O3</EmccLinkOptimizationFlag>
     <RunAOTCompilation>false</RunAOTCompilation>
+    <DebuggerSupport>false</DebuggerSupport>
+    <EnableUnsafeBinaryFormatterSerialization>false</EnableUnsafeBinaryFormatterSerialization>
+    <EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding>
+    <EventSourceSupport>false</EventSourceSupport>
+    <HttpActivityPropagationSupport>false</HttpActivityPropagationSupport>
+    <InvariantGlobalization>true</InvariantGlobalization>
+    <MetadataUpdaterSupport>false</MetadataUpdaterSupport>
+    <UseNativeHttpHandler>true</UseNativeHttpHandler>
+    <UseSystemResourceKeys>true</UseSystemResourceKeys>
+    <PublishTrimmed>true</PublishTrimmed>
+    <TrimMode>link</TrimMode>
+    <TrimmerRemoveSymbols>true</TrimmerRemoveSymbols>
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.0"/>
-    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.0" PrivateAssets="all"/>
+    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.0" />
+    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.0" PrivateAssets="all" />
   </ItemGroup>
 
-  <Import Project="..\..\src\Web\Avalonia.Web.Blazor\Avalonia.Web.Blazor.targets" />
-  <Import Project="..\..\src\Web\Avalonia.Web.Blazor\Avalonia.Web.Blazor.CompilationTuning.props" />
-
   <ItemGroup>
-    <ProjectReference Include="..\..\src\Web\Avalonia.Web.Blazor\Avalonia.Web.Blazor.csproj"/>
-    <ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj"/>
+    <ProjectReference Include="..\..\src\Skia\Avalonia.Skia\Avalonia.Skia.csproj" />
+    <ProjectReference Include="..\..\src\Web\Avalonia.Web.Blazor\Avalonia.Web.Blazor.csproj" />
+    <ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" />
   </ItemGroup>
 
+  <Import Project="..\..\build\ReferenceCoreLibraries.props" />
+  <Import Project="..\..\build\BuildTargets.targets" />
+
+  <Import Project="..\..\src\Web\Avalonia.Web.Blazor\Avalonia.Web.Blazor.targets" />
+  <Import Project="..\..\src\Web\Avalonia.Web.Blazor\Avalonia.Web.Blazor.CompilationTuning.props" />
+
 </Project>
+

+ 0 - 28
samples/ControlCatalog.Web/LinkerConfig.xml

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

+ 11 - 181
samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj

@@ -1,186 +1,16 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
-    <ProjectGuid>{57E0455D-D565-44BB-B069-EE1AA20F8337}</ProjectGuid>
-    <ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
     <OutputType>Exe</OutputType>
-    <RootNamespace>ControlCatalog.iOS</RootNamespace>
-    <IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
-    <AssemblyName>ControlCatalogiOS</AssemblyName>
-    <MtouchEnableSGenConc>true</MtouchEnableSGenConc>
-    <MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
-    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
-    <ProvisioningType>automatic</ProvisioningType>
+    <ProvisioningType>manual</ProvisioningType>
+    <TargetFramework>net6.0-ios</TargetFramework>
+    <SupportedOSPlatformVersion>10.0</SupportedOSPlatformVersion>
+    <!-- temporal workaround for our GL interface backend -->
+    <UseInterpreter>True</UseInterpreter>
+    <RuntimeIdentifier>iossimulator-x64</RuntimeIdentifier>
+    <!--    <RuntimeIdentifier>ios-arm64</RuntimeIdentifier>-->
   </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
-    <DefineConstants>DEBUG</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <ConsolePause>false</ConsolePause>
-    <MtouchArch>x86_64</MtouchArch>
-    <MtouchLink>None</MtouchLink>
-    <MtouchDebug>True</MtouchDebug>
-    <MtouchSdkVersion>9.1</MtouchSdkVersion>
-    <MtouchProfiling>False</MtouchProfiling>
-    <MtouchFastDev>False</MtouchFastDev>
-    <MtouchNoSymbolStrip>False</MtouchNoSymbolStrip>
-    <MtouchUseLlvm>False</MtouchUseLlvm>
-    <MtouchUseThumb>False</MtouchUseThumb>
-    <MtouchEnableBitcode>False</MtouchEnableBitcode>
-    <MtouchUseSGen>False</MtouchUseSGen>
-    <MtouchUseRefCounting>False</MtouchUseRefCounting>
-    <OptimizePNGs>True</OptimizePNGs>
-    <MtouchTlsProvider>Default</MtouchTlsProvider>
-    <MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler>
-    <MtouchFloat32>False</MtouchFloat32>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
-    <DebugType>none</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\iPhoneSimulator\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <MtouchLink>None</MtouchLink>
-    <MtouchArch>x86_64</MtouchArch>
-    <ConsolePause>false</ConsolePause>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\iPhone\Debug</OutputPath>
-    <DefineConstants>DEBUG</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <ConsolePause>false</ConsolePause>
-    <MtouchArch>ARMv7, ARM64</MtouchArch>
-    <CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
-    <CodesignKey>iPhone Developer</CodesignKey>
-    <MtouchDebug>true</MtouchDebug>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
-    <DebugType>none</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\iPhone\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
-    <MtouchArch>ARMv7, ARM64</MtouchArch>
-    <ConsolePause>false</ConsolePause>
-    <CodesignKey>iPhone Developer</CodesignKey>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone' ">
-    <DebugType>none</DebugType>
-    <Optimize>True</Optimize>
-    <OutputPath>bin\iPhone\Ad-Hoc</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <ConsolePause>False</ConsolePause>
-    <MtouchArch>ARMv7, ARM64</MtouchArch>
-    <CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
-    <BuildIpa>True</BuildIpa>
-    <CodesignProvision>Automatic:AdHoc</CodesignProvision>
-    <CodesignKey>iPhone Distribution</CodesignKey>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' ">
-    <DebugType>none</DebugType>
-    <Optimize>True</Optimize>
-    <OutputPath>bin\iPhone\AppStore</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <ConsolePause>False</ConsolePause>
-    <MtouchArch>ARMv7, ARM64</MtouchArch>
-    <CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
-    <CodesignProvision>Automatic:AppStore</CodesignProvision>
-    <CodesignKey>iPhone Distribution</CodesignKey>
-  </PropertyGroup>
-  <ItemGroup>
-    <Compile Include="Main.cs" />
-    <Compile Include="AppDelegate.cs" />
-    <None Include="Info.plist" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <InterfaceDefinition Include="Resources\LaunchScreen.xib" />
-    <Content Include="Entitlements.plist" />
-  </ItemGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Core" />
-    <Reference Include="Xamarin.iOS" />
-  </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\..\src\iOS\Avalonia.iOS\Avalonia.iOS.csproj">
-      <Project>{4488AD85-1495-4809-9AA4-DDFE0A48527E}</Project>
-      <Name>Avalonia.iOS</Name>
-      <IsAppExtension>false</IsAppExtension>
-      <IsWatchApp>false</IsWatchApp>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj">
-      <Project>{3E53A01A-B331-47F3-B828-4A5717E77A24}</Project>
-      <Name>Avalonia.Markup.Xaml</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Markup\Avalonia.Markup\Avalonia.Markup.csproj">
-      <Project>{6417E941-21BC-467B-A771-0DE389353CE6}</Project>
-      <Name>Avalonia.Markup</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj">
-      <Project>{D211E587-D8BC-45B9-95A4-F297C8FA5200}</Project>
-      <Name>Avalonia.Animation</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj">
-      <Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
-      <Name>Avalonia.Base</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Controls\Avalonia.Controls.csproj">
-      <Project>{D2221C82-4A25-4583-9B43-D791E3F6820C}</Project>
-      <Name>Avalonia.Controls</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj">
-      <Project>{7062AE20-5DCC-4442-9645-8195BDECE63E}</Project>
-      <Name>Avalonia.Diagnostics</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj">
-      <Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
-      <Name>Avalonia.Input</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Interactivity\Avalonia.Interactivity.csproj">
-      <Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
-      <Name>Avalonia.Interactivity</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Layout\Avalonia.Layout.csproj">
-      <Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
-      <Name>Avalonia.Layout</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Visuals\Avalonia.Visuals.csproj">
-      <Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
-      <Name>Avalonia.Visuals</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Styling\Avalonia.Styling.csproj">
-      <Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
-      <Name>Avalonia.Styling</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj">
-      <Project>{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}</Project>
-      <Name>Avalonia.Themes.Default</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Skia\Avalonia.Skia\Avalonia.Skia.csproj">
-      <Project>{7d2d3083-71dd-4cc9-8907-39a0d86fb322}</Project>
-      <Name>Avalonia.Skia</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj">
-      <Project>{d0a739b9-3c68-4ba6-a328-41606954b6bd}</Project>
-      <Name>ControlCatalog</Name>
-    </ProjectReference>
-    <PackageReference Include="SkiaSharp.HarfBuzz" Version="2.80.2-preview.33" />
+    <ProjectReference Include="..\..\src\iOS\Avalonia.iOS\Avalonia.iOS.csproj" />
+    <ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" />
   </ItemGroup>
-  <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
-  <Import Project="..\..\build\LegacyProject.targets" />
-  <Import Project="..\..\build\SkiaSharp.props" />
-  <Import Project="..\..\build\HarfBuzzSharp.props" />
-</Project>
+</Project>

+ 7 - 2
samples/ControlCatalog.iOS/Info.plist

@@ -5,7 +5,7 @@
 	<key>CFBundleDisplayName</key>
 	<string>ControlCatalog.iOS</string>
 	<key>CFBundleIdentifier</key>
-	<string>com.companyname.ControlCatalog.iOS</string>
+	<string>Avalonia.ControlCatalog</string>
 	<key>CFBundleShortVersionString</key>
 	<string>1.0</string>
 	<key>CFBundleVersion</key>
@@ -13,7 +13,7 @@
 	<key>LSRequiresIPhoneOS</key>
 	<true/>
 	<key>MinimumOSVersion</key>
-	<string>8.0</string>
+	<string>10.0</string>
 	<key>UIDeviceFamily</key>
 	<array>
 		<integer>1</integer>
@@ -28,6 +28,7 @@
 	<key>UISupportedInterfaceOrientations</key>
 	<array>
 		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
 		<string>UIInterfaceOrientationLandscapeLeft</string>
 		<string>UIInterfaceOrientationLandscapeRight</string>
 	</array>
@@ -38,5 +39,9 @@
 		<string>UIInterfaceOrientationLandscapeLeft</string>
 		<string>UIInterfaceOrientationLandscapeRight</string>
 	</array>
+	<key>UIStatusBarHidden</key>
+	<true/>
+	<key>UIViewControllerBasedStatusBarAppearance</key>
+	<false/>
 </dict>
 </plist>

+ 2 - 2
samples/ControlCatalog.iOS/Main.cs

@@ -9,7 +9,7 @@ namespace ControlCatalog.iOS
         {
             // if you want to use a different Application Delegate class from "AppDelegate"
             // you can specify it here.
-            UIApplication.Main(args, null, "AppDelegate");
+            UIApplication.Main(args, null, typeof(AppDelegate));
         }
     }
-}
+}

+ 0 - 36
samples/ControlCatalog.iOS/Properties/AssemblyInfo.cs

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

+ 1 - 1
samples/ControlCatalog.iOS/Resources/LaunchScreen.xib

@@ -11,7 +11,7 @@
 			<rect key="frame" x="0.0" y="0.0" width="480" height="480" />
 			<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" />
 			<subviews>
-				<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="  Copyright (c) 2016 " textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines"
+				<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="  Copyright (c) 2022 " textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines"
 					minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
 					<rect key="frame" x="20" y="439" width="441" height="21" />
 					<fontDescription key="fontDescription" type="system" pointSize="17" />

+ 12 - 6
samples/ControlCatalog/App.xaml.cs

@@ -18,6 +18,16 @@ namespace ControlCatalog
             DataContext = new ApplicationViewModel();
         }
 
+        public static readonly StyleInclude ColorPickerFluent = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
+        {
+            Source = new Uri("avares://Avalonia.Controls.ColorPicker/Themes/Fluent/Fluent.xaml")
+        };
+
+        public static readonly StyleInclude ColorPickerDefault = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
+        {
+            Source = new Uri("avares://Avalonia.Controls.ColorPicker/Themes/Default/Default.xaml")
+        };
+
         public static readonly StyleInclude DataGridFluent = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
         {
             Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml")
@@ -69,7 +79,8 @@ namespace ControlCatalog
         public override void Initialize()
         {
             Styles.Insert(0, Fluent);
-            Styles.Insert(1, DataGridFluent);
+            Styles.Insert(1, ColorPickerFluent);
+            Styles.Insert(2, DataGridFluent);
             AvaloniaXamlLoader.Load(this);
         }
 
@@ -78,11 +89,6 @@ namespace ControlCatalog
             if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktopLifetime)
             {
                 desktopLifetime.MainWindow = new MainWindow();
-
-                this.AttachDevTools(new Avalonia.Diagnostics.DevToolsOptions()
-                {
-                    StartupScreenIndex = 1,
-                });
             }
             else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewLifetime)
             {

+ 5 - 2
samples/ControlCatalog/ControlCatalog.csproj

@@ -1,7 +1,8 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>    
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <Nullable>enable</Nullable>    
   </PropertyGroup>
   <ItemGroup>
     <Compile Update="**\*.xaml.cs">
@@ -23,8 +24,10 @@
 
   <ItemGroup>
     <ProjectReference Include="..\..\packages\Avalonia\Avalonia.csproj" />
-    <ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.Controls.ColorPicker\Avalonia.Controls.ColorPicker.csproj" />
     <ProjectReference Include="..\..\src\Avalonia.Controls.DataGrid\Avalonia.Controls.DataGrid.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.Themes.Fluent\Avalonia.Themes.Fluent.csproj" />
     <ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />
     <ProjectReference Include="..\SampleControls\ControlSamples.csproj" />
   </ItemGroup>

+ 18 - 0
samples/ControlCatalog/Converter/MathSubtractConverter.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Globalization;
+using Avalonia.Data.Converters;
+
+namespace ControlCatalog.Converter;
+
+public class MathSubtractConverter : IValueConverter
+{
+    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+    {
+        return (double)value - (double)parameter;
+    }
+
+    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+    {
+        throw new NotSupportedException();
+    }
+}

+ 17 - 0
samples/ControlCatalog/MainView.xaml

@@ -40,6 +40,12 @@
       <TabItem Header="CheckBox">
         <pages:CheckBoxPage />
       </TabItem>
+      <TabItem Header="Clipboard">
+        <pages:ClipboardPage />
+      </TabItem>
+      <TabItem Header="ColorPicker">
+        <pages:ColorPickerPage />
+      </TabItem>
       <TabItem Header="ComboBox">
         <pages:ComboBoxPage />
       </TabItem>
@@ -142,6 +148,9 @@
       <TabItem Header="ToolTip">
         <pages:ToolTipPage />
       </TabItem>
+      <TabItem Header="TransitioningContentControl">
+        <pages:TransitioningContentControlPage />
+      </TabItem>
       <TabItem Header="TreeView">
         <pages:TreeViewPage />
       </TabItem>
@@ -184,6 +193,14 @@
                 <WindowTransparencyLevel>Mica</WindowTransparencyLevel>
               </ComboBox.Items>
             </ComboBox>
+            <ComboBox x:Name="FlowDirection"
+                      HorizontalAlignment="Stretch"
+                      SelectedIndex="0">
+              <ComboBox.Items>
+                <FlowDirection>LeftToRight</FlowDirection>
+                <FlowDirection>RightToLeft</FlowDirection>
+              </ComboBox.Items>
+            </ComboBox>
             <ComboBox HorizontalAlignment="Stretch"
                       Items="{Binding WindowStates}"
                       SelectedItem="{Binding WindowState}" />

+ 17 - 4
samples/ControlCatalog/MainView.xaml.cs

@@ -49,7 +49,8 @@ namespace ControlCatalog
                             App.Fluent.Mode = FluentThemeMode.Light;
                         }
                         Application.Current.Styles[0] = App.Fluent;
-                        Application.Current.Styles[1] = App.DataGridFluent;
+                        Application.Current.Styles[1] = App.ColorPickerFluent;
+                        Application.Current.Styles[2] = App.DataGridFluent;
                     }
                     else if (theme == CatalogTheme.FluentDark)
                     {
@@ -59,23 +60,35 @@ namespace ControlCatalog
                             App.Fluent.Mode = FluentThemeMode.Dark;
                         }
                         Application.Current.Styles[0] = App.Fluent;
-                        Application.Current.Styles[1] = App.DataGridFluent;
+                        Application.Current.Styles[1] = App.ColorPickerFluent;
+                        Application.Current.Styles[2] = App.DataGridFluent;
                     }
                     else if (theme == CatalogTheme.DefaultLight)
                     {
                         App.Default.Mode = Avalonia.Themes.Default.SimpleThemeMode.Light;
                         Application.Current.Styles[0] = App.DefaultLight;
-                        Application.Current.Styles[1] = App.DataGridDefault;
+                        Application.Current.Styles[1] = App.ColorPickerDefault;
+                        Application.Current.Styles[2] = App.DataGridDefault;
                     }
                     else if (theme == CatalogTheme.DefaultDark)
                     {
                         App.Default.Mode = Avalonia.Themes.Default.SimpleThemeMode.Dark;
                         Application.Current.Styles[0] = App.DefaultDark;
-                        Application.Current.Styles[1] = App.DataGridDefault;
+                        Application.Current.Styles[1] = App.ColorPickerDefault;
+                        Application.Current.Styles[2] = App.DataGridDefault;
                     }
                 }
             };
 
+            var flowDirections = this.Find<ComboBox>("FlowDirection");
+            flowDirections.SelectionChanged += (sender, e) =>
+            {
+                if (flowDirections.SelectedItem is FlowDirection flowDirection)
+                {
+                    this.FlowDirection = flowDirection;
+                }
+            };
+
             var decorations = this.Find<ComboBox>("Decorations");
             decorations.SelectionChanged += (sender, e) =>
             {

+ 31 - 1
samples/ControlCatalog/Pages/ButtonsPage.xaml

@@ -147,6 +147,35 @@
       </StackPanel>
     </Border>
 
+    <!-- DropDownButton -->
+    <Border Classes="header-border">
+      <StackPanel Orientation="Vertical"
+                  Spacing="4">
+        <TextBlock Text="DropDownButton"
+                   Classes="header" />
+        <TextBlock TextWrapping="Wrap">A button with an added drop-down chevron to visually indicate it has a flyout with additional actions.</TextBlock>
+      </StackPanel>
+    </Border>
+
+    <Border Classes="thin"
+            Padding="15">
+      <StackPanel Orientation="Vertical"
+                  Spacing="8">
+        <DropDownButton Flyout="{StaticResource SharedMenuFlyout}">
+          <TextBlock Text="Drop Down Button" />
+        </DropDownButton>
+        <DropDownButton Padding="0,0,8,0">
+          <Border Background="Teal"
+                  HorizontalAlignment="Stretch"
+                  VerticalAlignment="Stretch"
+                  Height="32"
+                  Width="32" />
+        </DropDownButton>
+        <DropDownButton IsEnabled="False">Disabled</DropDownButton>
+        <DropDownButton />
+      </StackPanel>
+    </Border>
+
     <!-- SplitButton -->
     <Border Classes="header-border">
       <StackPanel Orientation="Vertical"
@@ -169,7 +198,8 @@
           <TextBlock Text="Disabled" />
         </SplitButton>
         <SplitButton Flyout="{StaticResource SharedMenuFlyout}"
-                     Content="Re-themed">
+                     Content="Re-themed"
+                     Foreground="White">
           <SplitButton.Styles>
             <Style>
               <Style.Resources>

+ 1 - 2
samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml

@@ -10,8 +10,7 @@
                 Margin="0,16,0,0"
                 HorizontalAlignment="Center"
                 Spacing="16">
-      <StackPanel Orientation="Vertical"
-                  Width="200">
+      <StackPanel Orientation="Vertical">
         <TextBlock Text="SelectedDateFormat: Short"/>
         <CalendarDatePicker Name="DatePicker1"
                     SelectedDateFormat="Short"

+ 3 - 2
samples/ControlCatalog/Pages/CanvasPage.xaml

@@ -4,7 +4,7 @@
   <StackPanel Orientation="Vertical" Spacing="4">
     <TextBlock Classes="h2">A panel which lays out its children by explicit coordinates</TextBlock>
     <Canvas Background="Yellow" Width="300" Height="400">
-      <Rectangle Fill="Blue" Width="63" Height="41" Canvas.Left="40" Canvas.Top="31">
+      <Rectangle Fill="Blue" Width="63" Height="41" Canvas.Left="40" Canvas.Top="31" RadiusX="10" RadiusY="10">
         <Rectangle.OpacityMask>
           <LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,100%">
             <LinearGradientBrush.GradientStops>
@@ -12,8 +12,9 @@
               <GradientStop Offset="1" Color="Transparent"/>
             </LinearGradientBrush.GradientStops>
           </LinearGradientBrush>
-        </Rectangle.OpacityMask>     
+        </Rectangle.OpacityMask>
       </Rectangle>
+      <Rectangle Fill="hsva(240, 83%, 73%, 90%)" Stroke="hsl(5, 85%, 85%)" StrokeThickness="2" Width="40" Height="20" Canvas.Left="150" Canvas.Top="10" RadiusX="10" RadiusY="5" />
       <Ellipse Fill="Green" Width="58" Height="58" Canvas.Left="88" Canvas.Top="100"/>
       <Path Fill="Orange" Data="M 0,0 c 0,0 50,0 50,-50 c 0,0 50,0 50,50 h -50 v 50 l -50,-50 Z" Canvas.Left="30" Canvas.Top="250"/>
       <Path Fill="OrangeRed" Canvas.Left="180" Canvas.Top="250">

+ 1 - 0
samples/ControlCatalog/Pages/CarouselPage.xaml

@@ -29,6 +29,7 @@
         <ComboBoxItem>None</ComboBoxItem>
         <ComboBoxItem>Slide</ComboBoxItem>
         <ComboBoxItem>Crossfade</ComboBoxItem>
+        <ComboBoxItem>3D Rotation</ComboBoxItem>
       </ComboBox>
     </StackPanel>
 

+ 3 - 0
samples/ControlCatalog/Pages/CarouselPage.xaml.cs

@@ -45,6 +45,9 @@ namespace ControlCatalog.Pages
                 case 2:
                     _carousel.PageTransition = new CrossFade(TimeSpan.FromSeconds(0.25));
                     break;
+                case 3:
+                    _carousel.PageTransition = new Rotate3DTransition(TimeSpan.FromSeconds(0.5), _orientation.SelectedIndex == 0 ? PageSlide.SlideAxis.Horizontal : PageSlide.SlideAxis.Vertical);
+                    break;
             }
         }
     }

+ 23 - 0
samples/ControlCatalog/Pages/ClipboardPage.xaml

@@ -0,0 +1,23 @@
+<UserControl x:Class="ControlCatalog.Pages.ClipboardPage"
+             xmlns="https://github.com/avaloniaui"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+  <StackPanel Orientation="Vertical" Spacing="4">
+    <TextBlock Classes="h2">Example of ClipboardPage capabilities</TextBlock>
+
+    <Button Click="CopyText" Content="Copy text to clipboard" />
+    <Button Click="PasteText" Content="Paste text from clipboard" />
+    <Button Click="CopyTextDataObject" Content="Copy text to clipboard (data object)" />
+    <Button Click="PasteTextDataObject" Content="Paste text from clipboard (data object)" />
+
+    <Button Click="CopyFilesDataObject" Content="Copy files to clipboard (data object)" />
+    <Button Click="PasteFilesDataObject" Content="Paste files from clipboard (data object)" />
+
+    <Button Click="GetFormats" Content="Get clipboard formats" />
+    <Button Click="Clear" Content="Clear clipboard" />
+
+    <TextBox x:Name="ClipboardContent"
+             MinHeight="100"
+             AcceptsReturn="True"
+             Watermark="Text to copy of file names per line" />
+  </StackPanel>
+</UserControl>

+ 77 - 0
samples/ControlCatalog/Pages/ClipboardPage.xaml.cs

@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Input;
+using Avalonia.Interactivity;
+using Avalonia.Markup.Xaml;
+
+namespace ControlCatalog.Pages
+{
+    public partial class ClipboardPage : UserControl
+    {
+        public ClipboardPage()
+        {
+            InitializeComponent();
+        }
+
+        private TextBox ClipboardContent => this.Get<TextBox>("ClipboardContent");
+
+        private void InitializeComponent()
+        {
+            AvaloniaXamlLoader.Load(this);
+        }
+
+        private async void CopyText(object sender, RoutedEventArgs args)
+        {
+            await Application.Current.Clipboard.SetTextAsync(ClipboardContent.Text);
+        }
+
+        private async void PasteText(object sender, RoutedEventArgs args)
+        {
+            ClipboardContent.Text = await Application.Current.Clipboard.GetTextAsync();
+        }
+
+        private async void CopyTextDataObject(object sender, RoutedEventArgs args)
+        {
+            var dataObject = new DataObject();
+            dataObject.Set(DataFormats.Text, ClipboardContent.Text ?? string.Empty);
+            await Application.Current.Clipboard.SetDataObjectAsync(dataObject);
+        }
+
+        private async void PasteTextDataObject(object sender, RoutedEventArgs args)
+        {
+            ClipboardContent.Text = await Application.Current.Clipboard.GetDataAsync(DataFormats.Text) as string ?? string.Empty;
+        }
+
+        private async void CopyFilesDataObject(object sender, RoutedEventArgs args)
+        {
+            var files = ClipboardContent.Text.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+            if (files.Length == 0)
+            {
+                return;
+            }
+            var dataObject = new DataObject();
+            dataObject.Set(DataFormats.FileNames, files);
+            await Application.Current.Clipboard.SetDataObjectAsync(dataObject);
+        }
+
+        private async void PasteFilesDataObject(object sender, RoutedEventArgs args)
+        {
+            var fiels = await Application.Current.Clipboard.GetDataAsync(DataFormats.FileNames) as IEnumerable<string>;
+            ClipboardContent.Text = fiels != null ? string.Join(Environment.NewLine, fiels) : string.Empty;
+        }
+
+        private async void GetFormats(object sender, RoutedEventArgs args)
+        {
+            var formats = await Application.Current.Clipboard.GetFormatsAsync();
+            ClipboardContent.Text = string.Join(Environment.NewLine, formats);
+        }
+
+        private async void Clear(object sender, RoutedEventArgs args)
+        {
+            await Application.Current.Clipboard.ClearAsync();
+        }
+    }
+}

+ 79 - 0
samples/ControlCatalog/Pages/ColorPickerPage.xaml

@@ -0,0 +1,79 @@
+<UserControl xmlns="https://github.com/avaloniaui"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+             xmlns:primitives="clr-namespace:Avalonia.Controls.Primitives;assembly=Avalonia.Controls"
+             xmlns:pc="clr-namespace:Avalonia.Controls.Primitives.Converters;assembly=Avalonia.Controls.ColorPicker"
+             mc:Ignorable="d"
+             d:DesignWidth="800"
+             d:DesignHeight="450"
+             x:Class="ControlCatalog.Pages.ColorPickerPage">
+
+  <UserControl.Resources>
+    <pc:ThirdComponentConverter x:Key="ThirdComponent" />
+  </UserControl.Resources>
+
+  <Grid ColumnDefinitions="Auto,10,Auto">
+    <Grid Grid.Column="0"
+          Grid.Row="0"
+          RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto">
+      <ColorSpectrum x:Name="ColorSpectrum1"
+                     Grid.Row="0"
+                     Color="Red"
+                     CornerRadius="10"
+                     Height="256"
+                     Width="256" />
+      <ColorSlider Grid.Row="1"
+                   Margin="0,10,0,0"
+                   ColorComponent="Component1"
+                   ColorModel="Hsva"
+                   HsvColor="{Binding HsvColor, ElementName=ColorSpectrum1}" />
+      <ColorSlider Grid.Row="2"
+                   ColorComponent="Component2"
+                   ColorModel="Hsva"
+                   HsvColor="{Binding HsvColor, ElementName=ColorSpectrum1}" />
+      <ColorSlider Grid.Row="3"
+                   ColorComponent="Component3"
+                   ColorModel="Hsva"
+                   HsvColor="{Binding HsvColor, ElementName=ColorSpectrum1}" />
+      <ColorSlider Grid.Row="4"
+                   ColorComponent="Alpha"
+                   ColorModel="Hsva"
+                   HsvColor="{Binding HsvColor, ElementName=ColorSpectrum1}" />
+      <ColorPreviewer Grid.Row="5"
+                      ShowAccentColors="True"
+                      HsvColor="{Binding HsvColor, ElementName=ColorSpectrum1}" />
+    </Grid>
+    <Grid Grid.Column="2"
+          Grid.Row="0"
+          ColumnDefinitions="Auto,Auto,Auto"
+          RowDefinitions="Auto,Auto">
+      <ColorSlider Grid.Column="0"
+                   Grid.Row="0"
+                   IsAlphaMaxForced="True"
+                   IsSaturationValueMaxForced="False"
+                   ColorComponent="{Binding Components, ElementName=ColorSpectrum2, Converter={StaticResource ThirdComponent}}"
+                   ColorModel="Hsva"
+                   Orientation="Vertical"
+                   HsvColor="{Binding HsvColor, ElementName=ColorSpectrum2}" />
+      <ColorSpectrum x:Name="ColorSpectrum2"
+                     Grid.Column="1"
+                     Grid.Row="0"
+                     Color="Green"
+                     Shape="Ring"
+                     Height="256"
+                     Width="256" />
+      <ColorSlider Grid.Column="2"
+                   Grid.Row="0"
+                   ColorComponent="Alpha"
+                   ColorModel="Hsva"
+                   Orientation="Vertical"
+                   HsvColor="{Binding HsvColor, ElementName=ColorSpectrum2}" />
+      <ColorPreviewer Grid.Column="0"
+                      Grid.ColumnSpan="3"
+                      Grid.Row="1"
+                      ShowAccentColors="True"
+                      HsvColor="{Binding HsvColor, ElementName=ColorSpectrum2}" />
+    </Grid>
+  </Grid>
+</UserControl>

+ 19 - 0
samples/ControlCatalog/Pages/ColorPickerPage.xaml.cs

@@ -0,0 +1,19 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace ControlCatalog.Pages
+{
+    public partial class ColorPickerPage : UserControl
+    {
+        public ColorPickerPage()
+        {
+            InitializeComponent();
+        }
+
+        private void InitializeComponent()
+        {
+            AvaloniaXamlLoader.Load(this);
+        }
+    }
+}

+ 10 - 0
samples/ControlCatalog/Pages/ComboBoxPage.xaml

@@ -86,6 +86,16 @@
                         <sys:Exception />
                     </DataValidationErrors.Error>
                 </ComboBox>
+
+                <ComboBox PlaceholderText="Scaled" Width="166" RenderTransformOrigin="0,0">
+                    <ComboBox.RenderTransform>
+                      <ScaleTransform ScaleX="1.5" ScaleY="1.5"/>
+                    </ComboBox.RenderTransform>
+                    <ComboBoxItem>Inline Items</ComboBoxItem>
+                    <ComboBoxItem>Inline Item 2</ComboBoxItem>
+                    <ComboBoxItem>Inline Item 3</ComboBoxItem>
+                    <ComboBoxItem>Inline Item 4</ComboBoxItem>
+                </ComboBox>
             </WrapPanel>
 
             <CheckBox IsChecked="{Binding WrapSelection}">WrapSelection</CheckBox>

+ 17 - 2
samples/ControlCatalog/Pages/DataGridPage.xaml

@@ -13,9 +13,22 @@
   </UserControl.Resources>
   <UserControl.Styles>
     <Style Selector="DataGridCell.gdp">
-      <Setter Property="FontWeight" Value="Bold" />
       <Setter Property="Background" Value="{Binding Path=GDP, Mode=OneWay, Converter={StaticResource GDPConverter}}" />
     </Style>
+    <Style Selector="DataGridColumnHeader:nth-last-child(1)">
+      <Setter Property="FontWeight" Value="Bold" />
+    </Style>
+    <Style Selector="DataGridCell:nth-last-child(1)">
+      <Setter Property="FontWeight" Value="Bold" />
+    </Style>
+    <Style Selector="DataGrid#dataGridGrouping DataGridRow:nth-child(5n+3)">
+      <Setter Property="Foreground" Value="Red" />
+      <Setter Property="FontWeight" Value="Bold" />
+    </Style>
+    <Style Selector="DataGrid#dataGridGrouping DataGridRow:nth-last-child(5n+1)">
+      <Setter Property="Foreground" Value="Blue" />
+      <Setter Property="FontWeight" Value="Bold" />
+    </Style>
   </UserControl.Styles>
   <Grid RowDefinitions="Auto,Auto,*">
     <StackPanel Orientation="Vertical" Spacing="4" Grid.Row="0">
@@ -31,7 +44,9 @@
         <DockPanel>
           <CheckBox x:Name="ShowGDP"  IsChecked="True"  Content="Toggle GDP Column Visibility"
                     DockPanel.Dock="Top"/>
-          <DataGrid Name="dataGrid1" Margin="12" CanUserResizeColumns="True" CanUserReorderColumns="True" CanUserSortColumns="True" HeadersVisibility="All">
+          <DataGrid Name="dataGrid1" Margin="12" CanUserResizeColumns="True" CanUserReorderColumns="True" CanUserSortColumns="True" HeadersVisibility="All"
+                    RowBackground="#1000"
+                    AlternatingRowBackground="#1fff">
             <DataGrid.Columns>
               <!-- Using HeaderTemplate -->
               <DataGridTextColumn Header="Country" HeaderTemplate="{StaticResource Demo.DataTemplates.CountryHeader}" Binding="{Binding Name}" Width="6*" />

+ 3 - 3
samples/ControlCatalog/Pages/DialogsPage.xaml.cs

@@ -8,7 +8,6 @@ using Avalonia.Dialogs;
 using Avalonia.Layout;
 using Avalonia.Markup.Xaml;
 #pragma warning disable 4014
-
 namespace ControlCatalog.Pages
 {
     public class DialogsPage : UserControl
@@ -22,7 +21,7 @@ namespace ControlCatalog.Pages
 
             string lastSelectedDirectory = null;
 
-            List<FileDialogFilter> GetFilters()
+            List<FileDialogFilter>? GetFilters()
             {
                 if (this.FindControl<CheckBox>("UseFilters").IsChecked != true)
                     return null;
@@ -166,7 +165,8 @@ namespace ControlCatalog.Pages
                         (button = new Button
                         {
                             HorizontalAlignment = HorizontalAlignment.Center,
-                            Content = "Click to close"
+                            Content = "Click to close",
+                            IsDefault = true
                         })
                     }
                 },

+ 7 - 1
samples/ControlCatalog/Pages/DragAndDropPage.xaml

@@ -11,7 +11,13 @@
                 Padding="16"
                 BorderBrush="{DynamicResource SystemAccentColor}"
                 BorderThickness="2">
-          <TextBlock Name="DragStateText" TextWrapping="Wrap">Drag Me</TextBlock>
+          <TextBlock Name="DragStateText" TextWrapping="Wrap">Drag Me (text)</TextBlock>
+        </Border>
+        <Border Name="DragMeFiles"
+                Padding="16"
+                BorderBrush="{DynamicResource SystemAccentColor}"
+                BorderThickness="2">
+          <TextBlock Name="DragStateFiles" TextWrapping="Wrap">Drag Me (files)</TextBlock>
         </Border>
         <Border Name="DragMeCustom"
                 Padding="16"

+ 1 - 3
samples/ControlCatalog/Pages/DragAndDropPage.xaml.cs

@@ -2,11 +2,8 @@
 using Avalonia.Input;
 using Avalonia.Markup.Xaml;
 using System;
-using System.Collections.Generic;
-using System.IO;
 using System.Linq;
 using System.Reflection;
-using System.Text;
 
 namespace ControlCatalog.Pages
 {
@@ -24,6 +21,7 @@ namespace ControlCatalog.Pages
                 $"Text was dragged {++textCount} times"), DragDropEffects.Copy | DragDropEffects.Move | DragDropEffects.Link);
 
             SetupDnd("Custom", d => d.Set(CustomFormat, "Test123"), DragDropEffects.Move);
+            SetupDnd("Files", d => d.Set(DataFormats.FileNames, new[] { Assembly.GetEntryAssembly()?.GetModules().FirstOrDefault()?.FullyQualifiedName }), DragDropEffects.Copy);
         }
 
         void SetupDnd(string suffix, Action<DataObject> factory, DragDropEffects effects)

+ 2 - 0
samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml

@@ -53,10 +53,12 @@
         <ComboBoxItem>UniformGrid - Horizontal</ComboBoxItem>
       </ComboBox>
       <Button Command="{Binding AddItem}">Add Item</Button>
+      <Button Command="{Binding RemoveItem}">Remove Item</Button>
       <Button Command="{Binding RandomizeHeights}">Randomize Heights</Button>
       <Button Command="{Binding ResetItems}">Reset items</Button>
       <Button x:Name="scrollToLast">Scroll to Last</Button>
       <Button x:Name="scrollToRandom">Scroll to Random</Button>
+      <Button x:Name="scrollToSelected">Scroll to Selected</Button>
     </StackPanel>
     <Border BorderThickness="1" BorderBrush="{DynamicResource SystemControlHighlightBaseMediumLowBrush}" Margin="0 0 0 16">
       <ScrollViewer Name="scroller"

+ 11 - 1
samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml.cs

@@ -15,8 +15,10 @@ namespace ControlCatalog.Pages
         private readonly ItemsRepeaterPageViewModel _viewModel;
         private ItemsRepeater _repeater;
         private ScrollViewer _scroller;
+        private int _selectedIndex;
         private Button _scrollToLast;
         private Button _scrollToRandom;
+        private Button _scrollToSelected;
         private Random _random = new Random(0);
 
         public ItemsRepeaterPage()
@@ -26,10 +28,12 @@ namespace ControlCatalog.Pages
             _scroller = this.FindControl<ScrollViewer>("scroller");
             _scrollToLast = this.FindControl<Button>("scrollToLast");
             _scrollToRandom = this.FindControl<Button>("scrollToRandom");
+            _scrollToSelected = this.FindControl<Button>("scrollToSelected");
             _repeater.PointerPressed += RepeaterClick;
             _repeater.KeyDown += RepeaterOnKeyDown;
             _scrollToLast.Click += scrollToLast_Click;
             _scrollToRandom.Click += scrollToRandom_Click;
+            _scrollToSelected.Click += scrollToSelected_Click;
             DataContext = _viewModel = new ItemsRepeaterPageViewModel();
         }
 
@@ -111,7 +115,7 @@ namespace ControlCatalog.Pages
         private void ScrollTo(int index)
         {
             System.Diagnostics.Debug.WriteLine("Scroll to " + index);
-            var layoutManager = ((Window)this.GetVisualRoot()).LayoutManager;
+            var layoutManager = ((TopLevel)VisualRoot).LayoutManager;
             var element = _repeater.GetOrCreateElement(index);
             layoutManager.ExecuteLayoutPass();
             element.BringIntoView();
@@ -121,6 +125,7 @@ namespace ControlCatalog.Pages
         {
             var item = (e.Source as TextBlock)?.DataContext as ItemsRepeaterPageViewModel.Item;
             _viewModel.SelectedItem = item;
+            _selectedIndex = _viewModel.Items.IndexOf(item);
         }
 
         private void RepeaterOnKeyDown(object sender, KeyEventArgs e)
@@ -140,5 +145,10 @@ namespace ControlCatalog.Pages
         {
             ScrollTo(_random.Next(_viewModel.Items.Count - 1));
         }
+
+        private void scrollToSelected_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
+        {
+            ScrollTo(_selectedIndex);
+        }
     }
 }

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません