diff --git a/build/ReactiveUI.props b/build/ReactiveUI.props
index f74ab07e31..c3b136d41d 100644
--- a/build/ReactiveUI.props
+++ b/build/ReactiveUI.props
@@ -1,5 +1,5 @@
-
+
diff --git a/native/Avalonia.Native/src/OSX/AvnString.h b/native/Avalonia.Native/src/OSX/AvnString.h
index 5d299374e5..3ce83d370a 100644
--- a/native/Avalonia.Native/src/OSX/AvnString.h
+++ b/native/Avalonia.Native/src/OSX/AvnString.h
@@ -11,6 +11,7 @@
extern IAvnString* CreateAvnString(NSString* string);
extern IAvnStringArray* CreateAvnStringArray(NSArray* array);
+extern IAvnStringArray* CreateAvnStringArray(NSArray* array);
extern IAvnStringArray* CreateAvnStringArray(NSString* string);
extern IAvnString* CreateByteArray(void* data, int len);
#endif /* AvnString_h */
diff --git a/native/Avalonia.Native/src/OSX/AvnString.mm b/native/Avalonia.Native/src/OSX/AvnString.mm
index 00b748ef63..001cf151d8 100644
--- a/native/Avalonia.Native/src/OSX/AvnString.mm
+++ b/native/Avalonia.Native/src/OSX/AvnString.mm
@@ -85,6 +85,16 @@ public:
}
}
+ AvnStringArrayImpl(NSArray* array)
+ {
+ for(int c = 0; c < [array count]; c++)
+ {
+ ComPtr s;
+ *s.getPPV() = new AvnStringImpl([array objectAtIndex:c].absoluteString);
+ _list.push_back(s);
+ }
+ }
+
AvnStringArrayImpl(NSString* string)
{
ComPtr s;
@@ -117,6 +127,11 @@ IAvnStringArray* CreateAvnStringArray(NSArray * array)
return new AvnStringArrayImpl(array);
}
+IAvnStringArray* CreateAvnStringArray(NSArray * array)
+{
+ return new AvnStringArrayImpl(array);
+}
+
IAvnStringArray* CreateAvnStringArray(NSString* string)
{
return new AvnStringArrayImpl(string);
diff --git a/native/Avalonia.Native/src/OSX/app.mm b/native/Avalonia.Native/src/OSX/app.mm
index 814b91cb62..460c24ea3a 100644
--- a/native/Avalonia.Native/src/OSX/app.mm
+++ b/native/Avalonia.Native/src/OSX/app.mm
@@ -1,10 +1,20 @@
#include "common.h"
+#include "AvnString.h"
@interface AvnAppDelegate : NSObject
+-(AvnAppDelegate* _Nonnull) initWithEvents: (IAvnApplicationEvents* _Nonnull) events;
@end
NSApplicationActivationPolicy AvnDesiredActivationPolicy = NSApplicationActivationPolicyRegular;
@implementation AvnAppDelegate
+ComPtr _events;
+
+- (AvnAppDelegate *)initWithEvents:(IAvnApplicationEvents *)events
+{
+ _events = events;
+ return self;
+}
+
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
if([[NSApplication sharedApplication] activationPolicy] != AvnDesiredActivationPolicy)
@@ -27,11 +37,23 @@ NSApplicationActivationPolicy AvnDesiredActivationPolicy = NSApplicationActivati
[[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
}
+- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
+{
+ auto array = CreateAvnStringArray(filenames);
+
+ _events->FilesOpened(array);
+}
+
+- (void)application:(NSApplication *)application openURLs:(NSArray *)urls
+{
+ auto array = CreateAvnStringArray(urls);
+
+ _events->FilesOpened(array);
+}
@end
@interface AvnApplication : NSApplication
-
@end
@implementation AvnApplication
@@ -63,9 +85,9 @@ NSApplicationActivationPolicy AvnDesiredActivationPolicy = NSApplicationActivati
@end
-extern void InitializeAvnApp()
+extern void InitializeAvnApp(IAvnApplicationEvents* events)
{
NSApplication* app = [AvnApplication sharedApplication];
- id delegate = [AvnAppDelegate new];
+ id delegate = [[AvnAppDelegate alloc] initWithEvents:events];
[app setDelegate:delegate];
}
diff --git a/native/Avalonia.Native/src/OSX/clipboard.mm b/native/Avalonia.Native/src/OSX/clipboard.mm
index 303f727317..f148374759 100644
--- a/native/Avalonia.Native/src/OSX/clipboard.mm
+++ b/native/Avalonia.Native/src/OSX/clipboard.mm
@@ -56,7 +56,7 @@ public:
return S_OK;
}
- NSArray* arr = (NSArray*)data;
+ NSArray* arr = (NSArray*)data;
for(int c = 0; c < [arr count]; c++)
if(![[arr objectAtIndex:c] isKindOfClass:[NSString class]])
diff --git a/native/Avalonia.Native/src/OSX/common.h b/native/Avalonia.Native/src/OSX/common.h
index ea48a19874..c082003ccf 100644
--- a/native/Avalonia.Native/src/OSX/common.h
+++ b/native/Avalonia.Native/src/OSX/common.h
@@ -23,13 +23,15 @@ extern IAvnCursorFactory* CreateCursorFactory();
extern IAvnGlDisplay* GetGlDisplay();
extern IAvnMenu* CreateAppMenu(IAvnMenuEvents* events);
extern IAvnMenuItem* CreateAppMenuItem();
-extern IAvnMenuItem* CreateAppMenuItemSeperator();
+extern IAvnMenuItem* CreateAppMenuItemSeparator();
extern IAvnNativeControlHost* CreateNativeControlHost(NSView* parent);
extern void SetAppMenu (NSString* appName, IAvnMenu* appMenu);
extern IAvnMenu* GetAppMenu ();
extern NSMenuItem* GetAppMenuItem ();
+extern void SetAutoGenerateDefaultAppMenuItems (bool enabled);
+extern bool GetAutoGenerateDefaultAppMenuItems ();
-extern void InitializeAvnApp();
+extern void InitializeAvnApp(IAvnApplicationEvents* events);
extern NSApplicationActivationPolicy AvnDesiredActivationPolicy;
extern NSPoint ToNSPoint (AvnPoint p);
extern AvnPoint ToAvnPoint (NSPoint p);
diff --git a/native/Avalonia.Native/src/OSX/main.mm b/native/Avalonia.Native/src/OSX/main.mm
index 72f5aa0a7d..aaaf381b26 100644
--- a/native/Avalonia.Native/src/OSX/main.mm
+++ b/native/Avalonia.Native/src/OSX/main.mm
@@ -2,6 +2,7 @@
#define COM_GUIDS_MATERIALIZE
#include "common.h"
+static bool s_generateDefaultAppMenuItems = true;
static NSString* s_appTitle = @"Avalonia";
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
@@ -122,6 +123,12 @@ public:
? NSApplicationActivationPolicyRegular : NSApplicationActivationPolicyAccessory;
return S_OK;
}
+
+ virtual HRESULT SetDisableDefaultApplicationMenuItems (bool enabled) override
+ {
+ SetAutoGenerateDefaultAppMenuItems(!enabled);
+ return S_OK;
+ }
};
/// See "Using POSIX Threads in a Cocoa Application" section here:
@@ -156,13 +163,13 @@ class AvaloniaNative : public ComSingleObject
{
private:
@@ -71,10 +70,12 @@ public:
FORWARD_IUNKNOWN()
AvnAppMenu(IAvnMenuEvents* events);
-
+
AvnMenu* GetNative();
void RaiseNeedsUpdate ();
+ void RaiseOpening();
+ void RaiseClosed();
virtual HRESULT InsertItem (int index, IAvnMenuItem* item) override;
diff --git a/native/Avalonia.Native/src/OSX/menu.mm b/native/Avalonia.Native/src/OSX/menu.mm
index 198b01714f..b9a95e7b3c 100644
--- a/native/Avalonia.Native/src/OSX/menu.mm
+++ b/native/Avalonia.Native/src/OSX/menu.mm
@@ -71,12 +71,12 @@
}
@end
-AvnAppMenuItem::AvnAppMenuItem(bool isSeperator)
+AvnAppMenuItem::AvnAppMenuItem(bool isSeparator)
{
_isCheckable = false;
- _isSeperator = isSeperator;
+ _isSeparator = isSeparator;
- if(isSeperator)
+ if(isSeparator)
{
_native = [NSMenuItem separatorItem];
}
@@ -298,6 +298,23 @@ void AvnAppMenu::RaiseNeedsUpdate()
}
}
+void AvnAppMenu::RaiseOpening()
+{
+ if(_baseEvents != nullptr)
+ {
+ _baseEvents->Opening();
+ }
+}
+
+void AvnAppMenu::RaiseClosed()
+{
+ if(_baseEvents != nullptr)
+ {
+ _baseEvents->Closed();
+ }
+}
+
+
HRESULT AvnAppMenu::InsertItem(int index, IAvnMenuItem *item)
{
@autoreleasepool
@@ -382,6 +399,15 @@ HRESULT AvnAppMenu::Clear()
_parent->RaiseNeedsUpdate();
}
+- (void)menuWillOpen:(NSMenu *)menu
+{
+ _parent->RaiseOpening();
+}
+
+- (void)menuDidClose:(NSMenu *)menu
+{
+ _parent->RaiseClosed();
+}
@end
@@ -401,7 +427,7 @@ extern IAvnMenuItem* CreateAppMenuItem()
}
}
-extern IAvnMenuItem* CreateAppMenuItemSeperator()
+extern IAvnMenuItem* CreateAppMenuItemSeparator()
{
@autoreleasepool
{
@@ -445,47 +471,50 @@ extern void SetAppMenu (NSString* appName, IAvnMenu* menu)
auto appMenu = [s_appMenuItem submenu];
- [appMenu addItem:[NSMenuItem separatorItem]];
-
- // Services item and menu
- auto servicesItem = [[NSMenuItem alloc] init];
- servicesItem.title = @"Services";
- NSMenu *servicesMenu = [[NSMenu alloc] initWithTitle:@"Services"];
- servicesItem.submenu = servicesMenu;
- [NSApplication sharedApplication].servicesMenu = servicesMenu;
- [appMenu addItem:servicesItem];
-
- [appMenu addItem:[NSMenuItem separatorItem]];
-
- // Hide Application
- auto hideItem = [[NSMenuItem alloc] initWithTitle:[@"Hide " stringByAppendingString:appName] action:@selector(hide:) keyEquivalent:@"h"];
-
- [appMenu addItem:hideItem];
-
- // Hide Others
- auto hideAllOthersItem = [[NSMenuItem alloc] initWithTitle:@"Hide Others"
- action:@selector(hideOtherApplications:)
- keyEquivalent:@"h"];
-
- hideAllOthersItem.keyEquivalentModifierMask = NSEventModifierFlagCommand | NSEventModifierFlagOption;
- [appMenu addItem:hideAllOthersItem];
-
- // Show All
- auto showAllItem = [[NSMenuItem alloc] initWithTitle:@"Show All"
- action:@selector(unhideAllApplications:)
- keyEquivalent:@""];
-
- [appMenu addItem:showAllItem];
-
- [appMenu addItem:[NSMenuItem separatorItem]];
-
- // Quit Application
- auto quitItem = [[NSMenuItem alloc] init];
- quitItem.title = [@"Quit " stringByAppendingString:appName];
- quitItem.keyEquivalent = @"q";
- quitItem.target = [AvnWindow class];
- quitItem.action = @selector(closeAll);
- [appMenu addItem:quitItem];
+ if(GetAutoGenerateDefaultAppMenuItems())
+ {
+ [appMenu addItem:[NSMenuItem separatorItem]];
+
+ // Services item and menu
+ auto servicesItem = [[NSMenuItem alloc] init];
+ servicesItem.title = @"Services";
+ NSMenu *servicesMenu = [[NSMenu alloc] initWithTitle:@"Services"];
+ servicesItem.submenu = servicesMenu;
+ [NSApplication sharedApplication].servicesMenu = servicesMenu;
+ [appMenu addItem:servicesItem];
+
+ [appMenu addItem:[NSMenuItem separatorItem]];
+
+ // Hide Application
+ auto hideItem = [[NSMenuItem alloc] initWithTitle:[@"Hide " stringByAppendingString:appName] action:@selector(hide:) keyEquivalent:@"h"];
+
+ [appMenu addItem:hideItem];
+
+ // Hide Others
+ auto hideAllOthersItem = [[NSMenuItem alloc] initWithTitle:@"Hide Others"
+ action:@selector(hideOtherApplications:)
+ keyEquivalent:@"h"];
+
+ hideAllOthersItem.keyEquivalentModifierMask = NSEventModifierFlagCommand | NSEventModifierFlagOption;
+ [appMenu addItem:hideAllOthersItem];
+
+ // Show All
+ auto showAllItem = [[NSMenuItem alloc] initWithTitle:@"Show All"
+ action:@selector(unhideAllApplications:)
+ keyEquivalent:@""];
+
+ [appMenu addItem:showAllItem];
+
+ [appMenu addItem:[NSMenuItem separatorItem]];
+
+ // Quit Application
+ auto quitItem = [[NSMenuItem alloc] init];
+ quitItem.title = [@"Quit " stringByAppendingString:appName];
+ quitItem.keyEquivalent = @"q";
+ quitItem.target = [AvnWindow class];
+ quitItem.action = @selector(closeAll);
+ [appMenu addItem:quitItem];
+ }
}
else
{
diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm
index 7fa6614d4d..b46655c7df 100644
--- a/native/Avalonia.Native/src/OSX/window.mm
+++ b/native/Avalonia.Native/src/OSX/window.mm
@@ -1877,7 +1877,12 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
for(int i = 0; i < numWindows; i++)
{
- [[windows objectAtIndex:i] performClose:nil];
+ auto window = (AvnWindow*)[windows objectAtIndex:i];
+
+ if([window parentWindow] == nullptr) // Avalonia will handle the child windows.
+ {
+ [window performClose:nil];
+ }
}
}
@@ -2226,9 +2231,12 @@ protected:
{
@autoreleasepool
{
- [Window setContentSize:NSSize{x, y}];
+ if (Window != nullptr)
+ {
+ [Window setContentSize:NSSize{x, y}];
- [Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(lastPositionSet))];
+ [Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(lastPositionSet))];
+ }
return S_OK;
}
diff --git a/nukebuild/Build.cs b/nukebuild/Build.cs
index 8e331edab4..d627a2bf19 100644
--- a/nukebuild/Build.cs
+++ b/nukebuild/Build.cs
@@ -89,10 +89,6 @@ partial class Build : NukeBuild
Process.Start(new ProcessStartInfo(command, args) {UseShellExecute = false}).WaitForExit();
}
ExecWait("dotnet version:", "dotnet", "--version");
- if (Parameters.IsRunningOnUnix)
- ExecWait("Mono version:", "mono", "--version");
-
-
}
IReadOnlyCollection