зеркало из https://github.com/AvaloniaUI/Avalonia.git
Avalonia.Native TopLevel embedding (#15932)
* Introduce Avalonia.Native TopLevelImpl * Update Avalonia.Native.csproj Revert change
This commit is contained in:
Родитель
42ec037e9a
Коммит
143399f65a
29
Avalonia.sln
29
Avalonia.sln
|
@ -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"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypeParameters/@EntryIndexedValue"><Policy Inspect="False" Prefix="T" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue"><Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=15b5b1f1_002D457c_002D4ca6_002Db278_002D5615aedc07d3/@EntryIndexedValue"><Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="s_" Suffix="" Style="aaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=236f7aa5_002D7b06_002D43ca_002Dbf2a_002D9b31bfcff09a/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"><ElementKinds><Kind Name="CONSTANT_FIELD" /></ElementKinds></Descriptor><Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=2c62818f_002D621b_002D4425_002Dadc9_002D78611099bfcb/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Type parameters"><ElementKinds><Kind Name="TYPE_PARAMETER" /></ElementKinds></Descriptor><Policy Inspect="False" Prefix="T" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue"><Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=61a991a4_002Dd0a3_002D4d19_002D90a5_002Df8f4d75c30c1/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Local variables"><ElementKinds><Kind Name="LOCAL_VARIABLE" /></ElementKinds></Descriptor><Policy Inspect="False" Prefix="" Suffix="" Style="aaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=669e5282_002Dfb4b_002D4e90_002D91e7_002D07d269d04b60/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Constant fields (not private)"><ElementKinds><Kind Name="CONSTANT_FIELD" /></ElementKinds></Descriptor><Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8a85b61a_002D1024_002D4f87_002Db9ef_002D1fdae19930a1/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Parameters"><ElementKinds><Kind Name="PARAMETER" /></ElementKinds></Descriptor><Policy Inspect="False" Prefix="" Suffix="" Style="aaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8b8504e3_002Df0be_002D4c14_002D9103_002Dc732f2bddc15/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Enum members"><ElementKinds><Kind Name="ENUM_MEMBER" /></ElementKinds></Descriptor><Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a0b4bc4d_002Dd13b_002D4a37_002Db37e_002Dc9c6864e4302/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"><ElementKinds><Kind Name="NAMESPACE" /><Kind Name="CLASS" /><Kind Name="STRUCT" /><Kind Name="ENUM" /><Kind Name="DELEGATE" /></ElementKinds></Descriptor><Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a7a3339e_002D4e89_002D4319_002D9735_002Da9dc4cb74cc7/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Interfaces"><ElementKinds><Kind Name="INTERFACE" /></ElementKinds></Descriptor><Policy Inspect="False" Prefix="I" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=c873eafb_002Dd57f_002D481d_002D8c93_002D77f6863c2f88/@EntryIndexedValue"><Policy><Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static readonly fields (not private)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=f9fce829_002De6f4_002D4cb2_002D80f1_002D5497c44f51df/@EntryIndexedValue"><Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="s_" Suffix="" Style="aaBb" /></Policy></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"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue"><Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=f9fce829_002De6f4_002D4cb2_002D80f1_002D5497c44f51df/@EntryIndexedValue"><Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy></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();
|
||||
|
|
Загрузка…
Ссылка в новой задаче