Browse Source

make it compile 2 versions is AvnWindow (NSWindow / NSPanel version)

fix include mess, and pragma once.
Dan Walmsley 3 years ago
parent
commit
f008e403cf

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

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

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

@@ -3,8 +3,10 @@
 // Copyright (c) 2022 Avalonia. All rights reserved.
 //
 
+#pragma once
+
 #import <Foundation/Foundation.h>
-#import "avalonia-native.h"
+#include "avalonia-native.h"
 
 @interface AutoFitContentView : NSView
 -(AutoFitContentView* _Nonnull) initWithContent: (NSView* _Nonnull) content;

+ 2 - 1
native/Avalonia.Native/src/OSX/AutoFitContentView.mm

@@ -4,7 +4,8 @@
 //
 
 #include "AvnView.h"
-#import "AutoFitContentView.h"
+#include "AutoFitContentView.h"
+#import "WindowInterfaces.h"
 
 @implementation AutoFitContentView
 {

+ 16 - 10
native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj

@@ -9,16 +9,19 @@
 /* Begin PBXBuildFile section */
 		18391068E48EF96E3DB5FDAB /* ResizeScope.mm in Sources */ = {isa = PBXBuildFile; fileRef = 18391E45702740FE9DD69695 /* ResizeScope.mm */; };
 		1839125F057B0A4EB1760058 /* WindowImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 183919BF108EB72A029F7671 /* WindowImpl.mm */; };
+		183914E50CF6D2EFC1667F7C /* WindowInterfaces.h in Headers */ = {isa = PBXBuildFile; fileRef = 18391DB45C7D892E61BF388C /* WindowInterfaces.h */; };
 		1839151F32D1BB1AB51A7BB6 /* AvnPanelWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = 18391884C7476DA4E53A492D /* AvnPanelWindow.mm */; };
 		183916173528EC2737DBE5E1 /* WindowBaseImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 183915BFF0E234CD3604A7CD /* WindowBaseImpl.h */; };
 		1839171DCC651B0638603AC4 /* INSWindowHolder.h in Headers */ = {isa = PBXBuildFile; fileRef = 18391BBB7782C296D424071F /* INSWindowHolder.h */; };
 		1839179A55FC1421BEE83330 /* WindowBaseImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 18391676ECF0E983F4964357 /* WindowBaseImpl.mm */; };
-		1839196EC57BBC5C8BE1C735 /* AvnPanelWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 18391DC046BC700D56DF0B82 /* AvnPanelWindow.h */; };
 		183919D91DB9AAB5D700C2EA /* WindowImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 18391CD090AA776E7E841AC9 /* WindowImpl.h */; };
 		18391AA7E0BBA74D184C5734 /* AutoFitContentView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1839166350F32661F3ABD70F /* AutoFitContentView.mm */; };
+		18391AC16726CBC45856233B /* AvnWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1839155B28B20FFB672D29C6 /* AvnWindow.mm */; };
+		18391AC65ADD7DDD33FBE737 /* PopupImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 183910513F396141938832B5 /* PopupImpl.h */; };
 		18391C28BF1823B5464FDD36 /* ResizeScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 1839171D898F9BFC1373631A /* ResizeScope.h */; };
 		18391CF07316F819E76B617C /* IWindowStateChanged.h in Headers */ = {isa = PBXBuildFile; fileRef = 183913C6BFD6856BD42D19FD /* IWindowStateChanged.h */; };
 		18391D4EB311BC7EF8B8C0A6 /* AvnView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1839132D0E2454D911F1D1F9 /* AvnView.mm */; };
+		18391D8CD1756DC858DC1A09 /* PopupImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 18391BB698579F40F1783F31 /* PopupImpl.mm */; };
 		18391E1381E2D5BFD60265A9 /* AutoFitContentView.h in Headers */ = {isa = PBXBuildFile; fileRef = 18391654EF0E7AB3D3AB4071 /* AutoFitContentView.h */; };
 		18391ED5F611FF62C45F196D /* AvnView.h in Headers */ = {isa = PBXBuildFile; fileRef = 18391D1669284AD2EC9E866A /* AvnView.h */; };
 		18391F1E2411C79405A9943A /* WindowProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 1839122E037567BDD1D09DEB /* WindowProtocol.h */; };
@@ -43,16 +46,17 @@
 		AB00E4F72147CA920032A60A /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB00E4F62147CA920032A60A /* main.mm */; };
 		AB1E522C217613570091CD71 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB1E522B217613570091CD71 /* OpenGL.framework */; };
 		AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB661C1D2148230F00291242 /* AppKit.framework */; };
-		AB661C202148286E00291242 /* window.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB661C1F2148286E00291242 /* window.mm */; };
 		AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */; };
 		BC11A5BE2608D58F0017BAD0 /* automation.h in Headers */ = {isa = PBXBuildFile; fileRef = BC11A5BC2608D58F0017BAD0 /* automation.h */; };
 		BC11A5BF2608D58F0017BAD0 /* automation.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC11A5BD2608D58F0017BAD0 /* automation.mm */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
+		183910513F396141938832B5 /* PopupImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopupImpl.h; sourceTree = "<group>"; };
 		1839122E037567BDD1D09DEB /* WindowProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowProtocol.h; sourceTree = "<group>"; };
 		1839132D0E2454D911F1D1F9 /* AvnView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AvnView.mm; sourceTree = "<group>"; };
 		183913C6BFD6856BD42D19FD /* IWindowStateChanged.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IWindowStateChanged.h; sourceTree = "<group>"; };
+		1839155B28B20FFB672D29C6 /* AvnWindow.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AvnWindow.mm; sourceTree = "<group>"; };
 		183915BFF0E234CD3604A7CD /* WindowBaseImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowBaseImpl.h; sourceTree = "<group>"; };
 		18391654EF0E7AB3D3AB4071 /* AutoFitContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoFitContentView.h; sourceTree = "<group>"; };
 		1839166350F32661F3ABD70F /* AutoFitContentView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AutoFitContentView.mm; sourceTree = "<group>"; };
@@ -60,10 +64,11 @@
 		1839171D898F9BFC1373631A /* ResizeScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResizeScope.h; sourceTree = "<group>"; };
 		18391884C7476DA4E53A492D /* AvnPanelWindow.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AvnPanelWindow.mm; sourceTree = "<group>"; };
 		183919BF108EB72A029F7671 /* WindowImpl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WindowImpl.mm; sourceTree = "<group>"; };
+		18391BB698579F40F1783F31 /* PopupImpl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PopupImpl.mm; sourceTree = "<group>"; };
 		18391BBB7782C296D424071F /* INSWindowHolder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INSWindowHolder.h; sourceTree = "<group>"; };
 		18391CD090AA776E7E841AC9 /* WindowImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowImpl.h; sourceTree = "<group>"; };
 		18391D1669284AD2EC9E866A /* AvnView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AvnView.h; sourceTree = "<group>"; };
-		18391DC046BC700D56DF0B82 /* AvnPanelWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AvnPanelWindow.h; sourceTree = "<group>"; };
+		18391DB45C7D892E61BF388C /* WindowInterfaces.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowInterfaces.h; sourceTree = "<group>"; };
 		18391E45702740FE9DD69695 /* ResizeScope.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ResizeScope.mm; sourceTree = "<group>"; };
 		1A002B9D232135EE00021753 /* app.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = app.mm; sourceTree = "<group>"; };
 		1A1852DB23E05814008F0DED /* deadlock.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = deadlock.mm; sourceTree = "<group>"; };
@@ -78,7 +83,6 @@
 		37A4E71A2178846A00EACBCD /* headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = headers; path = ../../inc; sourceTree = "<group>"; };
 		37A517B22159597E00FBA241 /* Screens.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Screens.mm; sourceTree = "<group>"; };
 		37C09D8721580FE4006A6758 /* SystemDialogs.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SystemDialogs.mm; sourceTree = "<group>"; };
-		37C09D8A21581EF2006A6758 /* window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = window.h; sourceTree = "<group>"; };
 		37DDA9AF219330F8002E132B /* AvnString.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AvnString.mm; sourceTree = "<group>"; };
 		37DDA9B121933371002E132B /* AvnString.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AvnString.h; sourceTree = "<group>"; };
 		37E2330E21583241000CB7E2 /* KeyTransform.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyTransform.mm; sourceTree = "<group>"; };
@@ -92,7 +96,6 @@
 		AB00E4F62147CA920032A60A /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; };
 		AB1E522B217613570091CD71 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
 		AB661C1D2148230F00291242 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
-		AB661C1F2148286E00291242 /* window.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = window.mm; sourceTree = "<group>"; };
 		AB661C212148288600291242 /* common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
 		AB7A61EF2147C815003C5833 /* libAvalonia.Native.OSX.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libAvalonia.Native.OSX.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
 		AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = platformthreading.mm; sourceTree = "<group>"; };
@@ -148,8 +151,6 @@
 				AB661C212148288600291242 /* common.h */,
 				379860FE214DA0C000CD0246 /* KeyTransform.h */,
 				37E2330E21583241000CB7E2 /* KeyTransform.mm */,
-				AB661C1F2148286E00291242 /* window.mm */,
-				37C09D8A21581EF2006A6758 /* window.h */,
 				AB00E4F62147CA920032A60A /* main.mm */,
 				37155CE3233C00EB0034DCE9 /* menu.h */,
 				520624B222973F4100C4DCEF /* menu.mm */,
@@ -173,8 +174,11 @@
 				1839166350F32661F3ABD70F /* AutoFitContentView.mm */,
 				18391654EF0E7AB3D3AB4071 /* AutoFitContentView.h */,
 				18391884C7476DA4E53A492D /* AvnPanelWindow.mm */,
-				18391DC046BC700D56DF0B82 /* AvnPanelWindow.h */,
 				1839122E037567BDD1D09DEB /* WindowProtocol.h */,
+				1839155B28B20FFB672D29C6 /* AvnWindow.mm */,
+				18391DB45C7D892E61BF388C /* WindowInterfaces.h */,
+				18391BB698579F40F1783F31 /* PopupImpl.mm */,
+				183910513F396141938832B5 /* PopupImpl.h */,
 			);
 			sourceTree = "<group>";
 		};
@@ -202,8 +206,9 @@
 				18391C28BF1823B5464FDD36 /* ResizeScope.h in Headers */,
 				18391ED5F611FF62C45F196D /* AvnView.h in Headers */,
 				18391E1381E2D5BFD60265A9 /* AutoFitContentView.h in Headers */,
-				1839196EC57BBC5C8BE1C735 /* AvnPanelWindow.h in Headers */,
 				18391F1E2411C79405A9943A /* WindowProtocol.h in Headers */,
+				183914E50CF6D2EFC1667F7C /* WindowInterfaces.h in Headers */,
+				18391AC65ADD7DDD33FBE737 /* PopupImpl.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -282,13 +287,14 @@
 				1A465D10246AB61600C5858B /* dnd.mm in Sources */,
 				AB00E4F72147CA920032A60A /* main.mm in Sources */,
 				37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */,
-				AB661C202148286E00291242 /* window.mm in Sources */,
 				1839179A55FC1421BEE83330 /* WindowBaseImpl.mm in Sources */,
 				1839125F057B0A4EB1760058 /* WindowImpl.mm in Sources */,
 				18391068E48EF96E3DB5FDAB /* ResizeScope.mm in Sources */,
 				18391D4EB311BC7EF8B8C0A6 /* AvnView.mm in Sources */,
 				18391AA7E0BBA74D184C5734 /* AutoFitContentView.mm in Sources */,
 				1839151F32D1BB1AB51A7BB6 /* AvnPanelWindow.mm in Sources */,
+				18391AC16726CBC45856233B /* AvnWindow.mm in Sources */,
+				18391D8CD1756DC858DC1A09 /* PopupImpl.mm in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

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

@@ -1,9 +0,0 @@
-//
-// Created by Dan Walmsley on 06/05/2022.
-// Copyright (c) 2022 Avalonia. All rights reserved.
-//
-
-#define NSWindow NSPanel
-#define AvnWindow AvnPanelWindow
-
-//#include "window.h"

+ 5 - 2
native/Avalonia.Native/src/OSX/AvnPanelWindow.mm

@@ -3,6 +3,9 @@
 // Copyright (c) 2022 Avalonia. All rights reserved.
 //
 
-#define AvnWindow AvnPanelWindow
+#pragma once
+
+#define IS_NSPANEL
+
+#include "AvnWindow.mm"
 
-//#include "window.mm"

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

@@ -2,17 +2,15 @@
 // Created by Dan Walmsley on 05/05/2022.
 // Copyright (c) 2022 Avalonia. All rights reserved.
 //
-
+#pragma once
 #import <Foundation/Foundation.h>
 
 
 #import <Foundation/Foundation.h>
 #import <AppKit/AppKit.h>
-#include "window.h"
-#import "comimpl.h"
-#import "common.h"
-#import "WindowImpl.h"
-#import "KeyTransform.h"
+#include "common.h"
+#include "WindowImpl.h"
+#include "KeyTransform.h"
 
 @class AvnAccessibilityElement;
 

+ 2 - 1
native/Avalonia.Native/src/OSX/AvnView.mm

@@ -4,8 +4,9 @@
 //
 
 #import <AppKit/AppKit.h>
-#import "AvnView.h"
+#include "AvnView.h"
 #include "automation.h"
+#import "WindowInterfaces.h"
 
 @implementation AvnView
 {

+ 75 - 114
native/Avalonia.Native/src/OSX/window.mm → native/Avalonia.Native/src/OSX/AvnWindow.mm

@@ -1,13 +1,32 @@
+//
+// Created by Dan Walmsley on 06/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+
 #import <AppKit/AppKit.h>
-#import "common.h"
-#import "window.h"
-#import "menu.h"
-#import "automation.h"
+#import "WindowProtocol.h"
 #import "WindowBaseImpl.h"
-#import "WindowImpl.h"
-#import "AvnView.h"
 
-@implementation AvnWindow
+#ifdef IS_NSPANEL
+#define BASE_CLASS NSPanel
+#define CLASS_NAME AvnPanel
+#else
+#define BASE_CLASS NSWindow
+#define CLASS_NAME AvnWindow
+#endif
+
+#import <AppKit/AppKit.h>
+#include "common.h"
+#include "menu.h"
+#include "automation.h"
+#include "WindowBaseImpl.h"
+#include "WindowImpl.h"
+#include "AvnView.h"
+#include "WindowInterfaces.h"
+#include "PopupImpl.h"
+
+@implementation CLASS_NAME
 {
     ComPtr<WindowBaseImpl> _parent;
     bool _canBecomeKeyAndMain;
@@ -66,7 +85,7 @@
 - (void)pollModalSession:(nonnull NSModalSession)session
 {
     auto response = [NSApp runModalSession:session];
-    
+
     if(response == NSModalResponseContinue)
     {
         dispatch_async(dispatch_get_main_queue(), ^{
@@ -85,18 +104,18 @@
     if(_menu != nullptr)
     {
         auto appMenuItem = ::GetAppMenuItem();
-        
+
         if(appMenuItem != nullptr)
         {
             auto appMenu = [appMenuItem menu];
-            
+
             [appMenu removeItem:appMenuItem];
-            
+
             [_menu insertItem:appMenuItem atIndex:0];
-            
+
             [_menu setHasGlobalMenuItem:true];
         }
-        
+
         [NSApp setMenu:_menu];
     }
     else
@@ -108,22 +127,22 @@
 -(void) showAppMenuOnly
 {
     auto appMenuItem = ::GetAppMenuItem();
-    
+
     if(appMenuItem != nullptr)
     {
         auto appMenu = ::GetAppMenu();
-        
+
         auto nativeAppMenu = dynamic_cast<AvnAppMenu*>(appMenu);
-        
+
         [[appMenuItem menu] removeItem:appMenuItem];
-        
+
         if(_menu != nullptr)
         {
             [_menu setHasGlobalMenuItem:false];
         }
-        
+
         [nativeAppMenu->GetNative() addItem:appMenuItem];
-        
+
         [NSApp setMenu:nativeAppMenu->GetNative()];
     }
 }
@@ -134,7 +153,7 @@
     {
         menu = [AvnMenu new];
     }
-    
+
     _menu = menu;
 }
 
@@ -143,19 +162,19 @@
     _canBecomeKeyAndMain = true;
 }
 
--(AvnWindow*)  initWithParent: (WindowBaseImpl*) parent contentRect: (NSRect)contentRect styleMask: (NSWindowStyleMask)styleMask;
+-(CLASS_NAME*)  initWithParent: (WindowBaseImpl*) parent contentRect: (NSRect)contentRect styleMask: (NSWindowStyleMask)styleMask;
 {
     // https://jameshfisher.com/2020/07/10/why-is-the-contentrect-of-my-nswindow-ignored/
     // create nswindow with specific contentRect, otherwise we wont be able to resize the window
     // until several ms after the window is physically on the screen.
     self = [super initWithContentRect:contentRect styleMask: styleMask backing:NSBackingStoreBuffered defer:false];
-    
+
     [self setReleasedWhenClosed:false];
     _parent = parent;
     [self setDelegate:self];
     _closed = false;
     _isEnabled = true;
-    
+
     [self backingScaleFactor];
     [self setOpaque:NO];
     [self setBackgroundColor: [NSColor clearColor]];
@@ -167,12 +186,12 @@
 - (BOOL)windowShouldClose:(NSWindow *)sender
 {
     auto window = dynamic_cast<WindowImpl*>(_parent.getRaw());
-    
+
     if(window != nullptr)
     {
         return !window->WindowEvents->Closing();
     }
-    
+
     return true;
 }
 
@@ -201,16 +220,17 @@
         // If the window has a child window being shown as a dialog then don't allow it to become the key window.
         for(NSWindow* uch in [self childWindows])
         {
-            auto ch = objc_cast<AvnWindow>(uch);
+            // TODO protocol
+            auto ch = objc_cast<CLASS_NAME>(uch);
             if(ch == nil)
                 continue;
             if (ch.isDialog)
                 return false;
         }
-        
+
         return true;
     }
-    
+
     return false;
 }
 
@@ -232,7 +252,7 @@
 -(void)becomeKeyWindow
 {
     [self showWindowMenuWithAppMenu];
-    
+
     if(_parent != nullptr)
     {
         _parent->BaseEvents->Activated();
@@ -243,7 +263,8 @@
 
 -(void) restoreParentWindow;
 {
-    auto parent = objc_cast<AvnWindow>([self parentWindow]);
+    // TODO protocol
+    auto parent = objc_cast<CLASS_NAME>([self parentWindow]);
     if(parent != nil)
     {
         [parent removeChildWindow:self];
@@ -253,7 +274,7 @@
 - (void)windowDidMiniaturize:(NSNotification *)notification
 {
     auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
-    
+
     if(parent != nullptr)
     {
         parent->WindowStateChanged();
@@ -263,7 +284,7 @@
 - (void)windowDidDeminiaturize:(NSNotification *)notification
 {
     auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
-    
+
     if(parent != nullptr)
     {
         parent->WindowStateChanged();
@@ -273,7 +294,7 @@
 - (void)windowDidResize:(NSNotification *)notification
 {
     auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
-    
+
     if(parent != nullptr)
     {
         parent->WindowStateChanged();
@@ -283,7 +304,7 @@
 - (void)windowWillExitFullScreen:(NSNotification *)notification
 {
     auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
-    
+
     if(parent != nullptr)
     {
         parent->StartStateTransition();
@@ -293,22 +314,22 @@
 - (void)windowDidExitFullScreen:(NSNotification *)notification
 {
     auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
-    
+
     if(parent != nullptr)
     {
         parent->EndStateTransition();
-        
+
         if(parent->Decorations() != SystemDecorationsFull && parent->WindowState() == Maximized)
         {
             NSRect screenRect = [[self screen] visibleFrame];
             [self setFrame:screenRect display:YES];
         }
-        
+
         if(parent->WindowState() == Minimized)
         {
             [self miniaturize:nullptr];
         }
-        
+
         parent->WindowStateChanged();
     }
 }
@@ -316,7 +337,7 @@
 - (void)windowWillEnterFullScreen:(NSNotification *)notification
 {
     auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
-    
+
     if(parent != nullptr)
     {
         parent->StartStateTransition();
@@ -326,7 +347,7 @@
 - (void)windowDidEnterFullScreen:(NSNotification *)notification
 {
     auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
-    
+
     if(parent != nullptr)
     {
         parent->EndStateTransition();
@@ -343,20 +364,20 @@
 {
     if(_parent)
         _parent->BaseEvents->Deactivated();
-    
+
     [self showAppMenuOnly];
-    
+
     [super resignKeyWindow];
 }
 
 - (void)windowDidMove:(NSNotification *)notification
 {
     AvnPoint position;
-    
+
     if(_parent != nullptr)
     {
         auto cparent = dynamic_cast<WindowImpl*>(_parent.getRaw());
-        
+
         if(cparent != nullptr)
         {
             if(cparent->WindowState() == Maximized)
@@ -364,7 +385,7 @@
                 cparent->SetWindowState(Normal);
             }
         }
-        
+
         _parent->GetPosition(&position);
         _parent->BaseEvents->PositionChanged(position);
     }
@@ -379,7 +400,7 @@
 - (void)sendEvent:(NSEvent *)event
 {
     [super sendEvent:event];
-    
+
     /// This is to detect non-client clicks. This can only be done on Windows... not popups, hence the dynamic_cast.
     if(_parent != nullptr && dynamic_cast<WindowImpl*>(_parent.getRaw()) != nullptr)
     {
@@ -390,30 +411,30 @@
                 AvnView* view = _parent->View;
                 NSPoint windowPoint = [event locationInWindow];
                 NSPoint viewPoint = [view convertPoint:windowPoint fromView:nil];
-                
+
                 if (!NSPointInRect(viewPoint, view.bounds))
                 {
                     auto avnPoint = [AvnView toAvnPoint:windowPoint];
                     auto point = [self translateLocalPoint:avnPoint];
                     AvnVector delta = { 0, 0 };
-                   
+
                     _parent->BaseEvents->RawMouseEvent(NonClientLeftButtonDown, static_cast<uint32>([event timestamp] * 1000), AvnInputModifiersNone, point, delta);
                 }
             }
-            break;
-                
+                break;
+
             case NSEventTypeMouseEntered:
             {
                 _parent->UpdateCursor();
             }
-            break;
-                
+                break;
+
             case NSEventTypeMouseExited:
             {
                 [[NSCursor arrowCursor] set];
             }
-            break;
-                
+                break;
+
             default:
                 break;
         }
@@ -422,63 +443,3 @@
 
 @end
 
-class PopupImpl : public virtual WindowBaseImpl, public IAvnPopup
-{
-private:
-    BEGIN_INTERFACE_MAP()
-    INHERIT_INTERFACE_MAP(WindowBaseImpl)
-    INTERFACE_MAP_ENTRY(IAvnPopup, IID_IAvnPopup)
-    END_INTERFACE_MAP()
-    virtual ~PopupImpl(){}
-    ComPtr<IAvnWindowEvents> WindowEvents;
-    PopupImpl(IAvnWindowEvents* events, IAvnGlContext* gl) : WindowBaseImpl(events, gl)
-    {
-        WindowEvents = events;
-        [Window setLevel:NSPopUpMenuWindowLevel];
-    }
-protected:
-    virtual NSWindowStyleMask GetStyle() override
-    {
-        return NSWindowStyleMaskBorderless;
-    }
-    
-    virtual HRESULT Resize(double x, double y, AvnPlatformResizeReason reason) override
-    {
-        START_COM_CALL;
-        
-        @autoreleasepool
-        {
-            if (Window != nullptr)
-            {
-                [Window setContentSize:NSSize{x, y}];
-            
-                [Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(lastPositionSet))];
-            }
-            
-            return S_OK;
-        }
-    }
-public:
-    virtual bool ShouldTakeFocusOnShow() override
-    {
-        return false;
-    }
-};
-
-extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events, IAvnGlContext* gl)
-{
-    @autoreleasepool
-    {
-        IAvnPopup* ptr = dynamic_cast<IAvnPopup*>(new PopupImpl(events, gl));
-        return ptr;
-    }
-}
-
-extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events, IAvnGlContext* gl)
-{
-    @autoreleasepool
-    {
-        IAvnWindow* ptr = (IAvnWindow*)new WindowImpl(events, gl);
-        return ptr;
-    }
-}

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

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

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

@@ -0,0 +1,68 @@
+//
+// Created by Dan Walmsley on 06/05/2022.
+// Copyright (c) 2022 Avalonia. All rights reserved.
+//
+
+#include "WindowInterfaces.h"
+#include "AvnView.h"
+#include "WindowImpl.h"
+#include "automation.h"
+#include "menu.h"
+#include "common.h"
+#import "WindowBaseImpl.h"
+#import "WindowProtocol.h"
+#import <AppKit/AppKit.h>
+#include "PopupImpl.h"
+
+class PopupImpl : public virtual WindowBaseImpl, public IAvnPopup
+{
+private:
+    BEGIN_INTERFACE_MAP()
+    INHERIT_INTERFACE_MAP(WindowBaseImpl)
+    INTERFACE_MAP_ENTRY(IAvnPopup, IID_IAvnPopup)
+    END_INTERFACE_MAP()
+    virtual ~PopupImpl(){}
+    ComPtr<IAvnWindowEvents> WindowEvents;
+    PopupImpl(IAvnWindowEvents* events, IAvnGlContext* gl) : WindowBaseImpl(events, gl)
+    {
+        WindowEvents = events;
+        [Window setLevel:NSPopUpMenuWindowLevel];
+    }
+protected:
+    virtual NSWindowStyleMask GetStyle() override
+    {
+        return NSWindowStyleMaskBorderless;
+    }
+
+    virtual HRESULT Resize(double x, double y, AvnPlatformResizeReason reason) override
+    {
+        START_COM_CALL;
+
+        @autoreleasepool
+        {
+            if (Window != nullptr)
+            {
+                [Window setContentSize:NSSize{x, y}];
+
+                [Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(lastPositionSet))];
+            }
+
+            return S_OK;
+        }
+    }
+public:
+    virtual bool ShouldTakeFocusOnShow() override
+    {
+        return false;
+    }
+};
+
+
+extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events, IAvnGlContext* gl)
+{
+    @autoreleasepool
+    {
+        IAvnPopup* ptr = dynamic_cast<IAvnPopup*>(new PopupImpl(events, gl));
+        return ptr;
+    }
+}

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

@@ -6,7 +6,6 @@
 #ifndef AVALONIA_NATIVE_OSX_RESIZESCOPE_H
 #define AVALONIA_NATIVE_OSX_RESIZESCOPE_H
 
-#include "window.h"
 #include "avalonia-native.h"
 
 @class AvnView;

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

@@ -5,7 +5,7 @@
 
 #import <AppKit/AppKit.h>
 #include "ResizeScope.h"
-#import "AvnView.h"
+#include "AvnView.h"
 
 ResizeScope::ResizeScope(AvnView *view, AvnPlatformResizeReason reason) {
     _view = view;

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

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

+ 3 - 2
native/Avalonia.Native/src/OSX/WindowBaseImpl.h

@@ -6,11 +6,12 @@
 #ifndef AVALONIA_NATIVE_OSX_WINDOWBASEIMPL_H
 #define AVALONIA_NATIVE_OSX_WINDOWBASEIMPL_H
 
-#import "rendertarget.h"
-#import "WindowProtocol.h"
+#include "rendertarget.h"
 #include "INSWindowHolder.h"
 
 @class AutoFitContentView;
+@class AvnMenu;
+@protocol AvnWindowProtocol;
 
 class WindowBaseImpl : public virtual ComObject,
                        public virtual IAvnWindowBase,

+ 14 - 5
native/Avalonia.Native/src/OSX/WindowBaseImpl.mm

@@ -5,14 +5,14 @@
 
 #import <AppKit/AppKit.h>
 #include "common.h"
-#import "window.h"
-#import "AvnView.h"
+#include "AvnView.h"
 #include "menu.h"
 #include "automation.h"
-#import "cursor.h"
+#include "cursor.h"
 #include "ResizeScope.h"
-#import "AutoFitContentView.h"
-#include "WindowBaseImpl.h"
+#include "AutoFitContentView.h"
+#import "WindowProtocol.h"
+#import "WindowInterfaces.h"
 
 
 WindowBaseImpl::~WindowBaseImpl() {
@@ -558,3 +558,12 @@ id <AvnWindowProtocol> WindowBaseImpl::GetWindowProtocol() {
 
     return instance;
 }
+
+extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events, IAvnGlContext* gl)
+{
+    @autoreleasepool
+    {
+        IAvnWindow* ptr = (IAvnWindow*)new WindowImpl(events, gl);
+        return ptr;
+    }
+}

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

@@ -6,7 +6,6 @@
 #ifndef AVALONIA_NATIVE_OSX_WINDOWIMPL_H
 #define AVALONIA_NATIVE_OSX_WINDOWIMPL_H
 
-
 #import "WindowBaseImpl.h"
 #include "IWindowStateChanged.h"
 

+ 3 - 3
native/Avalonia.Native/src/OSX/WindowImpl.mm

@@ -4,10 +4,10 @@
 //
 
 #import <AppKit/AppKit.h>
-#import "window.h"
-#import "AutoFitContentView.h"
-#import "AvnView.h"
+#include "AutoFitContentView.h"
+#include "AvnView.h"
 #include "automation.h"
+#include "WindowProtocol.h"
 
 WindowImpl::WindowImpl(IAvnWindowEvents *events, IAvnGlContext *gl) : WindowBaseImpl(events, gl) {
     _isClientAreaExtended = false;

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

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

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

@@ -3,6 +3,8 @@
 // Copyright (c) 2022 Avalonia. All rights reserved.
 //
 
+#pragma once
+
 #import <AppKit/AppKit.h>
 
 @class AvnMenu;

+ 2 - 1
native/Avalonia.Native/src/OSX/automation.h

@@ -1,5 +1,6 @@
-#import <Cocoa/Cocoa.h>
+#pragma once
 
+#import <Cocoa/Cocoa.h>
 NS_ASSUME_NONNULL_BEGIN
 
 class IAvnAutomationPeer;

+ 3 - 4
native/Avalonia.Native/src/OSX/automation.mm

@@ -1,9 +1,8 @@
 #include "common.h"
-#import "automation.h"
-#import "window.h"
+#include "automation.h"
 #include "AvnString.h"
-#import "INSWindowHolder.h"
-#import "AvnView.h"
+#include "INSWindowHolder.h"
+#include "AvnView.h"
 
 @interface AvnAccessibilityElement (Events)
 - (void) raiseChildrenChanged;

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

@@ -1,7 +1,6 @@
 //This file will contain actual IID structures
 #define COM_GUIDS_MATERIALIZE
 #include "common.h"
-#include "window.h"
 
 static NSString* s_appTitle = @"Avalonia";
 

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

@@ -1,7 +1,6 @@
 
 #include "common.h"
 #include "menu.h"
-#import "window.h"
 #include "KeyTransform.h"
 #include <CoreFoundation/CoreFoundation.h>
 #include <Carbon/Carbon.h> /* For kVK_ constants, and TIS functions. */

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

@@ -1,15 +0,0 @@
-#ifndef window_h
-#define window_h
-
-#import "avalonia-native.h"
-#import "WindowProtocol.h"
-
-@class AvnMenu;
-
-class WindowBaseImpl;
-
-@interface AvnWindow : NSWindow <AvnWindowProtocol, NSWindowDelegate>
--(AvnWindow* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent contentRect: (NSRect)contentRect styleMask: (NSWindowStyleMask)styleMask;
-@end
-
-#endif /* window_h */

+ 1 - 0
src/Avalonia.Native/avn.idl

@@ -2,6 +2,7 @@
 @clr-access internal
 @clr-map bool int
 @cpp-preamble @@
+#pragma once
 #include "com.h"
 #include "stddef.h"
 @@