Avalonia.Native TopLevel embedding (#15932)

* Introduce Avalonia.Native TopLevelImpl

* Update Avalonia.Native.csproj

Revert change
This commit is contained in:
Benedikt Stebner 2024-06-20 01:55:59 +02:00 коммит произвёл GitHub
Родитель 42ec037e9a
Коммит 143399f65a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
60 изменённых файлов: 1425 добавлений и 1042 удалений

Просмотреть файл

@ -116,19 +116,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1
build\SourceGenerators.props = build\SourceGenerators.props
build\SourceLink.props = build\SourceLink.props
build\System.Memory.props = build\System.Memory.props
build\TargetFrameworks.props = build\TargetFrameworks.props
build\TrimmingEnable.props = build\TrimmingEnable.props
build\UnitTests.NetFX.props = build\UnitTests.NetFX.props
build\XUnit.props = build\XUnit.props
build\TargetFrameworks.props = build\TargetFrameworks.props
build\WarnAsErrors.props = build\WarnAsErrors.props
build\XUnit.props = build\XUnit.props
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{4D6FAF79-58B4-482F-9122-0668C346364C}"
ProjectSection(SolutionItems) = preProject
build\BuildTargets.targets = build\BuildTargets.targets
build\DevSingleProject.targets = build\DevSingleProject.targets
build\LegacyProject.targets = build\LegacyProject.targets
build\UnitTests.NetCore.targets = build\UnitTests.NetCore.targets
build\DevSingleProject.targets = build\DevSingleProject.targets
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linux", "Linux", "{86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B}"
@ -232,8 +232,8 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{176582E8-46AF-416A-85C1-13A5C6744497}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
azure-pipelines.yml = azure-pipelines.yml
azure-pipelines-integrationtests.yml = azure-pipelines-integrationtests.yml
azure-pipelines.yml = azure-pipelines.yml
CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
CONTRIBUTING.md = CONTRIBUTING.md
Directory.Build.props = Directory.Build.props
@ -283,24 +283,23 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Tizen", "sam
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Metal", "src\Avalonia.Metal\Avalonia.Metal.csproj", "{60B4ED1F-ECFA-453B-8A70-1788261C8355}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Build.Tasks.UnitTest", "tests\Avalonia.Build.Tasks.UnitTest\Avalonia.Build.Tasks.UnitTest.csproj", "{B0FD6A48-FBAB-4676-B36A-DE76B0922B12}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Build.Tasks.UnitTest", "tests\Avalonia.Build.Tasks.UnitTest\Avalonia.Build.Tasks.UnitTest.csproj", "{B0FD6A48-FBAB-4676-B36A-DE76B0922B12}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestFiles", "TestFiles", "{9D6AEF22-221F-4F4B-B335-A4BA510F002C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BuildTasks", "BuildTasks", "{5BF0C3B8-E595-4940-AB30-2DA206C2F085}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PInvoke", "tests\TestFiles\BuildTasks\PInvoke\PInvoke.csproj", "{0A948D71-99C5-43E9-BACB-B0BA59EA25B4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PInvoke", "tests\TestFiles\BuildTasks\PInvoke\PInvoke.csproj", "{0A948D71-99C5-43E9-BACB-B0BA59EA25B4}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnloadableAssemblyLoadContext", "UnloadableAssemblyLoadContext", "{9CCA131B-DE95-4D44-8788-C3CAE28574CD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnloadableAssemblyLoadContext", "samples\UnloadableAssemblyLoadContext\UnloadableAssemblyLoadContext\UnloadableAssemblyLoadContext.csproj", "{D7FE3E0F-3FE0-4F87-A2F5-24F1454D84C0}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnloadableAssemblyLoadContext", "samples\UnloadableAssemblyLoadContext\UnloadableAssemblyLoadContext\UnloadableAssemblyLoadContext.csproj", "{D7FE3E0F-3FE0-4F87-A2F5-24F1454D84C0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnloadableAssemblyLoadContextPlug", "samples\UnloadableAssemblyLoadContext\UnloadableAssemblyLoadContextPlug\UnloadableAssemblyLoadContextPlug.csproj", "{DA5F1FF9-4259-4C54-B443-85CFA226EE6A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnloadableAssemblyLoadContextPlug", "samples\UnloadableAssemblyLoadContext\UnloadableAssemblyLoadContextPlug\UnloadableAssemblyLoadContextPlug.csproj", "{DA5F1FF9-4259-4C54-B443-85CFA226EE6A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Vulkan", "src\Avalonia.Vulkan\Avalonia.Vulkan.csproj", "{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Vulkan", "src\Avalonia.Vulkan\Avalonia.Vulkan.csproj", "{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.RenderTests.WpfCompare", "tests\Avalonia.RenderTests.WpfCompare\Avalonia.RenderTests.WpfCompare.csproj", "{9AE1B827-21AC-4063-AB22-C8804B7F931E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.RenderTests.WpfCompare", "tests\Avalonia.RenderTests.WpfCompare\Avalonia.RenderTests.WpfCompare.csproj", "{9AE1B827-21AC-4063-AB22-C8804B7F931E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -678,10 +677,6 @@ Global
{60B4ED1F-ECFA-453B-8A70-1788261C8355}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60B4ED1F-ECFA-453B-8A70-1788261C8355}.Release|Any CPU.ActiveCfg = Release|Any CPU
{60B4ED1F-ECFA-453B-8A70-1788261C8355}.Release|Any CPU.Build.0 = Release|Any CPU
{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}.Release|Any CPU.Build.0 = Release|Any CPU
{B0FD6A48-FBAB-4676-B36A-DE76B0922B12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B0FD6A48-FBAB-4676-B36A-DE76B0922B12}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B0FD6A48-FBAB-4676-B36A-DE76B0922B12}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -698,6 +693,10 @@ Global
{DA5F1FF9-4259-4C54-B443-85CFA226EE6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA5F1FF9-4259-4C54-B443-85CFA226EE6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA5F1FF9-4259-4C54-B443-85CFA226EE6A}.Release|Any CPU.Build.0 = Release|Any CPU
{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E2DE2B6-13BC-4C27-BCB9-A423B86CAF77}.Release|Any CPU.Build.0 = Release|Any CPU
{9AE1B827-21AC-4063-AB22-C8804B7F931E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9AE1B827-21AC-4063-AB22-C8804B7F931E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9AE1B827-21AC-4063-AB22-C8804B7F931E}.Release|Any CPU.ActiveCfg = Release|Any CPU

Просмотреть файл

@ -36,7 +36,20 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypeParameters/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="T" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=15b5b1f1_002D457c_002D4ca6_002Db278_002D5615aedc07d3/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="s_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=236f7aa5_002D7b06_002D43ca_002Dbf2a_002D9b31bfcff09a/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=2c62818f_002D621b_002D4425_002Dadc9_002D78611099bfcb/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Type parameters"&gt;&lt;ElementKinds&gt;&lt;Kind Name="TYPE_PARAMETER" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="False" Prefix="T" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=61a991a4_002Dd0a3_002D4d19_002D90a5_002Df8f4d75c30c1/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Local variables"&gt;&lt;ElementKinds&gt;&lt;Kind Name="LOCAL_VARIABLE" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="False" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=669e5282_002Dfb4b_002D4e90_002D91e7_002D07d269d04b60/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Constant fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8a85b61a_002D1024_002D4f87_002Db9ef_002D1fdae19930a1/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Parameters"&gt;&lt;ElementKinds&gt;&lt;Kind Name="PARAMETER" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="False" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8b8504e3_002Df0be_002D4c14_002D9103_002Dc732f2bddc15/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Enum members"&gt;&lt;ElementKinds&gt;&lt;Kind Name="ENUM_MEMBER" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a0b4bc4d_002Dd13b_002D4a37_002Db37e_002Dc9c6864e4302/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"&gt;&lt;ElementKinds&gt;&lt;Kind Name="NAMESPACE" /&gt;&lt;Kind Name="CLASS" /&gt;&lt;Kind Name="STRUCT" /&gt;&lt;Kind Name="ENUM" /&gt;&lt;Kind Name="DELEGATE" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a7a3339e_002D4e89_002D4319_002D9735_002Da9dc4cb74cc7/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Interfaces"&gt;&lt;ElementKinds&gt;&lt;Kind Name="INTERFACE" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="False" Prefix="I" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=c873eafb_002Dd57f_002D481d_002D8c93_002D77f6863c2f88/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static readonly fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=f9fce829_002De6f4_002D4cb2_002D80f1_002D5497c44f51df/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="s_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002EDaemon_002ESettings_002EMigration_002ESwaWarningsModeSettingsMigrate/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Activatable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Avalonia/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fcitx/@EntryIndexedValue">True</s:Boolean>

Просмотреть файл

@ -17,7 +17,6 @@
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 */; };
@ -61,10 +60,11 @@
ED3791C42862E1F40080BD62 /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED3791C32862E1F40080BD62 /* UniformTypeIdentifiers.framework */; };
ED754D262A97306B0078B4DF /* PlatformRenderTimer.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED754D252A97306B0078B4DF /* PlatformRenderTimer.mm */; };
EDF8CDCD2964CB01001EE34F /* PlatformSettings.mm in Sources */ = {isa = PBXBuildFile; fileRef = EDF8CDCC2964CB01001EE34F /* PlatformSettings.mm */; };
F10084842BFF1F9E0024303E /* TopLevelImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = F10084832BFF1F9E0024303E /* TopLevelImpl.h */; };
F10084862BFF1FB40024303E /* TopLevelImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = F10084852BFF1FB40024303E /* TopLevelImpl.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>"; };
@ -125,6 +125,8 @@
ED3791C32862E1F40080BD62 /* UniformTypeIdentifiers.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UniformTypeIdentifiers.framework; path = System/Library/Frameworks/UniformTypeIdentifiers.framework; sourceTree = SDKROOT; };
ED754D252A97306B0078B4DF /* PlatformRenderTimer.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformRenderTimer.mm; sourceTree = "<group>"; };
EDF8CDCC2964CB01001EE34F /* PlatformSettings.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformSettings.mm; sourceTree = "<group>"; };
F10084832BFF1F9E0024303E /* TopLevelImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TopLevelImpl.h; sourceTree = "<group>"; };
F10084852BFF1FB40024303E /* TopLevelImpl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TopLevelImpl.mm; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -164,9 +166,11 @@
AB7A61E62147C814003C5833 = {
isa = PBXGroup;
children = (
F10084852BFF1FB40024303E /* TopLevelImpl.mm */,
ED754D252A97306B0078B4DF /* PlatformRenderTimer.mm */,
855EDC9E28C6546F00807998 /* PlatformBehaviorInhibition.mm */,
8D2F3511292F6AAE007FCF54 /* AvnTextInputMethodDelegate.h */,
F10084832BFF1F9E0024303E /* TopLevelImpl.h */,
8D300D68292E1E5D00320C49 /* AvnTextInputMethod.mm */,
8D300D64292D0A6800320C49 /* AvnTextInputMethod.h */,
BC11A5BC2608D58F0017BAD0 /* automation.h */,
@ -214,7 +218,6 @@
1839155B28B20FFB672D29C6 /* AvnWindow.mm */,
18391DB45C7D892E61BF388C /* WindowInterfaces.h */,
18391BB698579F40F1783F31 /* PopupImpl.mm */,
183910513F396141938832B5 /* PopupImpl.h */,
64B1EBEECBE13D8616D7C934 /* metal.mm */,
64B1E4FA7D9D6E5F47AA8606 /* noarc.mm */,
64B1E26F2B1B9C577BF52F06 /* noarc.h */,
@ -237,6 +240,7 @@
buildActionMask = 2147483647;
files = (
37155CE4233C00EB0034DCE9 /* menu.h in Headers */,
F10084842BFF1F9E0024303E /* TopLevelImpl.h in Headers */,
BC11A5BE2608D58F0017BAD0 /* automation.h in Headers */,
183916173528EC2737DBE5E1 /* WindowBaseImpl.h in Headers */,
1839171DCC651B0638603AC4 /* INSWindowHolder.h in Headers */,
@ -249,7 +253,6 @@
18391E1381E2D5BFD60265A9 /* AutoFitContentView.h in Headers */,
18391F1E2411C79405A9943A /* WindowProtocol.h in Headers */,
183914E50CF6D2EFC1667F7C /* WindowInterfaces.h in Headers */,
18391AC65ADD7DDD33FBE737 /* PopupImpl.h in Headers */,
64B1ECA861163C0EFF0E502B /* noarc.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -332,6 +335,7 @@
AB00E4F72147CA920032A60A /* main.mm in Sources */,
37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */,
1839179A55FC1421BEE83330 /* WindowBaseImpl.mm in Sources */,
F10084862BFF1FB40024303E /* TopLevelImpl.mm in Sources */,
1839125F057B0A4EB1760058 /* WindowImpl.mm in Sources */,
18391068E48EF96E3DB5FDAB /* ResizeScope.mm in Sources */,
18391D4EB311BC7EF8B8C0A6 /* AvnView.mm in Sources */,

Просмотреть файл

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
version = "1.3">
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">

Просмотреть файл

@ -7,20 +7,20 @@
#import <AppKit/AppKit.h>
#include "common.h"
#include "WindowImpl.h"
#include "TopLevelImpl.h"
#include "KeyTransform.h"
@class AvnAccessibilityElement;
@protocol IRenderTarget;
@interface AvnView : NSView<NSTextInputClient, NSDraggingDestination, AvnTextInputMethodDelegate, CALayerDelegate>
-(AvnView* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent;
-(AvnView* _Nonnull) initWithParent: (TopLevelImpl* _Nonnull) parent;
-(NSEvent* _Nonnull) lastMouseDownEvent;
-(AvnPoint) translateLocalPoint:(AvnPoint)pt;
-(void) onClosed;
-(AvnPlatformResizeReason) getResizeReason;
-(void) setResizeReason:(AvnPlatformResizeReason)reason;
-(void) setRenderTarget:(NSObject<IRenderTarget>*)target;
-(void) setRenderTarget:(NSObject<IRenderTarget>* _Nonnull)target;
+ (AvnPoint)toAvnPoint:(CGPoint)p;
@end

Просмотреть файл

@ -7,10 +7,11 @@
#include "AvnView.h"
#include "automation.h"
#import "WindowInterfaces.h"
#import "WindowImpl.h"
@implementation AvnView
{
ComPtr<WindowBaseImpl> _parent;
ComPtr<TopLevelImpl> _parent;
NSTrackingArea* _area;
bool _isLeftPressed, _isMiddlePressed, _isRightPressed, _isXButton1Pressed, _isXButton2Pressed;
AvnInputModifiers _modifierState;
@ -67,7 +68,7 @@
[self updateLayer];
}
-(AvnView*) initWithParent: (WindowBaseImpl*) parent
-(AvnView*) initWithParent: (TopLevelImpl*) parent
{
self = [super init];
[self setWantsLayer:YES];
@ -155,7 +156,7 @@
auto reason = [self inLiveResize] ? ResizeUser : _resizeReason;
_parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height}, reason);
_parent->TopLevelEvents->Resized(FromNSSize(newSize), reason);
}
}
@ -167,14 +168,14 @@
return;
}
_parent->BaseEvents->RunRenderPriorityJobs();
_parent->TopLevelEvents->RunRenderPriorityJobs();
if (_parent == nullptr)
{
return;
}
_parent->BaseEvents->Paint();
_parent->TopLevelEvents->Paint();
}
- (void)drawRect:(NSRect)dirtyRect
@ -207,7 +208,7 @@
if(_parent != nullptr)
{
_parent->BaseEvents->ScalingChanged([_parent->Window backingScaleFactor]);
_parent->TopLevelEvents->ScalingChanged([[self window] backingScaleFactor]);
}
[super viewDidChangeBackingProperties];
@ -219,19 +220,24 @@
{
return TRUE;
}
id<AvnWindowProtocol> parentWindow = nullptr;
auto parentWindow = _parent->GetWindowProtocol();
if([[self window] conformsToProtocol:@protocol(AvnWindowProtocol)]){
parentWindow = (id<AvnWindowProtocol>)[self window];
}
if(parentWindow == nil || ![parentWindow shouldTryToHandleEvents])
if(parentWindow != nullptr && ![parentWindow shouldTryToHandleEvents])
{
if(trigerInputWhenDisabled)
{
auto window = dynamic_cast<WindowImpl*>(_parent.getRaw());
if(window != nullptr)
{
window->WindowEvents->GotInputWhenDisabled();
WindowImpl* windowImpl = dynamic_cast<WindowImpl*>(_parent.getRaw());
if(windowImpl == nullptr){
return FALSE;
}
windowImpl->WindowEvents->GotInputWhenDisabled();
}
return TRUE;
@ -301,7 +307,7 @@
if(_parent != nullptr)
{
_parent->BaseEvents->RawMouseEvent(type, timestamp, modifiers, point, delta);
_parent->TopLevelEvents->RawMouseEvent(type, timestamp, modifiers, point, delta);
}
[super mouseMoved:event];
@ -309,7 +315,7 @@
- (BOOL) resignFirstResponder
{
_parent->BaseEvents->LostFocus();
_parent->TopLevelEvents->LostFocus();
return YES;
}
@ -461,7 +467,7 @@
auto timestamp = static_cast<uint64_t>([event timestamp] * 1000);
auto modifiers = [self getModifiers:[event modifierFlags]];
_parent->BaseEvents->RawKeyEvent(type, timestamp, modifiers, key, physicalKey, keySymbolUtf8);
_parent->TopLevelEvents->RawKeyEvent(type, timestamp, modifiers, key, physicalKey, keySymbolUtf8);
}
- (void)flagsChanged:(NSEvent *)event
@ -521,7 +527,7 @@
}
- (bool) handleKeyDown: (NSTimeInterval) timestamp withKey:(AvnKey)key withPhysicalKey:(AvnPhysicalKey)physicalKey withModifiers:(AvnInputModifiers)modifiers withKeySymbol:(NSString*)keySymbol {
return _parent->BaseEvents->RawKeyEvent(KeyDown, timestamp, modifiers, key, physicalKey, [keySymbol UTF8String]);
return _parent->TopLevelEvents->RawKeyEvent(KeyDown, timestamp, modifiers, key, physicalKey, [keySymbol UTF8String]);
}
- (void)keyDown:(NSEvent *)event
@ -575,7 +581,7 @@
if(keySymbol != nullptr && key != AvnKeyEnter){
auto timestamp = static_cast<uint64_t>([event timestamp] * 1000);
_parent->BaseEvents->RawTextInputEvent(timestamp, [keySymbol UTF8String]);
_parent->TopLevelEvents->RawTextInputEvent(timestamp, [keySymbol UTF8String]);
}
}
}
@ -707,7 +713,7 @@
uint64_t timestamp = static_cast<uint64_t>([NSDate timeIntervalSinceReferenceDate] * 1000);
_parent->BaseEvents->RawTextInputEvent(timestamp, [text UTF8String]);
_parent->TopLevelEvents->RawTextInputEvent(timestamp, [text UTF8String]);
}
- (NSUInteger)characterIndexForPoint:(NSPoint)point
@ -733,7 +739,7 @@
NSDragOperation nsop = [info draggingSourceOperationMask];
auto effects = ConvertDragDropEffects(nsop);
int reffects = (int)_parent->BaseEvents
int reffects = (int)_parent->TopLevelEvents
->DragEvent(type, point, modifiers, effects,
CreateClipboard([info draggingPasteboard], nil),
GetAvnDataObjectHandleFromDraggingInfo(info));
@ -799,7 +805,7 @@
{
if (_accessibilityChild == nil)
{
auto peer = _parent->BaseEvents->GetAutomationPeer();
auto peer = _parent->TopLevelEvents->GetAutomationPeer();
if (peer == nil)
return nil;

Просмотреть файл

@ -24,7 +24,6 @@
#include "WindowImpl.h"
#include "AvnView.h"
#include "WindowInterfaces.h"
#include "PopupImpl.h"
@implementation CLASS_NAME
{
@ -201,8 +200,6 @@
[self backingScaleFactor];
}
- (void)windowWillClose:(NSNotification *_Nonnull)notification
{
_closed = true;
@ -231,7 +228,7 @@
//
// If we don't implement this, then isZoomed always returns true for a non-
// resizable window ¯\_(ツ)_/¯
- (NSRect)windowWillUseStandardFrame:(NSWindow*)window
- (NSRect)windowWillUseStandardFrame:(NSWindow* _Nonnull)window
defaultFrame:(NSRect)newFrame {
return newFrame;
}
@ -397,7 +394,7 @@
return _parent->CanZoom();
}
-(void)windowDidResignKey:(NSNotification *)notification
-(void)windowDidResignKey:(NSNotification* _Nonnull)notification
{
if(_parent)
_parent->BaseEvents->Deactivated();

Просмотреть файл

@ -11,6 +11,10 @@
struct INSWindowHolder
{
virtual NSWindow* _Nonnull GetNSWindow () = 0;
};
struct INSViewHolder
{
virtual AvnView* _Nonnull GetNSView () = 0;
};

Просмотреть файл

@ -1,9 +0,0 @@
//
// 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

Просмотреть файл

@ -12,7 +12,6 @@
#import "WindowBaseImpl.h"
#import "WindowProtocol.h"
#import <AppKit/AppKit.h>
#include "PopupImpl.h"
class PopupImpl : public virtual WindowBaseImpl, public IAvnPopup
{
@ -23,7 +22,7 @@ private:
END_INTERFACE_MAP()
virtual ~PopupImpl(){}
ComPtr<IAvnWindowEvents> WindowEvents;
PopupImpl(IAvnWindowEvents* events) : WindowBaseImpl(events)
PopupImpl(IAvnWindowEvents* events) : TopLevelImpl(events), WindowBaseImpl(events)
{
WindowEvents = events;
[Window setLevel:NSPopUpMenuWindowLevel];
@ -35,13 +34,12 @@ protected:
}
public:
virtual bool ShouldTakeFocusOnShow() override
{
return false;
}
virtual HRESULT Show(bool activate, bool isDialog) override
{
auto windowProtocol = GetWindowProtocol();
[windowProtocol setEnabled:true];
return WindowBaseImpl::Show(activate, true);
}
};

Просмотреть файл

@ -0,0 +1,76 @@
//
// TopLevelImpl.h
// Avalonia.Native.OSX
//
// Created by Benedikt Stebner on 16.05.24.
// Copyright © 2024 Avalonia. All rights reserved.
//
#ifndef TopLevelImpl_h
#define TopLevelImpl_h
#include "rendertarget.h"
#include "INSWindowHolder.h"
#include "AvnTextInputMethod.h"
#include "AutoFitContentView.h"
#include <list>
class TopLevelImpl : public virtual ComObject,
public virtual IAvnTopLevel,
public INSViewHolder{
public:
FORWARD_IUNKNOWN()
BEGIN_INTERFACE_MAP()
INTERFACE_MAP_ENTRY(IAvnTopLevel, IID_IAvnTopLevel)
END_INTERFACE_MAP()
virtual ~TopLevelImpl();
TopLevelImpl(IAvnTopLevelEvents* events);
virtual AvnView *GetNSView() override;
virtual HRESULT SetCursor(IAvnCursor* cursor) override;
virtual HRESULT GetScaling(double*ret) override;
virtual HRESULT GetClientSize(AvnSize *ret) override;
virtual HRESULT GetInputMethod(IAvnTextInputMethod **ppv) override;
virtual HRESULT ObtainNSViewHandle(void** retOut) override;
virtual HRESULT ObtainNSViewHandleRetained(void** retOut) override;
virtual HRESULT CreateSoftwareRenderTarget(IAvnSoftwareRenderTarget** ret) override;
virtual HRESULT CreateMetalRenderTarget(IAvnMetalDevice* device, IAvnMetalRenderTarget** ret) override;
virtual HRESULT CreateGlRenderTarget(IAvnGlContext* context, IAvnGlSurfaceRenderTarget** ret) override;
virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost **retOut) override;
virtual HRESULT Invalidate() override;
virtual HRESULT PointToClient(AvnPoint point, AvnPoint *ret) override;
virtual HRESULT PointToScreen(AvnPoint point, AvnPoint *ret) override;
virtual HRESULT SetTransparencyMode(AvnWindowTransparencyMode mode) override;
protected:
NSCursor *cursor;
virtual void UpdateAppearance();
public:
NSObject<IRenderTarget> *currentRenderTarget;
ComPtr<AvnTextInputMethod> InputMethod;
ComPtr<IAvnTopLevelEvents> TopLevelEvents;
AvnView *View;
void UpdateCursor();
virtual void SetClientSize(NSSize size);
};
#endif /* TopLevelImpl_h */

Просмотреть файл

@ -0,0 +1,251 @@
#import <AppKit/AppKit.h>
#import <Cocoa/Cocoa.h>
#include "automation.h"
#include "cursor.h"
#include "AutoFitContentView.h"
#include "TopLevelImpl.h"
#include "AvnTextInputMethod.h"
#include "AvnView.h"
TopLevelImpl::~TopLevelImpl() {
View = nullptr;
}
TopLevelImpl::TopLevelImpl(IAvnTopLevelEvents *events) {
TopLevelEvents = events;
View = [[AvnView alloc] initWithParent:this];
InputMethod = new AvnTextInputMethod(View);
}
HRESULT TopLevelImpl::GetScaling(double *ret) {
START_COM_CALL;
@autoreleasepool {
if (ret == nullptr)
return E_POINTER;
if ([View window] == nullptr) {
*ret = 1;
return S_OK;
}
*ret = [[View window] backingScaleFactor];
return S_OK;
}
}
HRESULT TopLevelImpl::GetClientSize(AvnSize *ret) {
START_COM_CALL;
@autoreleasepool {
if (ret == nullptr)
return E_POINTER;
NSRect frame = [View frame];
ret->Width = frame.size.width;
ret->Height = frame.size.height;
return S_OK;
}
}
HRESULT TopLevelImpl::GetInputMethod(IAvnTextInputMethod **retOut) {
START_COM_CALL;
*retOut = InputMethod;
return S_OK;
}
HRESULT TopLevelImpl::ObtainNSViewHandle(void **ret) {
START_COM_CALL;
if (ret == nullptr) {
return E_POINTER;
}
*ret = (__bridge void *) View;
return S_OK;
}
HRESULT TopLevelImpl::ObtainNSViewHandleRetained(void **ret) {
START_COM_CALL;
if (ret == nullptr) {
return E_POINTER;
}
*ret = (__bridge_retained void *) View;
return S_OK;
}
HRESULT TopLevelImpl::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 TopLevelImpl::UpdateCursor() {
if (cursor != nil) {
[cursor set];
}
}
HRESULT TopLevelImpl::CreateSoftwareRenderTarget(IAvnSoftwareRenderTarget **ppv) {
START_COM_CALL;
if(![NSThread isMainThread])
return COR_E_INVALIDOPERATION;
if (View == NULL)
return E_FAIL;
auto target = [[IOSurfaceRenderTarget alloc] initWithOpenGlContext: nil];
*ppv = [target createSoftwareRenderTarget];
[View setRenderTarget: target];
return S_OK;
}
HRESULT TopLevelImpl::CreateGlRenderTarget(IAvnGlContext* glContext, IAvnGlSurfaceRenderTarget **ppv) {
START_COM_CALL;
if(![NSThread isMainThread])
return COR_E_INVALIDOPERATION;
if (View == NULL)
return E_FAIL;
auto target = [[IOSurfaceRenderTarget alloc] initWithOpenGlContext: glContext];
*ppv = [target createSurfaceRenderTarget];
[View setRenderTarget: target];
return S_OK;
}
HRESULT TopLevelImpl::CreateMetalRenderTarget(IAvnMetalDevice* device, IAvnMetalRenderTarget **ppv) {
START_COM_CALL;
if(![NSThread isMainThread])
return COR_E_INVALIDOPERATION;
if (View == NULL)
return E_FAIL;
auto target = [[MetalRenderTarget alloc] initWithDevice: device];
[View setRenderTarget: target];
[target getRenderTarget: ppv];
return S_OK;
}
HRESULT TopLevelImpl::CreateNativeControlHost(IAvnNativeControlHost **retOut) {
START_COM_CALL;
if (View == NULL)
return E_FAIL;
*retOut = ::CreateNativeControlHost(View);
return S_OK;
}
AvnView *TopLevelImpl::GetNSView() {
return View;
}
HRESULT TopLevelImpl::Invalidate() {
START_COM_CALL;
@autoreleasepool {
[View setNeedsDisplayInRect:[View frame]];
return S_OK;
}
}
HRESULT TopLevelImpl::PointToClient(AvnPoint point, AvnPoint *ret) {
START_COM_CALL;
@autoreleasepool {
if (ret == nullptr) {
return E_POINTER;
}
auto window = [View window];
if(window == nullptr){
ret = &point;
return S_OK;
}
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 TopLevelImpl::PointToScreen(AvnPoint point, AvnPoint *ret) {
START_COM_CALL;
@autoreleasepool {
if (ret == nullptr) {
return E_POINTER;
}
auto window = [View window];
if(window == nullptr){
ret = &point;
return S_OK;
}
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 TopLevelImpl::SetTransparencyMode(AvnWindowTransparencyMode mode) {
START_COM_CALL;
return S_OK;
}
void TopLevelImpl::UpdateAppearance() {
}
void TopLevelImpl::SetClientSize(NSSize size){
[View setFrameSize:size];
}
extern IAvnTopLevel* CreateAvnTopLevel(IAvnTopLevelEvents* events)
{
@autoreleasepool
{
IAvnTopLevel* ptr = (IAvnTopLevel*)new TopLevelImpl(events);
return ptr;
}
}

Просмотреть файл

@ -9,19 +9,21 @@
#include "rendertarget.h"
#include "INSWindowHolder.h"
#include "AvnTextInputMethod.h"
#include "TopLevelImpl.h"
#include <list>
@class AutoFitContentView;
@class AvnMenu;
@protocol AvnWindowProtocol;
class WindowBaseImpl : public virtual ComObject,
class WindowBaseImpl : public virtual TopLevelImpl,
public virtual IAvnWindowBase,
public INSWindowHolder {
public:
FORWARD_IUNKNOWN()
BEGIN_INTERFACE_MAP()
BEGIN_INTERFACE_MAP()
INHERIT_INTERFACE_MAP(TopLevelImpl)
INTERFACE_MAP_ENTRY(IAvnWindowBase, IID_IAvnWindowBase)
END_INTERFACE_MAP()
@ -33,14 +35,8 @@ BEGIN_INTERFACE_MAP()
virtual HRESULT ObtainNSWindowHandleRetained(void **ret) override;
virtual HRESULT ObtainNSViewHandle(void **ret) override;
virtual HRESULT ObtainNSViewHandleRetained(void **ret) override;
virtual NSWindow *GetNSWindow() override;
virtual AvnView *GetNSView() override;
virtual HRESULT Show(bool activate, bool isDialog) override;
virtual bool IsShown ();
@ -55,18 +51,12 @@ BEGIN_INTERFACE_MAP()
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;
@ -77,49 +67,33 @@ BEGIN_INTERFACE_MAP()
virtual HRESULT SetPosition(AvnPoint point) override;
virtual HRESULT PointToClient(AvnPoint point, AvnPoint *ret) override;
virtual HRESULT PointToScreen(AvnPoint point, AvnPoint *ret) override;
virtual HRESULT SetCursor(IAvnCursor *cursor) override;
virtual void UpdateCursor();
virtual HRESULT CreateSoftwareRenderTarget(IAvnSoftwareRenderTarget **ppv) override;
virtual HRESULT CreateGlRenderTarget(IAvnGlContext* glContext, IAvnGlSurfaceRenderTarget **ppv) override;
virtual HRESULT CreateMetalRenderTarget(IAvnMetalDevice* device, IAvnMetalRenderTarget **ppv) override;
virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost **retOut) override;
virtual HRESULT SetTransparencyMode(AvnWindowTransparencyMode mode) override;
virtual HRESULT SetFrameThemeVariant(AvnPlatformThemeVariant variant) override;
virtual HRESULT BeginDragAndDropOperation(AvnDragDropEffects effects, AvnPoint point,
IAvnClipboard *clipboard, IAvnDndResultCallback *cb,
void *sourceHandle) override;
virtual HRESULT SetTransparencyMode(AvnWindowTransparencyMode mode) override;
virtual bool IsModal();
id<AvnWindowProtocol> GetWindowProtocol ();
virtual void BringToFront ();
virtual HRESULT GetInputMethod(IAvnTextInputMethod **retOut) override;
virtual bool CanZoom() { return false; }
virtual HRESULT SetParent(IAvnWindowBase* parent) override;
protected:
virtual NSWindowStyleMask CalculateStyleMask() = 0;
virtual void UpdateStyle();
virtual void UpdateAppearance() override;
virtual void SetClientSize(NSSize size) override;
private:
void CreateNSWindow (bool isDialog);
void CleanNSWindow ();
NSCursor *cursor;
bool hasPosition;
NSSize lastSize;
NSSize lastMinSize;
@ -128,16 +102,16 @@ private:
bool _inResize;
protected:
AvnPoint lastPositionSet;
AutoFitContentView *StandardContainer;
AvnPoint lastPositionSet;
bool _shown;
std::list<WindowBaseImpl*> _children;
bool _isModal;
public:
NSObject <IRenderTarget> *currentRenderTarget;
WindowBaseImpl* Parent;
NSWindow * Window;
ComPtr<IAvnWindowBaseEvents> BaseEvents;
ComPtr<AvnTextInputMethod> InputMethod;
AvnView *View;
};
#endif //AVALONIA_NATIVE_OSX_WINDOWBASEIMPL_H

Просмотреть файл

@ -15,22 +15,22 @@
#import "WindowProtocol.h"
#import "WindowInterfaces.h"
#include "WindowBaseImpl.h"
#include "WindowImpl.h"
#include "AvnTextInputMethod.h"
#include "AvnView.h"
@class AutoFitContentView;
WindowBaseImpl::~WindowBaseImpl() {
View = nullptr;
Window = nullptr;
}
WindowBaseImpl::WindowBaseImpl(IAvnWindowBaseEvents *events, bool usePanel) {
WindowBaseImpl::WindowBaseImpl(IAvnWindowBaseEvents *events, bool usePanel) : TopLevelImpl(events) {
_children = std::list<WindowBaseImpl*>();
_shown = false;
_inResize = false;
BaseEvents = events;
View = [[AvnView alloc] initWithParent:this];
InputMethod = new AvnTextInputMethod(View);
StandardContainer = [[AutoFitContentView new] initWithContent:View];
lastPositionSet = { 0, 0 };
hasPosition = false;
@ -41,6 +41,8 @@ WindowBaseImpl::WindowBaseImpl(IAvnWindowBaseEvents *events, bool usePanel) {
CreateNSWindow(usePanel);
StandardContainer = [[AutoFitContentView new] initWithContent:View];
[Window setContentView:StandardContainer];
[Window setBackingType:NSBackingStoreBuffered];
[Window setContentMinSize:lastMinSize];
@ -48,38 +50,10 @@ WindowBaseImpl::WindowBaseImpl(IAvnWindowBaseEvents *events, bool usePanel) {
[Window setOpaque:false];
}
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;
}
AvnView *WindowBaseImpl::GetNSView() {
return View;
}
HRESULT WindowBaseImpl::ObtainNSWindowHandleRetained(void **ret) {
START_COM_CALL;
@ -117,7 +91,7 @@ HRESULT WindowBaseImpl::Show(bool activate, bool isDialog) {
auto collectionBehavior = [Window collectionBehavior];
[Window setCollectionBehavior:collectionBehavior & ~NSWindowCollectionBehaviorFullScreenPrimary];
UpdateStyle();
UpdateAppearance();
[Window invalidateShadow];
@ -219,20 +193,6 @@ HRESULT WindowBaseImpl::Close() {
}
}
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;
@ -250,23 +210,6 @@ HRESULT WindowBaseImpl::GetFrameSize(AvnSize *ret) {
}
}
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;
@ -330,7 +273,7 @@ HRESULT WindowBaseImpl::Resize(double x, double y, AvnPlatformResizeReason reaso
lastSize = NSSize{x, y};
[Window setContentSize:lastSize];
SetClientSize(lastSize);
[Window invalidateShadow];
}
}
@ -342,16 +285,6 @@ HRESULT WindowBaseImpl::Resize(double x, double y, AvnPlatformResizeReason reaso
}
}
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;
@ -431,119 +364,6 @@ HRESULT WindowBaseImpl::SetPosition(AvnPoint point) {
}
}
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::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::CreateSoftwareRenderTarget(IAvnSoftwareRenderTarget **ppv) {
START_COM_CALL;
if(![NSThread isMainThread])
return COR_E_INVALIDOPERATION;
if (View == NULL)
return E_FAIL;
auto target = [[IOSurfaceRenderTarget alloc] initWithOpenGlContext: nil];
*ppv = [target createSoftwareRenderTarget];
[View setRenderTarget: target];
return S_OK;
}
HRESULT WindowBaseImpl::CreateGlRenderTarget(IAvnGlContext* glContext, IAvnGlSurfaceRenderTarget **ppv) {
START_COM_CALL;
if(![NSThread isMainThread])
return COR_E_INVALIDOPERATION;
if (View == NULL)
return E_FAIL;
auto target = [[IOSurfaceRenderTarget alloc] initWithOpenGlContext: glContext];
*ppv = [target createSurfaceRenderTarget];
[View setRenderTarget: target];
return S_OK;
}
HRESULT WindowBaseImpl::CreateMetalRenderTarget(IAvnMetalDevice* device, IAvnMetalRenderTarget **ppv) {
START_COM_CALL;
if(![NSThread isMainThread])
return COR_E_INVALIDOPERATION;
if (View == NULL)
return E_FAIL;
auto target = [[MetalRenderTarget alloc] initWithDevice: device];
[View setRenderTarget: target];
[target getRenderTarget: ppv];
return S_OK;
}
HRESULT WindowBaseImpl::CreateNativeControlHost(IAvnNativeControlHost **retOut) {
START_COM_CALL;
if (View == NULL)
return E_FAIL;
*retOut = ::CreateNativeControlHost(View);
return S_OK;
}
HRESULT WindowBaseImpl::SetTransparencyMode(AvnWindowTransparencyMode mode) {
START_COM_CALL;
@ -619,10 +439,14 @@ bool WindowBaseImpl::IsModal() {
return false;
}
void WindowBaseImpl::UpdateStyle() {
void WindowBaseImpl::UpdateAppearance() {
[Window setStyleMask:CalculateStyleMask()];
}
void WindowBaseImpl::SetClientSize(NSSize size){
[Window setContentSize:lastSize];
}
void WindowBaseImpl::CleanNSWindow() {
if(Window != nullptr) {
[GetWindowProtocol() disconnectParent];
@ -654,19 +478,35 @@ void WindowBaseImpl::BringToFront()
// do nothing.
}
HRESULT WindowBaseImpl::GetInputMethod(IAvnTextInputMethod **retOut) {
HRESULT WindowBaseImpl::SetParent(IAvnWindowBase *parent) {
START_COM_CALL;
*retOut = InputMethod;
@autoreleasepool {
if(Parent != nullptr)
{
Parent->_children.remove(this);
}
return S_OK;
}
auto cparent = dynamic_cast<WindowImpl *>(parent);
Parent = cparent;
extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events)
{
@autoreleasepool
{
IAvnWindow* ptr = (IAvnWindow*)new WindowImpl(events);
return ptr;
_isModal = Parent != nullptr;
if(Parent != nullptr && Window != nullptr){
// If one tries to show a child window with a minimized parent window, then the parent window will be
// 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->_children.push_back(this);
UpdateAppearance();
}
return S_OK;
}
}

Просмотреть файл

@ -8,26 +8,9 @@
#import "WindowBaseImpl.h"
#include "IWindowStateChanged.h"
#include <list>
class WindowImpl : public virtual WindowBaseImpl, public virtual IAvnWindow, public IWindowStateChanged
{
private:
bool _isEnabled;
bool _canResize;
bool _fullScreenActive;
SystemDecorations _decorations;
AvnWindowState _lastWindowState;
AvnWindowState _actualWindowState;
bool _inSetWindowState;
NSRect _preZoomSize;
bool _transitioningWindowState;
bool _isClientAreaExtended;
bool _isModal;
WindowImpl* _parent;
std::list<WindowImpl*> _children;
AvnExtendClientAreaChromeHints _extendClientHints;
public:
FORWARD_IUNKNOWN()
BEGIN_INTERFACE_MAP()
INHERIT_INTERFACE_MAP(WindowBaseImpl)
@ -45,8 +28,6 @@ BEGIN_INTERFACE_MAP()
virtual HRESULT SetEnabled (bool enable) override;
virtual HRESULT SetParent (IAvnWindow* parent) override;
void StartStateTransition () override ;
void EndStateTransition () override ;
@ -103,12 +84,23 @@ BEGIN_INTERFACE_MAP()
protected:
virtual NSWindowStyleMask CalculateStyleMask() override;
void UpdateStyle () override;
virtual void UpdateAppearance() override;
private:
void ZOrderChildWindows();
void OnInitialiseNSWindow();
NSString *_lastTitle;
bool _isEnabled;
bool _canResize;
bool _fullScreenActive;
SystemDecorations _decorations;
AvnWindowState _lastWindowState;
AvnWindowState _actualWindowState;
bool _inSetWindowState;
NSRect _preZoomSize;
bool _transitioningWindowState;
bool _isClientAreaExtended;
AvnExtendClientAreaChromeHints _extendClientHints;
};
#endif //AVALONIA_NATIVE_OSX_WINDOWIMPL_H

Просмотреть файл

@ -8,10 +8,10 @@
#include "AvnView.h"
#include "automation.h"
#include "WindowProtocol.h"
#include "WindowImpl.h"
WindowImpl::WindowImpl(IAvnWindowEvents *events) : WindowBaseImpl(events) {
WindowImpl::WindowImpl(IAvnWindowEvents *events) : TopLevelImpl(events), WindowBaseImpl(events, false) {
_isEnabled = true;
_children = std::list<WindowImpl*>();
_isClientAreaExtended = false;
_extendClientHints = AvnDefaultChrome;
_fullScreenActive = false;
@ -22,7 +22,7 @@ WindowImpl::WindowImpl(IAvnWindowEvents *events) : WindowBaseImpl(events) {
_lastWindowState = Normal;
_actualWindowState = Normal;
_lastTitle = @"";
_parent = nullptr;
Parent = nullptr;
WindowEvents = events;
[Window setHasShadow:true];
@ -69,40 +69,7 @@ HRESULT WindowImpl::SetEnabled(bool enable) {
@autoreleasepool {
_isEnabled = enable;
[GetWindowProtocol() setEnabled:enable];
UpdateStyle();
return S_OK;
}
}
HRESULT WindowImpl::SetParent(IAvnWindow *parent) {
START_COM_CALL;
@autoreleasepool {
if(_parent != nullptr)
{
_parent->_children.remove(this);
}
auto cparent = dynamic_cast<WindowImpl *>(parent);
_parent = cparent;
_isModal = _parent != nullptr;
if(_parent != nullptr && Window != nullptr){
// If one tries to show a child window with a minimized parent window, then the parent window will be
// 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->_children.push_back(this);
UpdateStyle();
}
UpdateAppearance();
return S_OK;
}
}
@ -156,12 +123,12 @@ bool WindowImpl::CanBecomeKeyWindow()
void WindowImpl::StartStateTransition() {
_transitioningWindowState = true;
UpdateStyle();
UpdateAppearance();
}
void WindowImpl::EndStateTransition() {
_transitioningWindowState = false;
UpdateStyle();
UpdateAppearance();
// Ensure correct order of child windows after fullscreen transition.
ZOrderChildWindows();
@ -236,7 +203,7 @@ HRESULT WindowImpl::SetCanResize(bool value) {
@autoreleasepool {
_canResize = value;
UpdateStyle();
UpdateAppearance();
return S_OK;
}
}
@ -252,7 +219,7 @@ HRESULT WindowImpl::SetDecorations(SystemDecorations value) {
return S_OK;
}
UpdateStyle();
UpdateAppearance();
switch (_decorations) {
case SystemDecorationsNone:
@ -427,7 +394,7 @@ HRESULT WindowImpl::SetExtendClientArea(bool enable) {
}
[GetWindowProtocol() setIsExtended:enable];
UpdateStyle();
UpdateAppearance();
}
return S_OK;
@ -579,7 +546,7 @@ bool WindowImpl::IsModal() {
}
bool WindowImpl::IsOwned() {
return _parent != nullptr;
return Parent != nullptr;
}
NSWindowStyleMask WindowImpl::CalculateStyleMask() {
@ -620,8 +587,8 @@ NSWindowStyleMask WindowImpl::CalculateStyleMask() {
return s;
}
void WindowImpl::UpdateStyle() {
WindowBaseImpl::UpdateStyle();
void WindowImpl::UpdateAppearance() {
WindowBaseImpl::UpdateAppearance();
if (Window == nil) {
return;
@ -642,3 +609,12 @@ void WindowImpl::UpdateStyle() {
[zoomButton setHidden:!hasTrafficLights];
[zoomButton setEnabled:CanZoom()];
}
extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events)
{
@autoreleasepool
{
IAvnWindow* ptr = (IAvnWindow*)new WindowImpl(events);
return ptr;
}
}

Просмотреть файл

@ -80,7 +80,7 @@ private:
return nil;
}
auto holder = dynamic_cast<INSWindowHolder*>(window);
auto holder = dynamic_cast<INSViewHolder*>(window);
auto view = holder->GetNSView();
return [[AvnRootAccessibilityElement alloc] initWithPeer:peer owner:view];
}

Просмотреть файл

@ -11,6 +11,7 @@
extern IAvnPlatformThreadingInterface* CreatePlatformThreading();
extern void FreeAvnGCHandle(void* handle);
extern void PostDispatcherCallback(IAvnActionCallback* cb);
extern IAvnTopLevel* CreateAvnTopLevel(IAvnTopLevelEvents* events);
extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events);
extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events);
extern IAvnSystemDialogs* CreateSystemDialogs();
@ -46,6 +47,7 @@ extern NSRect ToNSRect (AvnRect r);
extern AvnPoint ToAvnPoint (NSPoint p);
extern AvnPoint ConvertPointY (AvnPoint p);
extern NSSize ToNSSize (AvnSize s);
extern AvnSize FromNSSize (NSSize s);
#ifdef DEBUG
#define NSDebugLog(...) NSLog(__VA_ARGS__)
#else

Просмотреть файл

@ -225,6 +225,19 @@ public:
return (IAvnMacOptions*)new MacOptions();
}
virtual HRESULT CreateTopLevel(IAvnTopLevelEvents* cb,
IAvnTopLevel** ppv) override {
START_COM_CALL;
@autoreleasepool
{
if(cb == nullptr || ppv == nullptr)
return E_POINTER;
*ppv = CreateAvnTopLevel(cb);
return S_OK;
}
}
virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnWindow** ppv) override
{
START_COM_CALL;
@ -484,6 +497,15 @@ NSSize ToNSSize (AvnSize s)
return result;
}
AvnSize FromNSSize (NSSize s)
{
AvnSize result;
result.Width = s.width;
result.Height = s.height;
return result;
}
NSPoint ToNSPoint (AvnPoint p)
{
NSPoint result;

Просмотреть файл

@ -13,6 +13,8 @@
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ANONYMOUSMETHOD_ON_SINGLE_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=f9fce829_002De6f4_002D4cb2_002D80f1_002D5497c44f51df/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
@ -21,4 +23,5 @@
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

Просмотреть файл

@ -100,6 +100,8 @@ namespace Avalonia.Android.Platform.SkiaPlatform
internal InvalidationAwareSurfaceView InternalView => _view;
public double DesktopScaling => RenderScaling;
public IScreenImpl? Screen { get; }
public IPlatformHandle Handle => _view;
public IEnumerable<object> Surfaces { get; }

Просмотреть файл

@ -7,6 +7,7 @@ namespace Avalonia.Android
internal class WindowingPlatformStub : IWindowingPlatform
{
public IWindowImpl CreateWindow() => throw new NotSupportedException();
public ITopLevelImpl CreateEmbeddableTopLevel() => CreateEmbeddableWindow();
public IWindowImpl CreateEmbeddableWindow() => throw new NotSupportedException();

Просмотреть файл

@ -13,7 +13,7 @@ namespace Avalonia.Controls.Embedding
{
}
public EmbeddableControlRoot() : base(PlatformManager.CreateEmbeddableWindow())
public EmbeddableControlRoot() : base(PlatformManager.CreateEmbeddableTopLevel())
{
}

Просмотреть файл

@ -29,6 +29,10 @@ namespace Avalonia.Controls.Embedding.Offscreen
public abstract IEnumerable<object> Surfaces { get; }
public double DesktopScaling => _scaling;
public IScreenImpl? Screen { get; }
public IPlatformHandle? Handle { get; }
public Size ClientSize
{
get => _clientSize;

Просмотреть файл

@ -3,9 +3,7 @@ using System.Collections.Generic;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Layout;
using Avalonia.Metadata;
using Avalonia.Rendering;
using Avalonia.Rendering.Composition;
namespace Avalonia.Platform
@ -20,16 +18,26 @@ namespace Avalonia.Platform
[Unstable]
public interface ITopLevelImpl : IOptionalFeatureProvider, IDisposable
{
/// <summary>
/// Gets the scaling factor for Window positioning and sizing.
/// </summary>
double DesktopScaling { get; }
/// <summary>
/// Gets platform specific display information
/// </summary>
IScreenImpl? Screen { get; }
/// <summary>
/// Get the platform handle.
/// </summary>
IPlatformHandle? Handle { get; }
/// <summary>
/// Gets the client size of the toplevel.
/// </summary>
Size ClientSize { get; }
/// <summary>
/// Gets the total size of the toplevel, excluding shadows.
/// </summary>
Size? FrameSize { get; }
/// <summary>
/// Gets the scaling factor for the toplevel. This is used for rendering.
/// </summary>
@ -123,16 +131,16 @@ namespace Avalonia.Platform
/// Gets the current <see cref="WindowTransparencyLevel"/> of the TopLevel.
/// </summary>
WindowTransparencyLevel TransparencyLevel { get; }
/// <summary>
/// Gets the <see cref="AcrylicPlatformCompensationLevels"/> for the platform.
/// </summary>
AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; }
/// <summary>
/// Sets the <see cref="PlatformThemeVariant"/> on the frame if it should be dark or light.
/// Also applies for the mobile status bar.
/// </summary>
void SetFrameThemeVariant(PlatformThemeVariant themeVariant);
/// <summary>
/// Gets the <see cref="AcrylicPlatformCompensationLevels"/> for the platform.
/// </summary>
AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; }
}
}

Просмотреть файл

@ -1,5 +1,4 @@
using System;
using Avalonia.Automation.Peers;
using Avalonia.Metadata;
namespace Avalonia.Platform
@ -7,6 +6,11 @@ namespace Avalonia.Platform
[Unstable]
public interface IWindowBaseImpl : ITopLevelImpl
{
/// <summary>
/// Gets the total size of the toplevel, excluding shadows.
/// </summary>
Size? FrameSize { get; }
/// <summary>
/// Shows the window.
/// </summary>
@ -18,11 +22,6 @@ namespace Avalonia.Platform
/// Hides the window.
/// </summary>
void Hide();
/// <summary>
/// Gets the scaling factor for Window positioning and sizing.
/// </summary>
double DesktopScaling { get; }
/// <summary>
/// Gets the position of the window in device pixels.
@ -48,11 +47,6 @@ namespace Avalonia.Platform
/// Gets or sets a method called when the window is activated (receives focus).
/// </summary>
Action? Activated { get; set; }
/// <summary>
/// Gets the platform window handle.
/// </summary>
IPlatformHandle Handle { get; }
/// <summary>
/// Gets a maximum client size hint for an auto-sizing window, in device-independent pixels.
@ -63,10 +57,5 @@ namespace Avalonia.Platform
/// Sets whether this window appears on top of all other windows
/// </summary>
void SetTopmost(bool value);
/// <summary>
/// Gets platform specific display information
/// </summary>
IScreenImpl Screen { get; }
}
}

Просмотреть файл

@ -7,6 +7,8 @@ namespace Avalonia.Platform
{
IWindowImpl CreateWindow();
ITopLevelImpl CreateEmbeddableTopLevel();
IWindowImpl CreateEmbeddableWindow();
ITrayIconImpl? CreateTrayIcon();

Просмотреть файл

@ -36,5 +36,11 @@ namespace Avalonia.Controls.Platform
var platform = AvaloniaLocator.Current.GetRequiredService<IWindowingPlatform>();
return platform.CreateEmbeddableWindow();
}
public static ITopLevelImpl CreateEmbeddableTopLevel()
{
var platform = AvaloniaLocator.Current.GetRequiredService<IWindowingPlatform>();
return platform.CreateEmbeddableTopLevel();
}
}
}

Просмотреть файл

@ -12,22 +12,33 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
[PrivateApi]
public class ManagedPopupPositionerPopupImplHelper : IManagedPopupPositionerPopup
{
private readonly IWindowBaseImpl _parent;
private readonly ITopLevelImpl _parent;
public delegate void MoveResizeDelegate(PixelPoint position, Size size, double scaling);
private readonly MoveResizeDelegate _moveResize;
public ManagedPopupPositionerPopupImplHelper(IWindowBaseImpl parent, MoveResizeDelegate moveResize)
public ManagedPopupPositionerPopupImplHelper(ITopLevelImpl parent, MoveResizeDelegate moveResize)
{
_parent = parent;
_moveResize = moveResize;
}
public IReadOnlyList<ManagedPopupPositionerScreenInfo> Screens =>
public IReadOnlyList<ManagedPopupPositionerScreenInfo> Screens
{
get
{
if (_parent.Screen is null)
{
return Array.Empty<ManagedPopupPositionerScreenInfo>();
}
_parent.Screen.AllScreens
.Select(s => new ManagedPopupPositionerScreenInfo(s.Bounds.ToRect(1), s.WorkingArea.ToRect(1)))
.ToArray();
return _parent.Screen.AllScreens
.Select(s => new ManagedPopupPositionerScreenInfo(s.Bounds.ToRect(1), s.WorkingArea.ToRect(1)))
.ToArray();
}
}
public Rect ParentClientAreaScreenGeometry
{

Просмотреть файл

@ -232,11 +232,6 @@ namespace Avalonia.Controls
impl.TransparencyLevelChanged = HandleTransparencyLevelChanged;
CreatePlatformImplBinding(TransparencyLevelHintProperty, hint => PlatformImpl.SetTransparencyLevelHint(hint ?? Array.Empty<WindowTransparencyLevel>()));
CreatePlatformImplBinding(ActualThemeVariantProperty, variant =>
{
variant ??= ThemeVariant.Default;
PlatformImpl.SetFrameThemeVariant((PlatformThemeVariant?)variant ?? PlatformThemeVariant.Light);
});
_keyboardNavigationHandler?.SetOwner(this);
_accessKeyHandler?.SetOwner(this);
@ -253,7 +248,6 @@ namespace Avalonia.Controls
}
ClientSize = impl.ClientSize;
FrameSize = impl.FrameSize;
if (((IStyleHost)this).StylingParent is IResourceHost applicationResources)
{
@ -429,7 +423,7 @@ namespace Avalonia.Controls
/// An <see cref="IPlatformHandle"/> describing the window handle, or null if the handle
/// could not be retrieved.
/// </returns>
public IPlatformHandle? TryGetPlatformHandle() => (PlatformImpl as IWindowBaseImpl)?.Handle;
public IPlatformHandle? TryGetPlatformHandle() => PlatformImpl?.Handle;
private protected void CreatePlatformImplBinding<TValue>(StyledProperty<TValue> property, Action<TValue> onValue)
{
@ -728,7 +722,6 @@ namespace Avalonia.Controls
internal virtual void HandleResized(Size clientSize, WindowResizeReason reason)
{
ClientSize = clientSize;
FrameSize = PlatformImpl!.FrameSize;
Width = clientSize.Width;
Height = clientSize.Height;
LayoutManager.ExecuteLayoutPass();
@ -789,7 +782,6 @@ namespace Avalonia.Controls
/// <param name="e">The event args.</param>
protected virtual void OnOpened(EventArgs e)
{
FrameSize = PlatformImpl?.FrameSize;
Dispatcher.UIThread.Send(_ => Opened?.Invoke(this, e));
}

Просмотреть файл

@ -4,6 +4,7 @@ using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Layout;
using Avalonia.Platform;
using Avalonia.Styling;
namespace Avalonia.Controls
{
@ -47,11 +48,18 @@ namespace Avalonia.Controls
public WindowBase(IWindowBaseImpl impl) : this(impl, AvaloniaLocator.Current)
{
CreatePlatformImplBinding(TopmostProperty, topmost => PlatformImpl!.SetTopmost(topmost));
CreatePlatformImplBinding(ActualThemeVariantProperty, variant =>
{
variant ??= ThemeVariant.Default;
PlatformImpl?.SetFrameThemeVariant((PlatformThemeVariant?)variant ?? PlatformThemeVariant.Light);
});
FrameSize = impl.FrameSize;
}
public WindowBase(IWindowBaseImpl impl, IAvaloniaDependencyResolver? dependencyResolver) : base(impl, dependencyResolver)
{
Screens = new Screens(impl.Screen);
Screens = new Screens(impl.Screen!);
impl.Activated = HandleActivated;
impl.Deactivated = HandleDeactivated;
impl.PositionChanged = HandlePositionChanged;
@ -212,6 +220,8 @@ namespace Avalonia.Controls
/// <inheritdoc/>
protected override void OnOpened(EventArgs e)
{
FrameSize = PlatformImpl?.FrameSize;
// Window must manually raise Loaded/Unloaded events as it is a visual root and
// does not raise OnAttachedToVisualTreeCore/OnDetachedFromVisualTreeCore events
ScheduleOnLoadedCore();

Просмотреть файл

@ -21,6 +21,7 @@ namespace Avalonia.DesignerSupport.Remote
public ITrayIconImpl CreateTrayIcon() => null;
public IWindowImpl CreateWindow() => new WindowStub();
public ITopLevelImpl CreateEmbeddableTopLevel() => CreateEmbeddableWindow();
public IWindowImpl CreateEmbeddableWindow()
{

Просмотреть файл

@ -190,10 +190,10 @@ namespace Avalonia.Native
class GlPlatformSurface : IGlPlatformSurface
{
private readonly IAvnWindowBase _window;
public GlPlatformSurface(IAvnWindowBase window)
private readonly IAvnTopLevel _topLevel;
public GlPlatformSurface(IAvnTopLevel topLevel)
{
_window = window;
_topLevel = topLevel;
}
public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget(IGlContext context)
@ -201,7 +201,7 @@ namespace Avalonia.Native
if (!Dispatcher.UIThread.CheckAccess())
throw new RenderTargetNotReadyException();
var avnContext = (GlContext)context;
return new GlPlatformSurfaceRenderTarget(_window.CreateGlRenderTarget(avnContext.Context), avnContext);
return new GlPlatformSurfaceRenderTarget(_topLevel.CreateGlRenderTarget(avnContext.Context), avnContext);
}
}

Просмотреть файл

@ -30,7 +30,12 @@ namespace Avalonia.Native
public static AvaloniaNativePlatform Initialize(IntPtr factory, AvaloniaNativePlatformOptions options)
{
var result = new AvaloniaNativePlatform(MicroComRuntime.CreateProxyFor<IAvaloniaNativeFactory>(factory, true));
var factoryProxy = MicroComRuntime.CreateProxyFor<IAvaloniaNativeFactory>(factory, true);
AvaloniaLocator.CurrentMutable.Bind<IAvaloniaNativeFactory>().ToConstant(factoryProxy);
var result = new AvaloniaNativePlatform(factoryProxy);
result.DoInitialize(options);
return result;
@ -196,5 +201,10 @@ namespace Avalonia.Native
{
throw new NotImplementedException();
}
public ITopLevelImpl CreateEmbeddableTopLevel()
{
return new EmbeddableTopLevelImpl(_factory);
}
}
}

Просмотреть файл

@ -13,9 +13,9 @@ namespace Avalonia.Native
private IAvnTextInputMethodClient? _nativeClient;
private readonly IAvnTextInputMethod _inputMethod;
public AvaloniaNativeTextInputMethod(IAvnWindowBase nativeWindow)
public AvaloniaNativeTextInputMethod(IAvnTopLevel topLevel)
{
_inputMethod = nativeWindow.InputMethod;
_inputMethod = topLevel.InputMethod;
}
public void Dispose()

Просмотреть файл

@ -9,13 +9,13 @@ namespace Avalonia.Native
internal unsafe class DeferredFramebuffer : ILockedFramebuffer
{
private readonly IAvnSoftwareRenderTarget _renderTarget;
private readonly Action<Action<IAvnWindowBase>> _lockWindow;
private readonly Action<Action<IAvnTopLevel>> _lockTopLevel;
public DeferredFramebuffer(IAvnSoftwareRenderTarget renderTarget, Action<Action<IAvnWindowBase>> lockWindow,
public DeferredFramebuffer(IAvnSoftwareRenderTarget renderTarget, Action<Action<IAvnTopLevel>> lockTopLevel,
int width, int height, Vector dpi)
{
_renderTarget = renderTarget;
_lockWindow = lockWindow;
_lockTopLevel = lockTopLevel;
Address = Marshal.AllocHGlobal(width * height * 4);
Size = new PixelSize(width, height);
RowBytes = width * 4;
@ -35,7 +35,7 @@ namespace Avalonia.Native
if (Address == IntPtr.Zero)
return;
_lockWindow(win =>
_lockTopLevel(win =>
{
var fb = new AvnFramebuffer
{

Просмотреть файл

@ -0,0 +1,15 @@
using Avalonia.Native.Interop;
namespace Avalonia.Native
{
internal class EmbeddableTopLevelImpl : TopLevelImpl
{
public EmbeddableTopLevelImpl(IAvaloniaNativeFactory factory) : base(factory)
{
using (var e = new TopLevelEvents(this))
{
Init(new MacOSTopLevelHandle(factory.CreateTopLevel(e)), factory.CreateScreens());
}
}
}
}

Просмотреть файл

@ -50,11 +50,11 @@ class MetalDevice : IMetalDevice
class MetalPlatformSurface : IMetalPlatformSurface
{
private readonly IAvnWindowBase _window;
private readonly IAvnTopLevel _topLevel;
public MetalPlatformSurface(IAvnWindowBase window)
public MetalPlatformSurface(IAvnTopLevel topLevel)
{
_window = window;
_topLevel = topLevel;
}
public IMetalPlatformSurfaceRenderTarget CreateMetalRenderTarget(IMetalDevice device)
{
@ -62,7 +62,7 @@ class MetalPlatformSurface : IMetalPlatformSurface
throw new RenderTargetNotReadyException();
var dev = (MetalDevice)device;
var target = _window.CreateMetalRenderTarget(dev.Native);
var target = _topLevel.CreateMetalRenderTarget(dev.Native);
return new MetalRenderTarget(target);
}
}

Просмотреть файл

@ -1,5 +1,4 @@
using System;
using Avalonia.Controls;
using Avalonia.Controls;
using Avalonia.Controls.Primitives.PopupPositioning;
using Avalonia.Native.Interop;
using Avalonia.Platform;
@ -8,17 +7,37 @@ namespace Avalonia.Native
{
class PopupImpl : WindowBaseImpl, IPopupImpl
{
private readonly IWindowBaseImpl _parent;
private readonly ITopLevelImpl _parent;
private readonly IAvnPopup _native;
private readonly AvaloniaNativeTextInputMethod _inputMethod;
public PopupImpl(IAvaloniaNativeFactory factory,
IWindowBaseImpl parent) : base(factory)
ITopLevelImpl parent) : base(factory)
{
_parent = parent;
using (var e = new PopupEvents(this))
{
Init(factory.CreatePopup(e), factory.CreateScreens());
Init(new MacOSTopLevelHandle(_native = factory.CreatePopup(e)), factory.CreateScreens());
}
PopupPositioner = new ManagedPopupPositioner(new ManagedPopupPositionerPopupImplHelper(parent, MoveResize));
while (parent is PopupImpl popupImpl)
{
parent = popupImpl._parent;
}
//Use the parent's input context to process events
if (parent is TopLevelImpl topLevelImpl)
{
_inputMethod = topLevelImpl.InputMethod;
}
}
internal sealed override void Init(MacOSTopLevelHandle handle, IAvnScreens screens)
{
base.Init(handle, screens);
}
private void MoveResize(PixelPoint position, Size size, double scaling)
@ -62,7 +81,7 @@ namespace Avalonia.Native
base.Show(false, isDialog);
}
public override IPopupImpl CreatePopup() => new PopupImpl(_factory, this);
public override IPopupImpl CreatePopup() => new PopupImpl(Factory, this);
public void SetWindowManagerAddShadowHint(bool enabled)
{

Просмотреть файл

@ -14,12 +14,12 @@ namespace Avalonia.Native
{
internal class SystemDialogs : BclStorageProvider
{
private readonly WindowBaseImpl _window;
private readonly TopLevelImpl _topLevel;
private readonly IAvnSystemDialogs _native;
public SystemDialogs(WindowBaseImpl window, IAvnSystemDialogs native)
public SystemDialogs(TopLevelImpl topLevel, IAvnSystemDialogs native)
{
_window = window;
_topLevel = topLevel;
_native = native;
}
@ -36,7 +36,7 @@ namespace Avalonia.Native
var suggestedDirectory = options.SuggestedStartLocation?.TryGetLocalPath() ?? string.Empty;
_native.OpenFileDialog((IAvnWindow)_window.Native,
_native.OpenFileDialog((IAvnWindow)_topLevel.Native,
events,
options.AllowMultiple.AsComBool(),
options.Title ?? string.Empty,
@ -57,7 +57,7 @@ namespace Avalonia.Native
var suggestedDirectory = options.SuggestedStartLocation?.TryGetLocalPath() ?? string.Empty;
_native.SaveFileDialog((IAvnWindow)_window.Native,
_native.SaveFileDialog((IAvnWindow)_topLevel.Native,
events,
options.Title ?? string.Empty,
suggestedDirectory,
@ -76,7 +76,7 @@ namespace Avalonia.Native
var suggestedDirectory = options.SuggestedStartLocation?.TryGetLocalPath() ?? string.Empty;
_native.SelectFolderDialog((IAvnWindow)_window.Native, events, options.AllowMultiple.AsComBool(), options.Title ?? "", suggestedDirectory);
_native.SelectFolderDialog((IAvnWindow)_topLevel.Native, events, options.AllowMultiple.AsComBool(), options.Title ?? "", suggestedDirectory);
var result = await events.Task.ConfigureAwait(false);
return result?.Select(f => new BclStorageFolder(new DirectoryInfo(f))).ToArray()

Просмотреть файл

@ -0,0 +1,557 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Avalonia.Automation.Peers;
using Avalonia.Controls;
using Avalonia.Controls.Platform;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Input.Raw;
using Avalonia.Input.TextInput;
using Avalonia.Native.Interop;
using Avalonia.Platform;
using Avalonia.Platform.Storage;
using Avalonia.Platform.Storage.FileIO;
using Avalonia.Rendering.Composition;
using Avalonia.Threading;
namespace Avalonia.Native;
internal class MacOSTopLevelHandle : IPlatformHandle, IMacOSTopLevelPlatformHandle
{
internal MacOSTopLevelHandle(IAvnTopLevel native)
{
Native = native;
HandleDescriptor = "NSView";
Handle = NSView;
}
internal MacOSTopLevelHandle(IAvnWindowBase native)
{
Native = native;
HandleDescriptor = "NSWindow";
Handle = NSWindow;
}
internal IAvnTopLevel Native { get; }
public IntPtr Handle { get; }
public string HandleDescriptor { get; }
public IntPtr NSView => Native.ObtainNSViewHandle();
public IntPtr GetNSViewRetained()
{
return Native.ObtainNSViewHandleRetained();
}
public IntPtr NSWindow => (Native as IAvnWindowBase)?.ObtainNSWindowHandle() ?? IntPtr.Zero;
public IntPtr GetNSWindowRetained()
{
return (Native as IAvnWindowBase)?.ObtainNSWindowHandleRetained() ?? IntPtr.Zero;
}
}
internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface
{
protected IInputRoot? _inputRoot;
private NativeControlHostImpl? _nativeControlHost;
private IStorageProvider? _storageProvider;
private PlatformBehaviorInhibition? _platformBehaviorInhibition;
private readonly MouseDevice? _mouse;
private readonly IKeyboardDevice? _keyboard;
private readonly ICursorFactory? _cursorFactory;
protected readonly IAvaloniaNativeFactory Factory;
private Size _savedLogicalSize;
private double _savedScaling;
private WindowTransparencyLevel _transparencyLevel = WindowTransparencyLevel.None;
protected MacOSTopLevelHandle? _handle;
private object _syncRoot = new object();
private IEnumerable<object>? _surfaces;
public TopLevelImpl(IAvaloniaNativeFactory factory)
{
Factory = factory;
_keyboard = AvaloniaLocator.Current.GetService<IKeyboardDevice>();
_mouse = new MouseDevice();
_cursorFactory = AvaloniaLocator.Current.GetService<ICursorFactory>();
}
internal virtual void Init(MacOSTopLevelHandle handle, IAvnScreens screens)
{
_handle = handle;
_savedLogicalSize = ClientSize;
_savedScaling = RenderScaling;
_nativeControlHost = new NativeControlHostImpl(Native!.CreateNativeControlHost());
_storageProvider = new SystemDialogs(this, Factory.CreateSystemDialogs());
_platformBehaviorInhibition = new PlatformBehaviorInhibition(Factory.CreatePlatformBehaviorInhibition());
_surfaces = new object[] { new GlPlatformSurface(Native), new MetalPlatformSurface(Native), this };
Screen = new ScreenImpl(screens);
InputMethod = new AvaloniaNativeTextInputMethod(Native);
}
public double DesktopScaling => 1;
public IAvnTopLevel? Native => _handle?.Native;
public IPlatformHandle? Handle => _handle;
public AvaloniaNativeTextInputMethod? InputMethod { get; private set; }
public Size ClientSize
{
get
{
if (Native == null)
{
return default;
}
var s = Native.ClientSize;
return new Size(s.Width, s.Height);
}
}
public double RenderScaling => Native?.Scaling ?? 1;
public IEnumerable<object> Surfaces => _surfaces ?? Array.Empty<object>();
public Action<RawInputEventArgs>? Input { get; set; }
public Action<Rect>? Paint { get; set; }
public Action<Size, WindowResizeReason>? Resized { get; set; }
public Action<double>? ScalingChanged { get; set; }
public Action<WindowTransparencyLevel>? TransparencyLevelChanged { get; set; }
public Compositor Compositor => AvaloniaNativePlatform.Compositor;
public Action? Closed { get; set; }
public Action? LostFocus { get; set; }
public WindowTransparencyLevel TransparencyLevel
{
get => _transparencyLevel;
private set
{
if (_transparencyLevel != value)
{
_transparencyLevel = value;
TransparencyLevelChanged?.Invoke(value);
}
}
}
public AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; } = new AcrylicPlatformCompensationLevels(1, 0, 0);
public virtual void SetFrameThemeVariant(PlatformThemeVariant themeVariant)
{
//noop
}
public IMouseDevice? MouseDevice => _mouse;
public INativeControlHostImpl? NativeControlHost => _nativeControlHost;
public IScreenImpl? Screen { get; private set; }
public AutomationPeer? GetAutomationPeer()
{
return _inputRoot is Control c ? ControlAutomationPeer.CreatePeerForElement(c) : null;
}
public bool RawTextInputEvent(ulong timeStamp, string text)
{
if (_inputRoot is null)
return false;
if (_keyboard is null)
{
return false;
}
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
var args = new RawTextInputEventArgs(_keyboard, timeStamp, _inputRoot, text);
Input?.Invoke(args);
return args.Handled;
}
public bool RawKeyEvent(
AvnRawKeyEventType type,
ulong timeStamp,
AvnInputModifiers modifiers,
AvnKey key,
AvnPhysicalKey physicalKey,
string keySymbol)
{
if (_inputRoot is null)
return false;
if (_keyboard is null)
{
return false;
}
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
var args = new RawKeyEventArgs(
_keyboard,
timeStamp,
_inputRoot,
(RawKeyEventType)type,
(Key)key,
(RawInputModifiers)modifiers,
(PhysicalKey)physicalKey,
keySymbol);
Input?.Invoke(args);
return args.Handled;
}
public void RawMouseEvent(AvnRawMouseEventType type, ulong timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta)
{
if (_inputRoot is null)
return;
if (_mouse is null)
{
return;
}
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
switch (type)
{
case AvnRawMouseEventType.Wheel:
Input?.Invoke(new RawMouseWheelEventArgs(_mouse, timeStamp, _inputRoot,
point.ToAvaloniaPoint(), new Vector(delta.X, delta.Y), (RawInputModifiers)modifiers));
break;
case AvnRawMouseEventType.Magnify:
Input?.Invoke(new RawPointerGestureEventArgs(_mouse, timeStamp, _inputRoot, RawPointerEventType.Magnify,
point.ToAvaloniaPoint(), new Vector(delta.X, delta.Y), (RawInputModifiers)modifiers));
break;
case AvnRawMouseEventType.Rotate:
Input?.Invoke(new RawPointerGestureEventArgs(_mouse, timeStamp, _inputRoot, RawPointerEventType.Rotate,
point.ToAvaloniaPoint(), new Vector(delta.X, delta.Y), (RawInputModifiers)modifiers));
break;
case AvnRawMouseEventType.Swipe:
Input?.Invoke(new RawPointerGestureEventArgs(_mouse, timeStamp, _inputRoot, RawPointerEventType.Swipe,
point.ToAvaloniaPoint(), new Vector(delta.X, delta.Y), (RawInputModifiers)modifiers));
break;
default:
var e = new RawPointerEventArgs(_mouse, timeStamp, _inputRoot, (RawPointerEventType)type,
point.ToAvaloniaPoint(), (RawInputModifiers)modifiers);
if (!ChromeHitTest(e))
{
Input?.Invoke(e);
}
break;
}
}
public void Invalidate()
{
Native?.Invalidate();
}
public void SetInputRoot(IInputRoot inputRoot)
{
_inputRoot = inputRoot;
}
public Point PointToClient(PixelPoint point)
{
return Native?.PointToClient(point.ToAvnPoint()).ToAvaloniaPoint() ?? default;
}
public PixelPoint PointToScreen(Point point)
{
return Native?.PointToScreen(point.ToAvnPoint()).ToAvaloniaPixelPoint() ?? default;
}
public void SetCursor(ICursorImpl? cursor)
{
if (Native == null)
{
return;
}
var newCursor = cursor as AvaloniaNativeCursor;
newCursor ??= (_cursorFactory?.GetCursor(StandardCursorType.Arrow) as AvaloniaNativeCursor);
Native.SetCursor(newCursor?.Cursor);
}
public virtual IPopupImpl CreatePopup()
{
return new PopupImpl(Factory, this);
}
public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevels)
{
foreach (var level in transparencyLevels)
{
AvnWindowTransparencyMode? mode = null;
if (level == WindowTransparencyLevel.None)
mode = AvnWindowTransparencyMode.Opaque;
if (level == WindowTransparencyLevel.Transparent)
mode = AvnWindowTransparencyMode.Transparent;
else if (level == WindowTransparencyLevel.AcrylicBlur)
mode = AvnWindowTransparencyMode.Blur;
if (mode.HasValue && level != TransparencyLevel)
{
Native?.SetTransparencyMode(mode.Value);
TransparencyLevel = level;
return;
}
}
// If we get here, we didn't find a supported level. Use the default of None.
if (TransparencyLevel != WindowTransparencyLevel.None)
{
Native?.SetTransparencyMode(AvnWindowTransparencyMode.Opaque);
TransparencyLevel = WindowTransparencyLevel.None;
}
}
public virtual object? TryGetFeature(Type featureType)
{
if (featureType == typeof(ITextInputMethodImpl))
{
return InputMethod;
}
if (featureType == typeof(INativeControlHostImpl))
{
return _nativeControlHost;
}
if (featureType == typeof(IStorageProvider))
{
return _storageProvider;
}
if (featureType == typeof(IPlatformBehaviorInhibition))
{
return _platformBehaviorInhibition;
}
if (featureType == typeof(IClipboard))
{
return AvaloniaLocator.Current.GetRequiredService<IClipboard>();
}
if (featureType == typeof(ILauncher))
{
return new BclLauncher();
}
return null;
}
public virtual void Dispose()
{
Native?.Dispose();
_handle = null;
_nativeControlHost?.Dispose();
_nativeControlHost = null;
(Screen as ScreenImpl)?.Dispose();
_mouse?.Dispose();
}
protected virtual bool ChromeHitTest(RawPointerEventArgs e)
{
return false;
}
IFramebufferRenderTarget IFramebufferPlatformSurface.CreateFramebufferRenderTarget()
{
if (!Dispatcher.UIThread.CheckAccess())
throw new RenderTargetNotReadyException();
var nativeRenderTarget = Native?.CreateSoftwareRenderTarget();
if (nativeRenderTarget is null)
{
throw new RenderTargetNotReadyException();
}
return new FramebufferRenderTarget(this, nativeRenderTarget);
}
protected internal unsafe class TopLevelEvents : NativeCallbackBase, IAvnTopLevelEvents
{
private readonly TopLevelImpl _parent;
public TopLevelEvents(TopLevelImpl parent)
{
_parent = parent;
}
void IAvnTopLevelEvents.Closed()
{
var n = _parent.Native;
try
{
_parent?.Closed?.Invoke();
}
finally
{
_parent?.Dispose();
n?.Dispose();
}
}
void IAvnTopLevelEvents.Paint()
{
Dispatcher.UIThread.RunJobs(DispatcherPriority.UiThreadRender);
var s = _parent.ClientSize;
_parent.Paint?.Invoke(new Rect(0, 0, s.Width, s.Height));
}
void IAvnTopLevelEvents.Resized(AvnSize* size, AvnPlatformResizeReason reason)
{
if (_parent?.Native == null)
{
return;
}
var s = new Size(size->Width, size->Height);
_parent._savedLogicalSize = s;
_parent.Resized?.Invoke(s, (WindowResizeReason)reason);
}
void IAvnTopLevelEvents.RawMouseEvent(AvnRawMouseEventType type, ulong timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta)
{
_parent.RawMouseEvent(type, timeStamp, modifiers, point, delta);
}
int IAvnTopLevelEvents.RawKeyEvent(AvnRawKeyEventType type, ulong timeStamp, AvnInputModifiers modifiers, AvnKey key, AvnPhysicalKey physicalKey, string keySymbol)
{
return _parent.RawKeyEvent(type, timeStamp, modifiers, key, physicalKey, keySymbol).AsComBool();
}
int IAvnTopLevelEvents.RawTextInputEvent(ulong timeStamp, string text)
{
return _parent.RawTextInputEvent(timeStamp, text).AsComBool();
}
void IAvnTopLevelEvents.ScalingChanged(double scaling)
{
_parent._savedScaling = scaling;
_parent.ScalingChanged?.Invoke(scaling);
}
void IAvnTopLevelEvents.RunRenderPriorityJobs()
{
Dispatcher.UIThread.RunJobs(DispatcherPriority.UiThreadRender);
}
void IAvnTopLevelEvents.LostFocus()
{
_parent.LostFocus?.Invoke();
}
AvnDragDropEffects IAvnTopLevelEvents.DragEvent(AvnDragEventType type, AvnPoint position,
AvnInputModifiers modifiers,
AvnDragDropEffects effects,
IAvnClipboard clipboard, IntPtr dataObjectHandle)
{
var device = AvaloniaLocator.Current.GetService<IDragDropDevice>();
if (device is null)
{
return AvnDragDropEffects.None;
}
if (_parent._inputRoot is null)
{
return AvnDragDropEffects.None;
}
IDataObject? dataObject = null;
if (dataObjectHandle != IntPtr.Zero)
dataObject = GCHandle.FromIntPtr(dataObjectHandle).Target as IDataObject;
using (var clipboardDataObject = new ClipboardDataObject(clipboard))
{
if (dataObject == null)
dataObject = clipboardDataObject;
var args = new RawDragEvent(device, (RawDragEventType)type,
_parent._inputRoot, position.ToAvaloniaPoint(), dataObject, (DragDropEffects)effects,
(RawInputModifiers)modifiers);
_parent.Input(args);
return (AvnDragDropEffects)args.Effects;
}
}
IAvnAutomationPeer? IAvnTopLevelEvents.AutomationPeer
{
get
{
var native = _parent.GetAutomationPeer();
return native is null ? null : AvnAutomationPeer.Wrap(native);
}
}
}
private class FramebufferRenderTarget : IFramebufferRenderTarget
{
private readonly TopLevelImpl _parent;
private IAvnSoftwareRenderTarget? _target;
public FramebufferRenderTarget(TopLevelImpl parent, IAvnSoftwareRenderTarget target)
{
_parent = parent;
_target = target;
}
public void Dispose()
{
lock (_parent._syncRoot)
{
_target?.Dispose();
_target = null;
}
}
public ILockedFramebuffer Lock()
{
var w = _parent._savedLogicalSize.Width * _parent._savedScaling;
var h = _parent._savedLogicalSize.Height * _parent._savedScaling;
var dpi = _parent._savedScaling * 96;
return new DeferredFramebuffer(_target, cb =>
{
lock (_parent._syncRoot)
{
if (_parent.Native != null && _target != null)
{
cb(_parent.Native);
}
}
}, (int)w, (int)h, new Vector(dpi, dpi));
}
}
}

Просмотреть файл

@ -16,7 +16,6 @@ namespace Avalonia.Native
private double _extendTitleBarHeight = -1;
private DoubleClickHelper _doubleClickHelper;
private readonly ITopLevelNativeMenuExporter _nativeMenuExporter;
private readonly AvaloniaNativeTextInputMethod _inputMethod;
private bool _canResize = true;
internal WindowImpl(IAvaloniaNativeFactory factory, AvaloniaNativePlatformOptions opts) : base(factory)
@ -26,12 +25,15 @@ namespace Avalonia.Native
using (var e = new WindowEvents(this))
{
Init(_native = factory.CreateWindow(e), factory.CreateScreens());
Init(new MacOSTopLevelHandle(_native = factory.CreateWindow(e)), factory.CreateScreens());
}
_nativeMenuExporter = new AvaloniaNativeMenuExporter(_native, factory);
_inputMethod = new AvaloniaNativeTextInputMethod(_native);
}
internal sealed override void Init(MacOSTopLevelHandle handle, IAvnScreens screens)
{
base.Init(handle, screens);
}
class WindowEvents : WindowBaseEvents, IAvnWindowEvents
@ -65,7 +67,7 @@ namespace Avalonia.Native
_parent.GotInputWhenDisabled?.Invoke();
}
}
public new IAvnWindow Native => _native;
public void CanResize(bool value)
@ -211,7 +213,7 @@ namespace Avalonia.Native
public void Move(PixelPoint point) => Position = point;
public override IPopupImpl CreatePopup() =>
_opts.OverlayPopups ? null : new PopupImpl(_factory, this);
_opts.OverlayPopups ? null : new PopupImpl(Factory, this);
public Action GotInputWhenDisabled { get; set; }
@ -229,7 +231,7 @@ namespace Avalonia.Native
{
if(featureType == typeof(ITextInputMethodImpl))
{
return _inputMethod;
return InputMethod;
}
if (featureType == typeof(ITopLevelNativeMenuExporter))

Просмотреть файл

@ -1,123 +1,44 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using Avalonia.Automation.Peers;
using Avalonia.Controls;
using Avalonia.Controls.Platform;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Input.Raw;
using Avalonia.Native.Interop;
using Avalonia.Platform;
using Avalonia.Platform.Storage;
using Avalonia.Platform.Storage.FileIO;
using Avalonia.Rendering.Composition;
using Avalonia.Threading;
namespace Avalonia.Native
{
internal class MacOSTopLevelWindowHandle : IPlatformHandle, IMacOSTopLevelPlatformHandle
internal abstract class WindowBaseImpl : TopLevelImpl, IWindowBaseImpl
{
IAvnWindowBase _native;
public MacOSTopLevelWindowHandle(IAvnWindowBase native)
internal WindowBaseImpl(IAvaloniaNativeFactory factory) : base(factory)
{
_native = native;
}
public IntPtr Handle => NSWindow;
public new IAvnWindowBase? Native => _handle?.Native as IAvnWindowBase;
public string HandleDescriptor => "NSWindow";
public IntPtr NSView => _native?.ObtainNSViewHandle() ?? IntPtr.Zero;
public IntPtr NSWindow => _native?.ObtainNSWindowHandle() ?? IntPtr.Zero;
public IntPtr GetNSViewRetained()
public PixelPoint Position
{
return _native?.ObtainNSViewHandleRetained() ?? IntPtr.Zero;
get => Native?.Position.ToAvaloniaPixelPoint() ?? default;
set => Native?.SetPosition(value.ToAvnPoint());
}
public IntPtr GetNSWindowRetained()
{
return _native?.ObtainNSWindowHandleRetained() ?? IntPtr.Zero;
}
}
public Action? Deactivated { get; set; }
public Action? Activated { get; set; }
internal abstract class WindowBaseImpl : IWindowBaseImpl,
IFramebufferPlatformSurface
{
protected readonly IAvaloniaNativeFactory _factory;
protected IInputRoot _inputRoot;
IAvnWindowBase _native;
private object _syncRoot = new object();
private readonly MouseDevice _mouse;
private readonly IKeyboardDevice _keyboard;
private readonly ICursorFactory _cursorFactory;
private Size _savedLogicalSize;
private double _savedScaling;
private NativeControlHostImpl _nativeControlHost;
private IStorageProvider _storageProvider;
private PlatformBehaviorInhibition _platformBehaviorInhibition;
private WindowTransparencyLevel _transparencyLevel = WindowTransparencyLevel.None;
internal WindowBaseImpl(IAvaloniaNativeFactory factory)
{
_factory = factory;
_keyboard = AvaloniaLocator.Current.GetService<IKeyboardDevice>();
_mouse = new MouseDevice();
_cursorFactory = AvaloniaLocator.Current.GetService<ICursorFactory>();
}
protected void Init(IAvnWindowBase window, IAvnScreens screens)
{
_native = window;
Surfaces = new object[] { new GlPlatformSurface(window), new MetalPlatformSurface(window), this };
Handle = new MacOSTopLevelWindowHandle(window);
Screen = new ScreenImpl(screens);
_savedLogicalSize = ClientSize;
_savedScaling = RenderScaling;
_nativeControlHost = new NativeControlHostImpl(_native.CreateNativeControlHost());
_storageProvider = new SystemDialogs(this, _factory.CreateSystemDialogs());
_platformBehaviorInhibition = new PlatformBehaviorInhibition(_factory.CreatePlatformBehaviorInhibition());
var monitor = Screen.AllScreens.OrderBy(x => x.Scaling)
.FirstOrDefault(m => m.Bounds.Contains(Position));
Resize(new Size(monitor.WorkingArea.Width * 0.75d, monitor.WorkingArea.Height * 0.7d), WindowResizeReason.Layout);
}
public IAvnWindowBase Native => _native;
public Size ClientSize
{
get
{
if (_native != null)
{
var s = _native.ClientSize;
return new Size(s.Width, s.Height);
}
return default;
}
}
public Action<PixelPoint>? PositionChanged { get; set; }
public Size? FrameSize
{
get
{
if (_native != null)
if (Native != null)
{
unsafe
{
var s = new AvnSize { Width = -1, Height = -1 };
_native.GetFrameSize(&s);
Native.GetFrameSize(&s);
return s.Width < 0 && s.Height < 0 ? null : new Size(s.Width, s.Height);
}
}
@ -125,471 +46,98 @@ namespace Avalonia.Native
return default;
}
}
public IEnumerable<object> Surfaces { get; private set; }
public INativeControlHostImpl NativeControlHost => _nativeControlHost;
IFramebufferRenderTarget IFramebufferPlatformSurface.CreateFramebufferRenderTarget()
{
if (!Dispatcher.UIThread.CheckAccess())
throw new RenderTargetNotReadyException();
return new FramebufferRenderTarget(this, _native.CreateSoftwareRenderTarget());
}
class FramebufferRenderTarget : IFramebufferRenderTarget
{
private readonly WindowBaseImpl _parent;
private IAvnSoftwareRenderTarget _target;
public FramebufferRenderTarget(WindowBaseImpl parent, IAvnSoftwareRenderTarget target)
{
_parent = parent;
_target = target;
}
public void Dispose()
{
lock (_parent._syncRoot)
{
_target?.Dispose();
_target = null;
}
}
public ILockedFramebuffer Lock()
{
var w = _parent._savedLogicalSize.Width * _parent._savedScaling;
var h = _parent._savedLogicalSize.Height * _parent._savedScaling;
var dpi = _parent._savedScaling * 96;
return new DeferredFramebuffer(_target, cb =>
{
lock (_parent._syncRoot)
{
if (_parent._native != null && _target != null)
{
cb(_parent._native);
}
}
}, (int)w, (int)h, new Vector(dpi, dpi));
}
}
public Action LostFocus { get; set; }
public Action<Rect> Paint { get; set; }
public Action<Size, WindowResizeReason> Resized { get; set; }
public Action Closed { get; set; }
public IMouseDevice MouseDevice => _mouse;
public abstract IPopupImpl CreatePopup();
public AutomationPeer GetAutomationPeer()
internal override void Init(MacOSTopLevelHandle handle, IAvnScreens screens)
{
return _inputRoot is Control c ? ControlAutomationPeer.CreatePeerForElement(c) : null;
_handle = handle;
base.Init(handle, screens);
var monitor = Screen!.AllScreens.OrderBy(x => x.Scaling)
.FirstOrDefault(m => m.Bounds.Contains(Position));
Resize(new Size(monitor!.WorkingArea.Width * 0.75d, monitor.WorkingArea.Height * 0.7d), WindowResizeReason.Layout);
}
protected unsafe class WindowBaseEvents : NativeCallbackBase, IAvnWindowBaseEvents
public void Activate()
{
Native?.Activate();
}
public void Resize(Size clientSize, WindowResizeReason reason)
{
Native?.Resize(clientSize.Width, clientSize.Height, (AvnPlatformResizeReason)reason);
}
public override void SetFrameThemeVariant(PlatformThemeVariant themeVariant)
{
Native?.SetFrameThemeVariant((AvnPlatformThemeVariant)themeVariant);
}
public override void Dispose()
{
Native?.Close();
Native?.Dispose();
_handle = null;
}
public virtual void Show(bool activate, bool isDialog)
{
Native?.Show(activate.AsComBool(), isDialog.AsComBool());
}
public void Hide()
{
Native?.Hide();
}
public void BeginMoveDrag(PointerPressedEventArgs e)
{
Native?.BeginMoveDrag();
}
public Size MaxAutoSizeHint => Screen!.AllScreens.Select(s => s.Bounds.Size.ToSize(1))
.OrderByDescending(x => x.Width + x.Height).FirstOrDefault();
public void SetTopmost(bool value)
{
Native?.SetTopMost(value.AsComBool());
}
// TODO
public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e)
{
}
public void SetMinMaxSize(Size minSize, Size maxSize)
{
Native?.SetMinMaxSize(minSize.ToAvnSize(), maxSize.ToAvnSize());
}
internal void BeginDraggingSession(AvnDragDropEffects effects, AvnPoint point, IAvnClipboard clipboard,
IAvnDndResultCallback callback, IntPtr sourceHandle)
{
Native?.BeginDragAndDropOperation(effects, point, clipboard, callback, sourceHandle);
}
protected class WindowBaseEvents : TopLevelEvents, IAvnWindowBaseEvents
{
private readonly WindowBaseImpl _parent;
public WindowBaseEvents(WindowBaseImpl parent)
public WindowBaseEvents(WindowBaseImpl parent) : base(parent)
{
_parent = parent;
}
void IAvnWindowBaseEvents.Closed()
{
var n = _parent._native;
try
{
_parent?.Closed?.Invoke();
}
finally
{
_parent?.Dispose();
n?.Dispose();
}
}
void IAvnWindowBaseEvents.Activated() => _parent.Activated?.Invoke();
void IAvnWindowBaseEvents.Deactivated() => _parent.Deactivated?.Invoke();
void IAvnWindowBaseEvents.Paint()
{
Dispatcher.UIThread.RunJobs(DispatcherPriority.UiThreadRender);
var s = _parent.ClientSize;
_parent.Paint?.Invoke(new Rect(0, 0, s.Width, s.Height));
}
void IAvnWindowBaseEvents.Resized(AvnSize* size, AvnPlatformResizeReason reason)
{
if (_parent?._native != null)
{
var s = new Size(size->Width, size->Height);
_parent._savedLogicalSize = s;
_parent.Resized?.Invoke(s, (WindowResizeReason)reason);
}
}
void IAvnWindowBaseEvents.PositionChanged(AvnPoint position)
{
_parent.PositionChanged?.Invoke(position.ToAvaloniaPixelPoint());
}
void IAvnWindowBaseEvents.RawMouseEvent(AvnRawMouseEventType type, ulong timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta)
{
_parent.RawMouseEvent(type, timeStamp, modifiers, point, delta);
}
void IAvnWindowBaseEvents.Activated() => _parent.Activated?.Invoke();
int IAvnWindowBaseEvents.RawKeyEvent(AvnRawKeyEventType type, ulong timeStamp, AvnInputModifiers modifiers, AvnKey key, AvnPhysicalKey physicalKey, string keySymbol)
{
return _parent.RawKeyEvent(type, timeStamp, modifiers, key, physicalKey, keySymbol).AsComBool();
}
int IAvnWindowBaseEvents.RawTextInputEvent(ulong timeStamp, string text)
{
return _parent.RawTextInputEvent(timeStamp, text).AsComBool();
}
void IAvnWindowBaseEvents.ScalingChanged(double scaling)
{
_parent._savedScaling = scaling;
_parent.ScalingChanged?.Invoke(scaling);
}
void IAvnWindowBaseEvents.RunRenderPriorityJobs()
{
Dispatcher.UIThread.RunJobs(DispatcherPriority.UiThreadRender);
}
void IAvnWindowBaseEvents.LostFocus()
{
_parent.LostFocus?.Invoke();
}
public AvnDragDropEffects DragEvent(AvnDragEventType type, AvnPoint position,
AvnInputModifiers modifiers,
AvnDragDropEffects effects,
IAvnClipboard clipboard, IntPtr dataObjectHandle)
{
var device = AvaloniaLocator.Current.GetService<IDragDropDevice>();
IDataObject dataObject = null;
if (dataObjectHandle != IntPtr.Zero)
dataObject = GCHandle.FromIntPtr(dataObjectHandle).Target as IDataObject;
using(var clipboardDataObject = new ClipboardDataObject(clipboard))
{
if (dataObject == null)
dataObject = clipboardDataObject;
var args = new RawDragEvent(device, (RawDragEventType)type,
_parent._inputRoot, position.ToAvaloniaPoint(), dataObject, (DragDropEffects)effects,
(RawInputModifiers)modifiers);
_parent.Input(args);
return (AvnDragDropEffects)args.Effects;
}
}
IAvnAutomationPeer IAvnWindowBaseEvents.AutomationPeer
{
get => AvnAutomationPeer.Wrap(_parent.GetAutomationPeer());
}
void IAvnWindowBaseEvents.Deactivated() => _parent.Deactivated?.Invoke();
}
public void Activate()
{
_native?.Activate();
}
public bool RawTextInputEvent(ulong timeStamp, string text)
{
if (_inputRoot is null)
return false;
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
var args = new RawTextInputEventArgs(_keyboard, timeStamp, _inputRoot, text);
Input?.Invoke(args);
return args.Handled;
}
public bool RawKeyEvent(
AvnRawKeyEventType type,
ulong timeStamp,
AvnInputModifiers modifiers,
AvnKey key,
AvnPhysicalKey physicalKey,
string keySymbol)
{
if (_inputRoot is null)
return false;
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
var args = new RawKeyEventArgs(
_keyboard,
timeStamp,
_inputRoot,
(RawKeyEventType)type,
(Key)key,
(RawInputModifiers)modifiers,
(PhysicalKey)physicalKey,
keySymbol);
Input?.Invoke(args);
return args.Handled;
}
protected virtual bool ChromeHitTest(RawPointerEventArgs e)
{
return false;
}
public void RawMouseEvent(AvnRawMouseEventType type, ulong timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta)
{
if (_inputRoot is null)
return;
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
switch (type)
{
case AvnRawMouseEventType.Wheel:
Input?.Invoke(new RawMouseWheelEventArgs(_mouse, timeStamp, _inputRoot,
point.ToAvaloniaPoint(), new Vector(delta.X, delta.Y), (RawInputModifiers)modifiers));
break;
case AvnRawMouseEventType.Magnify:
Input?.Invoke(new RawPointerGestureEventArgs(_mouse, timeStamp, _inputRoot, RawPointerEventType.Magnify,
point.ToAvaloniaPoint(), new Vector(delta.X, delta.Y), (RawInputModifiers)modifiers));
break;
case AvnRawMouseEventType.Rotate:
Input?.Invoke(new RawPointerGestureEventArgs(_mouse, timeStamp, _inputRoot, RawPointerEventType.Rotate,
point.ToAvaloniaPoint(), new Vector(delta.X, delta.Y), (RawInputModifiers)modifiers));
break;
case AvnRawMouseEventType.Swipe:
Input?.Invoke(new RawPointerGestureEventArgs(_mouse, timeStamp, _inputRoot, RawPointerEventType.Swipe,
point.ToAvaloniaPoint(), new Vector(delta.X, delta.Y), (RawInputModifiers)modifiers));
break;
default:
var e = new RawPointerEventArgs(_mouse, timeStamp, _inputRoot, (RawPointerEventType)type,
point.ToAvaloniaPoint(), (RawInputModifiers)modifiers);
if(!ChromeHitTest(e))
{
Input?.Invoke(e);
}
break;
}
}
public void Resize(Size clientSize, WindowResizeReason reason)
{
_native?.Resize(clientSize.Width, clientSize.Height, (AvnPlatformResizeReason)reason);
}
public Compositor Compositor => AvaloniaNativePlatform.Compositor;
public virtual void Dispose()
{
_native?.Close();
_native?.Dispose();
_native = null;
_nativeControlHost?.Dispose();
_nativeControlHost = null;
(Screen as ScreenImpl)?.Dispose();
_mouse.Dispose();
}
public void Invalidate(Rect rect)
{
_native?.Invalidate(new AvnRect { Height = rect.Height, Width = rect.Width, X = rect.X, Y = rect.Y });
}
public void SetInputRoot(IInputRoot inputRoot)
{
_inputRoot = inputRoot;
}
public virtual void Show(bool activate, bool isDialog)
{
_native?.Show(activate.AsComBool(), isDialog.AsComBool());
}
public PixelPoint Position
{
get => _native?.Position.ToAvaloniaPixelPoint() ?? default;
set => _native?.SetPosition(value.ToAvnPoint());
}
public Point PointToClient(PixelPoint point)
{
return _native?.PointToClient(point.ToAvnPoint()).ToAvaloniaPoint() ?? default;
}
public PixelPoint PointToScreen(Point point)
{
return _native?.PointToScreen(point.ToAvnPoint()).ToAvaloniaPixelPoint() ?? default;
}
public void Hide()
{
_native?.Hide();
}
public void BeginMoveDrag(PointerPressedEventArgs e)
{
_native?.BeginMoveDrag();
}
public Size MaxAutoSizeHint => Screen.AllScreens.Select(s => s.Bounds.Size.ToSize(1))
.OrderByDescending(x => x.Width + x.Height).FirstOrDefault();
public void SetTopmost(bool value)
{
_native?.SetTopMost(value.AsComBool());
}
public double RenderScaling => _native?.Scaling ?? 1;
public double DesktopScaling => 1;
public Action Deactivated { get; set; }
public Action Activated { get; set; }
public void SetCursor(ICursorImpl cursor)
{
if (_native == null)
{
return;
}
var newCursor = cursor as AvaloniaNativeCursor;
newCursor = newCursor ?? (_cursorFactory.GetCursor(StandardCursorType.Arrow) as AvaloniaNativeCursor);
_native.SetCursor(newCursor.Cursor);
}
public Action<PixelPoint> PositionChanged { get; set; }
public Action<RawInputEventArgs> Input { get; set; }
public Action<double> ScalingChanged { get; set; }
public Action<WindowTransparencyLevel> TransparencyLevelChanged { get; set; }
public IScreenImpl Screen { get; private set; }
// TODO
public void SetMinMaxSize(Size minSize, Size maxSize)
{
_native?.SetMinMaxSize(minSize.ToAvnSize(), maxSize.ToAvnSize());
}
public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e)
{
}
internal void BeginDraggingSession(AvnDragDropEffects effects, AvnPoint point, IAvnClipboard clipboard,
IAvnDndResultCallback callback, IntPtr sourceHandle)
{
_native?.BeginDragAndDropOperation(effects, point, clipboard, callback, sourceHandle);
}
public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevels)
{
foreach (var level in transparencyLevels)
{
AvnWindowTransparencyMode? mode = null;
if (level == WindowTransparencyLevel.None)
mode = AvnWindowTransparencyMode.Opaque;
if (level == WindowTransparencyLevel.Transparent)
mode = AvnWindowTransparencyMode.Transparent;
else if (level == WindowTransparencyLevel.AcrylicBlur)
mode = AvnWindowTransparencyMode.Blur;
if (mode.HasValue && level != TransparencyLevel)
{
_native?.SetTransparencyMode(mode.Value);
TransparencyLevel = level;
return;
}
}
// If we get here, we didn't find a supported level. Use the default of None.
if (TransparencyLevel != WindowTransparencyLevel.None)
{
_native?.SetTransparencyMode(AvnWindowTransparencyMode.Opaque);
TransparencyLevel = WindowTransparencyLevel.None;
}
}
public WindowTransparencyLevel TransparencyLevel
{
get => _transparencyLevel;
private set
{
if (_transparencyLevel != value)
{
_transparencyLevel = value;
TransparencyLevelChanged?.Invoke(value);
}
}
}
public void SetFrameThemeVariant(PlatformThemeVariant themeVariant)
{
_native.SetFrameThemeVariant((AvnPlatformThemeVariant)themeVariant);
}
public AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; } = new AcrylicPlatformCompensationLevels(1, 0, 0);
public virtual object TryGetFeature(Type featureType)
{
if (featureType == typeof(INativeControlHostImpl))
{
return _nativeControlHost;
}
if (featureType == typeof(IStorageProvider))
{
return _storageProvider;
}
if (featureType == typeof(IPlatformBehaviorInhibition))
{
return _platformBehaviorInhibition;
}
if (featureType == typeof(IClipboard))
{
return AvaloniaLocator.Current.GetRequiredService<IClipboard>();
}
if (featureType == typeof(ILauncher))
{
return new BclLauncher();
}
return null;
}
public IPlatformHandle Handle { get; private set; }
}
}

Просмотреть файл

@ -663,6 +663,7 @@ interface IAvaloniaNativeFactory : IUnknown
HRESULT Initialize(IAvnGCHandleDeallocatorCallback* deallocator, IAvnApplicationEvents* appCb,
IAvnDispatcher* dispatcher);
IAvnMacOptions* GetMacOptions();
HRESULT CreateTopLevel(IAvnTopLevelEvents* cb, IAvnTopLevel** ppv);
HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnWindow** ppv);
HRESULT CreatePopup(IAvnWindowEvents* cb, IAvnPopup** ppv);
HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv);
@ -692,41 +693,53 @@ interface IAvnString : IUnknown
HRESULT Length(int*ret);
}
[uuid(e5aca675-02b7-4129-aa79-d6e417210bda)]
interface IAvnWindowBase : IUnknown
[uuid(e8cccd3e-e6dc-430a-a0b9-2ce7d7922de6)]
interface IAvnTopLevel : IUnknown
{
HRESULT Show(bool activate, bool isDialog);
HRESULT Hide();
HRESULT Close();
HRESULT Activate();
HRESULT GetClientSize(AvnSize*ret);
HRESULT GetFrameSize(AvnSize*result);
HRESULT GetScaling(double*ret);
HRESULT SetMinMaxSize(AvnSize minSize, AvnSize maxSize);
HRESULT Resize(double width, double height, AvnPlatformResizeReason reason);
HRESULT Invalidate(AvnRect rect);
HRESULT BeginMoveDrag();
HRESULT BeginResizeDrag(AvnWindowEdge edge);
HRESULT GetPosition(AvnPoint*ret);
HRESULT SetPosition(AvnPoint point);
HRESULT Invalidate();
HRESULT PointToClient(AvnPoint point, AvnPoint*ret);
HRESULT PointToScreen(AvnPoint point, AvnPoint*ret);
HRESULT SetTopMost(bool value);
HRESULT SetCursor(IAvnCursor* cursor);
HRESULT CreateGlRenderTarget(IAvnGlContext* context, IAvnGlSurfaceRenderTarget** ret);
HRESULT CreateSoftwareRenderTarget(IAvnSoftwareRenderTarget** ret);
HRESULT CreateMetalRenderTarget(IAvnMetalDevice* device, IAvnMetalRenderTarget** ret);
HRESULT ObtainNSViewHandle([intptr]void** retOut);
HRESULT ObtainNSViewHandleRetained([intptr]void** retOut);
HRESULT CreateNativeControlHost(IAvnNativeControlHost** retOut);
HRESULT GetInputMethod(IAvnTextInputMethod **ppv);
HRESULT SetTransparencyMode(AvnWindowTransparencyMode mode);
}
[uuid(e5aca675-02b7-4129-aa79-d6e417210bda), cpp-virtual-inherits]
interface IAvnWindowBase : IAvnTopLevel
{
HRESULT GetFrameSize(AvnSize*result);
HRESULT SetFrameThemeVariant(AvnPlatformThemeVariant mode);
HRESULT SetParent(IAvnWindowBase* parent);
HRESULT Show(bool activate, bool isDialog);
HRESULT Hide();
HRESULT Close();
HRESULT Activate();
HRESULT SetMinMaxSize(AvnSize minSize, AvnSize maxSize);
HRESULT Resize(double width, double height, AvnPlatformResizeReason reason);
HRESULT BeginMoveDrag();
HRESULT BeginResizeDrag(AvnWindowEdge edge);
HRESULT GetPosition(AvnPoint*ret);
HRESULT SetPosition(AvnPoint point);
HRESULT SetTopMost(bool value);
HRESULT SetMainMenu(IAvnMenu* menu);
HRESULT ObtainNSWindowHandle([intptr]void** retOut);
HRESULT ObtainNSWindowHandleRetained([intptr]void** retOut);
HRESULT ObtainNSViewHandle([intptr]void** retOut);
HRESULT ObtainNSViewHandleRetained([intptr]void** retOut);
HRESULT CreateNativeControlHost(IAvnNativeControlHost** retOut);
HRESULT BeginDragAndDropOperation(AvnDragDropEffects effects, AvnPoint point,
IAvnClipboard* clipboard, IAvnDndResultCallback* cb, [intptr]void* sourceHandle);
HRESULT SetTransparencyMode(AvnWindowTransparencyMode mode);
HRESULT SetFrameThemeVariant(AvnPlatformThemeVariant mode);
HRESULT GetInputMethod(IAvnTextInputMethod **ppv);
}
[uuid(83e588f3-6981-4e48-9ea0-e1e569f79a91), cpp-virtual-inherits]
@ -739,7 +752,6 @@ interface IAvnPopup : IAvnWindowBase
interface IAvnWindow : IAvnWindowBase
{
HRESULT SetEnabled(bool enable);
HRESULT SetParent(IAvnWindow* parent);
HRESULT SetCanResize(bool value);
HRESULT SetDecorations(SystemDecorations value);
HRESULT SetTitle(char* utf8Title);
@ -754,30 +766,39 @@ interface IAvnWindow : IAvnWindowBase
HRESULT GetWindowZOrder(long*ret);
}
[uuid(939b6599-40a8-4710-a4c8-5d72d8f174fb)]
interface IAvnWindowBaseEvents : IUnknown
[uuid(fda9c1b3-69e0-43d7-9459-8cc97cb41f6a)]
interface IAvnTopLevelEvents : IUnknown
{
HRESULT Paint();
void Closed();
void Activated();
void Deactivated();
void Resized([const] AvnSize& size, AvnPlatformResizeReason reason);
void PositionChanged(AvnPoint position);
void RawMouseEvent(AvnRawMouseEventType type,
u_int64_t timeStamp,
AvnInputModifiers modifiers,
AvnPoint point,
AvnVector delta);
bool RawKeyEvent(AvnRawKeyEventType type, u_int64_t timeStamp, AvnInputModifiers modifiers,
AvnKey key, AvnPhysicalKey physicalKey, [const] char* keySymbol);
bool RawTextInputEvent(u_int64_t timeStamp, [const] char* text);
void ScalingChanged(double scaling);
void RunRenderPriorityJobs();
void LostFocus();
AvnDragDropEffects DragEvent(AvnDragEventType type, AvnPoint position,
void Closed();
HRESULT Paint();
void Resized([const] AvnSize& size, AvnPlatformResizeReason reason);
void RawMouseEvent(AvnRawMouseEventType type,
u_int64_t timeStamp,
AvnInputModifiers modifiers,
AvnPoint point,
AvnVector delta);
bool RawKeyEvent(AvnRawKeyEventType type, u_int64_t timeStamp, AvnInputModifiers modifiers,
AvnKey key, AvnPhysicalKey physicalKey, [const] char* keySymbol);
bool RawTextInputEvent(u_int64_t timeStamp, [const] char* text);
void ScalingChanged(double scaling);
void RunRenderPriorityJobs();
void LostFocus();
IAvnAutomationPeer* GetAutomationPeer();
AvnDragDropEffects DragEvent(AvnDragEventType type, AvnPoint position,
AvnInputModifiers modifiers, AvnDragDropEffects effects,
IAvnClipboard* clipboard, [intptr]void* dataObjectHandle);
IAvnAutomationPeer* GetAutomationPeer();
}
[uuid(939b6599-40a8-4710-a4c8-5d72d8f174fb)]
interface IAvnWindowBaseEvents : IAvnTopLevelEvents
{
void Activated();
void Deactivated();
void PositionChanged(AvnPoint position);
}
[uuid(1ae178ee-1fcc-447f-b6dd-b7bb727f934c)]

Просмотреть файл

@ -135,6 +135,8 @@ namespace Avalonia.X11
return new X11Window(this, null);
}
public ITopLevelImpl CreateEmbeddableTopLevel() => CreateEmbeddableWindow();
public IWindowImpl CreateEmbeddableWindow()
{
throw new NotSupportedException();

Просмотреть файл

@ -124,6 +124,9 @@ namespace Avalonia.Browser
{
}
public double DesktopScaling => RenderScaling;
public IScreenImpl? Screen { get; }
public IPlatformHandle? Handle { get; }
public Size ClientSize => _surface?.ClientSize ?? new Size(1, 1);
public Size? FrameSize => null;
public double RenderScaling => _surface?.Scaling ?? 1;

Просмотреть файл

@ -58,11 +58,17 @@ internal class BrowserWindowingPlatform : IWindowingPlatform
public IWindowImpl CreateWindow() => throw new NotSupportedException("Browser doesn't support windowing platform. In order to display a single-view content, set ISingleViewApplicationLifetime.MainView.");
IWindowImpl IWindowingPlatform.CreateEmbeddableWindow()
{
throw new NotImplementedException("Browser doesn't support embeddable windowing platform.");
}
ITopLevelImpl IWindowingPlatform.CreateEmbeddableTopLevel()
{
throw new NotImplementedException();
}
public ITrayIconImpl? CreateTrayIcon()
{
return null;

Просмотреть файл

@ -58,6 +58,7 @@ namespace Avalonia.Headless
_frameBufferFormat = frameBufferFormat;
}
public IWindowImpl CreateWindow() => new HeadlessWindowImpl(false, _frameBufferFormat);
public ITopLevelImpl CreateEmbeddableTopLevel() => CreateEmbeddableWindow();
public IWindowImpl CreateEmbeddableWindow() => throw new PlatformNotSupportedException();

Просмотреть файл

@ -53,6 +53,9 @@ using Avalonia.Rendering.Composition;
{
}
public double DesktopScaling => 1;
public IScreenImpl Screen { get; }
public IPlatformHandle Handle { get; }
public Size ClientSize => ScaledSize;
public Size? FrameSize => null;
public IMouseDevice MouseDevice => new MouseDevice();

Просмотреть файл

@ -9,6 +9,8 @@ internal class WindowingPlatformStub : IWindowingPlatform
public IWindowImpl CreateEmbeddableWindow() => throw new NotSupportedException();
public ITopLevelImpl CreateEmbeddableTopLevel() => CreateEmbeddableWindow();
public ITrayIconImpl? CreateTrayIcon() => null;
}

Просмотреть файл

@ -26,6 +26,10 @@ internal class TopLevelImpl : ITopLevelImpl
_clipboard = new NuiClipboardImpl();
}
public double DesktopScaling => RenderScaling;
public IScreenImpl? Screen { get; }
public IPlatformHandle? Handle { get; }
public Size ClientSize => _view.ClientSize;
public Size? FrameSize => null;

Просмотреть файл

@ -54,7 +54,7 @@ namespace Avalonia.Win32.Automation
{
get
{
var handle = WindowImpl?.Handle.Handle ?? IntPtr.Zero;
var handle = WindowImpl?.Handle?.Handle ?? IntPtr.Zero;
if (handle == IntPtr.Zero)
return null;
var hr = UiaCoreProviderApi.UiaHostProviderFromHwnd(handle, out var result);

Просмотреть файл

@ -39,7 +39,7 @@ namespace Avalonia.Win32
var focusOwner = UnmanagedMethods.GetFocus();
if (focusOwner != IntPtr.Zero &&
UnmanagedMethods.GetAncestor(focusOwner, UnmanagedMethods.GetAncestorFlags.GA_ROOT)
== parent.Handle.Handle)
== parent.Handle?.Handle)
UnmanagedMethods.SetFocus(parent.Handle.Handle);
}
@ -116,7 +116,7 @@ namespace Avalonia.Win32
// One fabulous design decision leads to another, I guess
private static IWindowBaseImpl SaveParentHandle(IWindowBaseImpl parent)
{
s_parentHandle = parent.Handle.Handle;
s_parentHandle = parent.Handle!.Handle;
return parent;
}

Просмотреть файл

@ -78,9 +78,14 @@ namespace Avalonia.Win32
/// <inheritdoc />
public Screen? ScreenFromWindow(IWindowBaseImpl window)
{
var handle = window.Handle.Handle;
var handle = window.Handle?.Handle;
var monitor = MonitorFromWindow(handle, MONITOR.MONITOR_DEFAULTTONULL);
if (handle is null)
{
return null;
}
var monitor = MonitorFromWindow(handle.Value, MONITOR.MONITOR_DEFAULTTONULL);
return FindScreenByHandle(monitor);
}

Просмотреть файл

@ -217,6 +217,8 @@ namespace Avalonia.Win32
return new WindowImpl();
}
public ITopLevelImpl CreateEmbeddableTopLevel() => CreateEmbeddableWindow();
public IWindowImpl CreateEmbeddableWindow()
{
var embedded = new EmbeddedWindowImpl();

Просмотреть файл

@ -256,7 +256,7 @@ namespace Avalonia.Win32
}
}
Size? ITopLevelImpl.FrameSize => FrameSize;
Size? IWindowBaseImpl.FrameSize => FrameSize;
public Size FrameSize
{

Просмотреть файл

@ -221,6 +221,9 @@ namespace Avalonia.iOS
// No-op
}
public double DesktopScaling => RenderScaling;
public IScreenImpl? Screen { get; }
public IPlatformHandle? Handle { get; }
public Size ClientSize => new Size(_view.Bounds.Width, _view.Bounds.Height);
public Size? FrameSize => null;
public double RenderScaling => _view.ContentScaleFactor;

Просмотреть файл

@ -20,6 +20,7 @@ namespace Avalonia.iOS
internal class WindowingPlatformStub : IWindowingPlatform
{
public IWindowImpl CreateWindow() => throw new NotSupportedException();
public ITopLevelImpl CreateEmbeddableTopLevel() => CreateEmbeddableWindow();
public IWindowImpl CreateEmbeddableWindow() => throw new NotSupportedException();

Просмотреть файл

@ -158,6 +158,9 @@ public class CompositorTestServices : IDisposable
}
public double DesktopScaling => 1;
public IScreenImpl Screen { get; }
public IPlatformHandle Handle { get; }
public Size ClientSize { get; }
public Size? FrameSize { get; }
public double RenderScaling => 1;

Просмотреть файл

@ -152,6 +152,8 @@ namespace Avalonia.UnitTests
}
}
public ITopLevelImpl CreateEmbeddableTopLevel() => CreateEmbeddableWindow();
public IWindowImpl CreateEmbeddableWindow()
{
throw new NotImplementedException();