diff --git a/Avalonia.sln b/Avalonia.sln
index 4ac1538b902..b4117d8aac3 100644
--- a/Avalonia.sln
+++ b/Avalonia.sln
@@ -116,16 +116,17 @@ 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
EndProjectSection
@@ -237,8 +238,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
@@ -294,24 +295,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
@@ -714,10 +714,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
@@ -734,6 +730,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
diff --git a/Avalonia.sln.DotSettings b/Avalonia.sln.DotSettings
index cc58566622a..061db721683 100644
--- a/Avalonia.sln.DotSettings
+++ b/Avalonia.sln.DotSettings
@@ -36,7 +36,20 @@
<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
<Policy Inspect="False" Prefix="T" Suffix="" Style="AaBb" />
<Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" />
+ <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>
+ <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>
+ <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>
+ <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>
+ <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Local variables"><ElementKinds><Kind Name="LOCAL_VARIABLE" /></ElementKinds></Descriptor><Policy Inspect="False" Prefix="" Suffix="" Style="aaBb" /></Policy>
+ <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>
+ <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Parameters"><ElementKinds><Kind Name="PARAMETER" /></ElementKinds></Descriptor><Policy Inspect="False" Prefix="" Suffix="" Style="aaBb" /></Policy>
+ <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Enum members"><ElementKinds><Kind Name="ENUM_MEMBER" /></ElementKinds></Descriptor><Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /></Policy>
+ <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>
+ <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Interfaces"><ElementKinds><Kind Name="INTERFACE" /></ElementKinds></Descriptor><Policy Inspect="False" Prefix="I" Suffix="" Style="AaBb" /></Policy>
+ <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>
+ <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>
True
+ True
True
True
True
diff --git a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj
index a07532412d6..5dd69e7009b 100644
--- a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj
+++ b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj
@@ -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 = ""; };
1839122E037567BDD1D09DEB /* WindowProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowProtocol.h; sourceTree = ""; };
1839132D0E2454D911F1D1F9 /* AvnView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AvnView.mm; sourceTree = ""; };
183913C6BFD6856BD42D19FD /* IWindowStateChanged.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IWindowStateChanged.h; sourceTree = ""; };
@@ -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 = ""; };
EDF8CDCC2964CB01001EE34F /* PlatformSettings.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformSettings.mm; sourceTree = ""; };
+ F10084832BFF1F9E0024303E /* TopLevelImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TopLevelImpl.h; sourceTree = ""; };
+ F10084852BFF1FB40024303E /* TopLevelImpl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TopLevelImpl.mm; sourceTree = ""; };
/* 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 */,
diff --git a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/xcshareddata/xcschemes/Avalonia.Native.OSX.xcscheme b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/xcshareddata/xcschemes/Avalonia.Native.OSX.xcscheme
index c1e5b91e3ef..5014c5d4394 100644
--- a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/xcshareddata/xcschemes/Avalonia.Native.OSX.xcscheme
+++ b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/xcshareddata/xcschemes/Avalonia.Native.OSX.xcscheme
@@ -1,7 +1,7 @@
+ version = "1.7">
diff --git a/native/Avalonia.Native/src/OSX/AvnView.h b/native/Avalonia.Native/src/OSX/AvnView.h
index e058656d3f7..4f673fceefa 100644
--- a/native/Avalonia.Native/src/OSX/AvnView.h
+++ b/native/Avalonia.Native/src/OSX/AvnView.h
@@ -7,20 +7,20 @@
#import
#include "common.h"
-#include "WindowImpl.h"
+#include "TopLevelImpl.h"
#include "KeyTransform.h"
@class AvnAccessibilityElement;
@protocol IRenderTarget;
@interface AvnView : NSView
--(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*)target;
+-(void) setRenderTarget:(NSObject* _Nonnull)target;
+ (AvnPoint)toAvnPoint:(CGPoint)p;
@end
diff --git a/native/Avalonia.Native/src/OSX/AvnView.mm b/native/Avalonia.Native/src/OSX/AvnView.mm
index fc0d695384e..ab52bcc4a9c 100644
--- a/native/Avalonia.Native/src/OSX/AvnView.mm
+++ b/native/Avalonia.Native/src/OSX/AvnView.mm
@@ -7,10 +7,11 @@
#include "AvnView.h"
#include "automation.h"
#import "WindowInterfaces.h"
+#import "WindowImpl.h"
@implementation AvnView
{
- ComPtr _parent;
+ ComPtr _parent;
NSTrackingArea* _area;
bool _isLeftPressed, _isMiddlePressed, _isRightPressed, _isXButton1Pressed, _isXButton2Pressed;
AvnInputModifiers _modifierState;
@@ -67,7 +68,7 @@ -(void)displayLayer: (CALayer*)layer
[self updateLayer];
}
--(AvnView*) initWithParent: (WindowBaseImpl*) parent
+-(AvnView*) initWithParent: (TopLevelImpl*) parent
{
self = [super init];
[self setWantsLayer:YES];
@@ -155,7 +156,7 @@ -(void)setFrameSize:(NSSize)newSize
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 @@ - (void)updateLayer
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 @@ - (void) viewDidChangeBackingProperties
if(_parent != nullptr)
{
- _parent->BaseEvents->ScalingChanged([_parent->Window backingScaleFactor]);
+ _parent->TopLevelEvents->ScalingChanged([[self window] backingScaleFactor]);
}
[super viewDidChangeBackingProperties];
@@ -219,19 +220,24 @@ - (bool) ignoreUserInput:(bool)trigerInputWhenDisabled
{
return TRUE;
}
+
+ id parentWindow = nullptr;
- auto parentWindow = _parent->GetWindowProtocol();
+ if([[self window] conformsToProtocol:@protocol(AvnWindowProtocol)]){
+ parentWindow = (id)[self window];
+ }
- if(parentWindow == nil || ![parentWindow shouldTryToHandleEvents])
+ if(parentWindow != nullptr && ![parentWindow shouldTryToHandleEvents])
{
if(trigerInputWhenDisabled)
{
- auto window = dynamic_cast(_parent.getRaw());
-
- if(window != nullptr)
- {
- window->WindowEvents->GotInputWhenDisabled();
+ WindowImpl* windowImpl = dynamic_cast(_parent.getRaw());
+
+ if(windowImpl == nullptr){
+ return FALSE;
}
+
+ windowImpl->WindowEvents->GotInputWhenDisabled();
}
return TRUE;
@@ -301,7 +307,7 @@ - (void)mouseEvent:(NSEvent *)event withType:(AvnRawMouseEventType) type
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 @@ - (void)mouseEvent:(NSEvent *)event withType:(AvnRawMouseEventType) type
- (BOOL) resignFirstResponder
{
- _parent->BaseEvents->LostFocus();
+ _parent->TopLevelEvents->LostFocus();
return YES;
}
@@ -461,7 +467,7 @@ - (void) keyboardEvent: (NSEvent *) event withType: (AvnRawKeyEventType)type
auto timestamp = static_cast([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 @@ - (void)flagsChanged:(NSEvent *)event
}
- (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 @@ - (void)keyDown:(NSEvent *)event
if(keySymbol != nullptr && key != AvnKeyEnter){
auto timestamp = static_cast([event timestamp] * 1000);
- _parent->BaseEvents->RawTextInputEvent(timestamp, [keySymbol UTF8String]);
+ _parent->TopLevelEvents->RawTextInputEvent(timestamp, [keySymbol UTF8String]);
}
}
}
@@ -707,7 +713,7 @@ - (void)insertText:(id)string replacementRange:(NSRange)replacementRange
uint64_t timestamp = static_cast([NSDate timeIntervalSinceReferenceDate] * 1000);
- _parent->BaseEvents->RawTextInputEvent(timestamp, [text UTF8String]);
+ _parent->TopLevelEvents->RawTextInputEvent(timestamp, [text UTF8String]);
}
- (NSUInteger)characterIndexForPoint:(NSPoint)point
@@ -733,7 +739,7 @@ - (NSDragOperation)triggerAvnDragEvent: (AvnDragEventType) type info: (id BaseEvents
+ int reffects = (int)_parent->TopLevelEvents
->DragEvent(type, point, modifiers, effects,
CreateClipboard([info draggingPasteboard], nil),
GetAvnDataObjectHandleFromDraggingInfo(info));
@@ -799,7 +805,7 @@ - (AvnAccessibilityElement *) accessibilityChild
{
if (_accessibilityChild == nil)
{
- auto peer = _parent->BaseEvents->GetAutomationPeer();
+ auto peer = _parent->TopLevelEvents->GetAutomationPeer();
if (peer == nil)
return nil;
diff --git a/native/Avalonia.Native/src/OSX/AvnWindow.mm b/native/Avalonia.Native/src/OSX/AvnWindow.mm
index ef50cdab841..86d412c76a7 100644
--- a/native/Avalonia.Native/src/OSX/AvnWindow.mm
+++ b/native/Avalonia.Native/src/OSX/AvnWindow.mm
@@ -24,7 +24,6 @@
#include "WindowImpl.h"
#include "AvnView.h"
#include "WindowInterfaces.h"
-#include "PopupImpl.h"
@implementation CLASS_NAME
{
@@ -201,8 +200,6 @@ - (void)windowDidChangeBackingProperties:(NSNotification *_Nonnull)notification
[self backingScaleFactor];
}
-
-
- (void)windowWillClose:(NSNotification *_Nonnull)notification
{
_closed = true;
@@ -231,7 +228,7 @@ - (void)windowWillClose:(NSNotification *_Nonnull)notification
//
// 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 @@ - (BOOL)windowShouldZoom:(NSWindow *_Nonnull)window toFrame:(NSRect)newFrame
return _parent->CanZoom();
}
--(void)windowDidResignKey:(NSNotification *)notification
+-(void)windowDidResignKey:(NSNotification* _Nonnull)notification
{
if(_parent)
_parent->BaseEvents->Deactivated();
diff --git a/native/Avalonia.Native/src/OSX/INSWindowHolder.h b/native/Avalonia.Native/src/OSX/INSWindowHolder.h
index 3c5010966b8..7c07d6bb409 100644
--- a/native/Avalonia.Native/src/OSX/INSWindowHolder.h
+++ b/native/Avalonia.Native/src/OSX/INSWindowHolder.h
@@ -11,6 +11,10 @@
struct INSWindowHolder
{
virtual NSWindow* _Nonnull GetNSWindow () = 0;
+};
+
+struct INSViewHolder
+{
virtual AvnView* _Nonnull GetNSView () = 0;
};
diff --git a/native/Avalonia.Native/src/OSX/PopupImpl.h b/native/Avalonia.Native/src/OSX/PopupImpl.h
deleted file mode 100644
index 451019a6a4f..00000000000
--- a/native/Avalonia.Native/src/OSX/PopupImpl.h
+++ /dev/null
@@ -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
diff --git a/native/Avalonia.Native/src/OSX/PopupImpl.mm b/native/Avalonia.Native/src/OSX/PopupImpl.mm
index 39aa568134e..40fe8ce88b3 100644
--- a/native/Avalonia.Native/src/OSX/PopupImpl.mm
+++ b/native/Avalonia.Native/src/OSX/PopupImpl.mm
@@ -12,7 +12,6 @@
#import "WindowBaseImpl.h"
#import "WindowProtocol.h"
#import
-#include "PopupImpl.h"
class PopupImpl : public virtual WindowBaseImpl, public IAvnPopup
{
@@ -23,7 +22,7 @@
END_INTERFACE_MAP()
virtual ~PopupImpl(){}
ComPtr WindowEvents;
- PopupImpl(IAvnWindowEvents* events) : WindowBaseImpl(events)
+ PopupImpl(IAvnWindowEvents* events) : TopLevelImpl(events), WindowBaseImpl(events)
{
WindowEvents = events;
[Window setLevel:NSPopUpMenuWindowLevel];
@@ -35,13 +34,12 @@ virtual NSWindowStyleMask CalculateStyleMask() override
}
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);
}
};
diff --git a/native/Avalonia.Native/src/OSX/TopLevelImpl.h b/native/Avalonia.Native/src/OSX/TopLevelImpl.h
new file mode 100644
index 00000000000..d6243b62681
--- /dev/null
+++ b/native/Avalonia.Native/src/OSX/TopLevelImpl.h
@@ -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
+
+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 *currentRenderTarget;
+ ComPtr InputMethod;
+ ComPtr TopLevelEvents;
+ AvnView *View;
+
+ void UpdateCursor();
+ virtual void SetClientSize(NSSize size);
+};
+
+#endif /* TopLevelImpl_h */
diff --git a/native/Avalonia.Native/src/OSX/TopLevelImpl.mm b/native/Avalonia.Native/src/OSX/TopLevelImpl.mm
new file mode 100644
index 00000000000..0a56b71f822
--- /dev/null
+++ b/native/Avalonia.Native/src/OSX/TopLevelImpl.mm
@@ -0,0 +1,251 @@
+#import
+#import
+#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);
+ 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;
+ }
+}
diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.h b/native/Avalonia.Native/src/OSX/WindowBaseImpl.h
index 83c7aed5d38..ab0a5fb6a19 100644
--- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.h
+++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.h
@@ -9,19 +9,21 @@
#include "rendertarget.h"
#include "INSWindowHolder.h"
#include "AvnTextInputMethod.h"
+#include "TopLevelImpl.h"
+#include
-@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 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 @@ BEGIN_INTERFACE_MAP()
bool _inResize;
protected:
- AvnPoint lastPositionSet;
AutoFitContentView *StandardContainer;
+ AvnPoint lastPositionSet;
bool _shown;
+ std::list _children;
+ bool _isModal;
public:
- NSObject *currentRenderTarget;
+ WindowBaseImpl* Parent;
NSWindow * Window;
ComPtr BaseEvents;
- ComPtr InputMethod;
- AvnView *View;
};
#endif //AVALONIA_NATIVE_OSX_WINDOWBASEIMPL_H
diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm
index 3f54680ae77..afae6d6b5bc 100644
--- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm
+++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm
@@ -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();
_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 @@
CreateNSWindow(usePanel);
+ StandardContainer = [[AutoFitContentView new] initWithContent:View];
+
[Window setContentView:StandardContainer];
[Window setBackingType:NSBackingStoreBuffered];
[Window setContentMinSize:lastMinSize];
@@ -48,38 +50,10 @@
[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 @@
auto collectionBehavior = [Window collectionBehavior];
[Window setCollectionBehavior:collectionBehavior & ~NSWindowCollectionBehaviorFullScreenPrimary];
- UpdateStyle();
+ UpdateAppearance();
[Window invalidateShadow];
@@ -219,20 +193,6 @@
}
}
-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::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 @@
lastSize = NSSize{x, y};
- [Window setContentSize:lastSize];
+ SetClientSize(lastSize);
[Window invalidateShadow];
}
}
@@ -342,16 +285,6 @@
}
}
-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::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);
- 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 @@
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 @@
// 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);
+ }
+
+ auto cparent = dynamic_cast(parent);
+
+ Parent = cparent;
- return S_OK;
-}
+ _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();
+ }
-extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events)
-{
- @autoreleasepool
- {
- IAvnWindow* ptr = (IAvnWindow*)new WindowImpl(events);
- return ptr;
+ return S_OK;
}
}
diff --git a/native/Avalonia.Native/src/OSX/WindowImpl.h b/native/Avalonia.Native/src/OSX/WindowImpl.h
index 047a0d2c84d..b931e933db5 100644
--- a/native/Avalonia.Native/src/OSX/WindowImpl.h
+++ b/native/Avalonia.Native/src/OSX/WindowImpl.h
@@ -8,26 +8,9 @@
#import "WindowBaseImpl.h"
#include "IWindowStateChanged.h"
-#include
-
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 _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
diff --git a/native/Avalonia.Native/src/OSX/WindowImpl.mm b/native/Avalonia.Native/src/OSX/WindowImpl.mm
index 1cdf81e2fbe..42ac37ae8cc 100644
--- a/native/Avalonia.Native/src/OSX/WindowImpl.mm
+++ b/native/Avalonia.Native/src/OSX/WindowImpl.mm
@@ -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();
_isClientAreaExtended = false;
_extendClientHints = AvnDefaultChrome;
_fullScreenActive = false;
@@ -22,7 +22,7 @@
_lastWindowState = Normal;
_actualWindowState = Normal;
_lastTitle = @"";
- _parent = nullptr;
+ Parent = nullptr;
WindowEvents = events;
[Window setHasShadow:true];
@@ -69,40 +69,7 @@
@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(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 @@
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 @@
@autoreleasepool {
_canResize = value;
- UpdateStyle();
+ UpdateAppearance();
return S_OK;
}
}
@@ -252,7 +219,7 @@
return S_OK;
}
- UpdateStyle();
+ UpdateAppearance();
switch (_decorations) {
case SystemDecorationsNone:
@@ -427,7 +394,7 @@
}
[GetWindowProtocol() setIsExtended:enable];
- UpdateStyle();
+ UpdateAppearance();
}
return S_OK;
@@ -579,7 +546,7 @@
}
bool WindowImpl::IsOwned() {
- return _parent != nullptr;
+ return Parent != nullptr;
}
NSWindowStyleMask WindowImpl::CalculateStyleMask() {
@@ -620,8 +587,8 @@
return s;
}
-void WindowImpl::UpdateStyle() {
- WindowBaseImpl::UpdateStyle();
+void WindowImpl::UpdateAppearance() {
+ WindowBaseImpl::UpdateAppearance();
if (Window == nil) {
return;
@@ -642,3 +609,12 @@
[zoomButton setHidden:!hasTrafficLights];
[zoomButton setEnabled:CanZoom()];
}
+
+extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events)
+{
+ @autoreleasepool
+ {
+ IAvnWindow* ptr = (IAvnWindow*)new WindowImpl(events);
+ return ptr;
+ }
+}
diff --git a/native/Avalonia.Native/src/OSX/automation.mm b/native/Avalonia.Native/src/OSX/automation.mm
index 9fe0ff3c60b..0f5f2943291 100644
--- a/native/Avalonia.Native/src/OSX/automation.mm
+++ b/native/Avalonia.Native/src/OSX/automation.mm
@@ -80,7 +80,7 @@ + (AvnAccessibilityElement *)acquire:(IAvnAutomationPeer *)peer
return nil;
}
- auto holder = dynamic_cast(window);
+ auto holder = dynamic_cast(window);
auto view = holder->GetNSView();
return [[AvnRootAccessibilityElement alloc] initWithPeer:peer owner:view];
}
diff --git a/native/Avalonia.Native/src/OSX/common.h b/native/Avalonia.Native/src/OSX/common.h
index a3473d39281..38b702d7754 100644
--- a/native/Avalonia.Native/src/OSX/common.h
+++ b/native/Avalonia.Native/src/OSX/common.h
@@ -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
diff --git a/native/Avalonia.Native/src/OSX/main.mm b/native/Avalonia.Native/src/OSX/main.mm
index 41d6fd37abd..a36170fddc0 100644
--- a/native/Avalonia.Native/src/OSX/main.mm
+++ b/native/Avalonia.Native/src/OSX/main.mm
@@ -225,6 +225,19 @@ virtual HRESULT Initialize(IAvnGCHandleDeallocatorCallback* deallocator,
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;
diff --git a/nukebuild/_build.csproj.DotSettings b/nukebuild/_build.csproj.DotSettings
index 9aac7d8e8d4..7348ae5acbb 100644
--- a/nukebuild/_build.csproj.DotSettings
+++ b/nukebuild/_build.csproj.DotSettings
@@ -13,6 +13,8 @@
False
<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <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>
+ <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy>
True
True
True
@@ -21,4 +23,5 @@
True
True
True
- True
+ True
+ True
diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
index 02e3f68d739..e3716d2a4e4 100644
--- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
+++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
@@ -100,6 +100,8 @@ public TopLevelImpl(AvaloniaView avaloniaView, bool placeOnTop = false)
internal InvalidationAwareSurfaceView InternalView => _view;
+ public double DesktopScaling => RenderScaling;
+ public IScreenImpl? Screen { get; }
public IPlatformHandle Handle => _view;
public IEnumerable