diff --git a/build/Microsoft.Reactive.Testing.props b/build/Microsoft.Reactive.Testing.props
index 777bc4bb53..a0ba2163bb 100644
--- a/build/Microsoft.Reactive.Testing.props
+++ b/build/Microsoft.Reactive.Testing.props
@@ -1,5 +1,5 @@
-
+
diff --git a/build/NetFX.props b/build/NetFX.props
index 4d2841714b..ed5cb6dd69 100644
--- a/build/NetFX.props
+++ b/build/NetFX.props
@@ -1,11 +1,7 @@
-
-
- /usr/lib/mono/4.6.1-api
- /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.6.1-api
-
-
- /usr/lib/mono/4.7-api/
- /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.7-api
-
+
+
+
+
+
diff --git a/build/ReactiveUI.props b/build/ReactiveUI.props
index 1208be34b8..f827cb9a32 100644
--- a/build/ReactiveUI.props
+++ b/build/ReactiveUI.props
@@ -1,5 +1,5 @@
-
+
diff --git a/build/Rx.props b/build/Rx.props
index 359ce53a92..edff0af160 100644
--- a/build/Rx.props
+++ b/build/Rx.props
@@ -1,5 +1,5 @@
-
+
diff --git a/build/SharedVersion.props b/build/SharedVersion.props
index 76abcf6912..44d5c239ef 100644
--- a/build/SharedVersion.props
+++ b/build/SharedVersion.props
@@ -4,11 +4,16 @@
Avalonia
0.8.999
Copyright 2019 © The AvaloniaUI Project
- https://github.com/AvaloniaUI/Avalonia/blob/master/licence.md
- https://github.com/AvaloniaUI/Avalonia/
+ https://avaloniaui.net
https://github.com/AvaloniaUI/Avalonia/
true
CS1591
latest
+ MIT
+ https://avatars2.githubusercontent.com/u/14075148?s=200
+ Avalonia is a WPF/UWP-inspired cross-platform XAML-based UI framework providing a flexible styling system and supporting a wide range of Operating Systems such as Windows (.NET Framework, .NET Core), Linux (via Xorg), MacOS and with experimental support for Android and iOS.
+ avalonia;avaloniaui;mvvm;rx;reactive extensions;android;ios;mac;forms;wpf;net;netstandard;net461;uwp;xamarin
+ https://github.com/AvaloniaUI/Avalonia/releases
+ git
diff --git a/build/System.Memory.props b/build/System.Memory.props
index b328f7fd97..b36998a780 100644
--- a/build/System.Memory.props
+++ b/build/System.Memory.props
@@ -1,5 +1,5 @@
-
+
diff --git a/dirs.proj b/dirs.proj
index e56320e73f..4b3b1183f0 100644
--- a/dirs.proj
+++ b/dirs.proj
@@ -8,7 +8,8 @@
-
+
+
diff --git a/native/Avalonia.Native/inc/avalonia-native.h b/native/Avalonia.Native/inc/avalonia-native.h
index a35f4f3eeb..e54f3fa6a7 100644
--- a/native/Avalonia.Native/inc/avalonia-native.h
+++ b/native/Avalonia.Native/inc/avalonia-native.h
@@ -52,6 +52,7 @@ struct AvnScreen
{
AvnRect Bounds;
AvnRect WorkingArea;
+ float PixelDensity;
bool Primary;
};
@@ -187,7 +188,6 @@ AVNCOM(IAvnWindowBase, 02) : IUnknown
virtual HRESULT Close() = 0;
virtual HRESULT Activate () = 0;
virtual HRESULT GetClientSize(AvnSize*ret) = 0;
- virtual HRESULT GetMaxClientSize(AvnSize* ret) = 0;
virtual HRESULT GetScaling(double*ret)=0;
virtual HRESULT SetMinMaxSize(AvnSize minSize, AvnSize maxSize) = 0;
virtual HRESULT Resize(double width, double height) = 0;
@@ -280,7 +280,7 @@ AVNCOM(IAvnPlatformThreadingInterface, 0b) : IUnknown
virtual bool GetCurrentThreadIsLoopThread() = 0;
virtual void SetSignaledCallback(IAvnSignaledCallback* cb) = 0;
virtual IAvnLoopCancellation* CreateLoopCancellation() = 0;
- virtual void RunLoop(IAvnLoopCancellation* cancel) = 0;
+ virtual HRESULT RunLoop(IAvnLoopCancellation* cancel) = 0;
// Can't pass int* to sharpgentools for some reason
virtual void Signal(int priority) = 0;
virtual IUnknown* StartTimer(int priority, int ms, IAvnActionCallback* callback) = 0;
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 cc74d5669f..1870ef7ab3 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
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 1A002B9E232135EE00021753 /* app.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A002B9D232135EE00021753 /* app.mm */; };
37A517B32159597E00FBA241 /* Screens.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37A517B22159597E00FBA241 /* Screens.mm */; };
37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C09D8721580FE4006A6758 /* SystemDialogs.mm */; };
37DDA9B0219330F8002E132B /* AvnString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37DDA9AF219330F8002E132B /* AvnString.mm */; };
@@ -22,6 +23,7 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
+ 1A002B9D232135EE00021753 /* app.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = app.mm; sourceTree = ""; };
379860FE214DA0C000CD0246 /* KeyTransform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyTransform.h; sourceTree = ""; };
37A4E71A2178846A00EACBCD /* headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = headers; path = ../../inc; sourceTree = ""; };
37A517B22159597E00FBA241 /* Screens.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Screens.mm; sourceTree = ""; };
@@ -68,6 +70,7 @@
AB7A61E62147C814003C5833 = {
isa = PBXGroup;
children = (
+ 1A002B9D232135EE00021753 /* app.mm */,
37DDA9B121933371002E132B /* AvnString.h */,
37DDA9AF219330F8002E132B /* AvnString.mm */,
37A4E71A2178846A00EACBCD /* headers */,
@@ -164,6 +167,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 1A002B9E232135EE00021753 /* app.mm in Sources */,
5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */,
5B21A982216530F500CEE36E /* cursor.mm in Sources */,
37DDA9B0219330F8002E132B /* AvnString.mm in Sources */,
diff --git a/native/Avalonia.Native/src/OSX/Screens.mm b/native/Avalonia.Native/src/OSX/Screens.mm
index 9d436b98c5..e7f009787a 100644
--- a/native/Avalonia.Native/src/OSX/Screens.mm
+++ b/native/Avalonia.Native/src/OSX/Screens.mm
@@ -38,6 +38,8 @@ class Screens : public ComSingleObject
ret->WorkingArea.Height = [screen visibleFrame].size.height;
ret->WorkingArea.Width = [screen visibleFrame].size.width;
+ ret->PixelDensity = [screen backingScaleFactor];
+
ret->Primary = index == 0;
return S_OK;
diff --git a/native/Avalonia.Native/src/OSX/app.mm b/native/Avalonia.Native/src/OSX/app.mm
new file mode 100644
index 0000000000..81855995b7
--- /dev/null
+++ b/native/Avalonia.Native/src/OSX/app.mm
@@ -0,0 +1,24 @@
+#include "common.h"
+@interface AvnAppDelegate : NSObject
+@end
+extern NSApplicationActivationPolicy AvnDesiredActivationPolicy = NSApplicationActivationPolicyRegular;
+@implementation AvnAppDelegate
+- (void)applicationWillFinishLaunching:(NSNotification *)notification
+{
+ [[NSApplication sharedApplication] setActivationPolicy: AvnDesiredActivationPolicy];
+}
+
+- (void)applicationDidFinishLaunching:(NSNotification *)notification
+{
+ [NSApp activateIgnoringOtherApps:true];
+}
+
+@end
+
+extern void InitializeAvnApp()
+{
+ NSApplication* app = [NSApplication sharedApplication];
+ id delegate = [AvnAppDelegate new];
+ [app setDelegate:delegate];
+
+}
diff --git a/native/Avalonia.Native/src/OSX/common.h b/native/Avalonia.Native/src/OSX/common.h
index f748dd59ad..45ec40c361 100644
--- a/native/Avalonia.Native/src/OSX/common.h
+++ b/native/Avalonia.Native/src/OSX/common.h
@@ -19,12 +19,12 @@ extern IAvnClipboard* CreateClipboard();
extern IAvnCursorFactory* CreateCursorFactory();
extern IAvnGlFeature* GetGlFeature();
extern IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(NSWindow* window, NSView* view);
-
+extern void InitializeAvnApp();
+extern NSApplicationActivationPolicy AvnDesiredActivationPolicy;
extern NSPoint ToNSPoint (AvnPoint p);
extern AvnPoint ToAvnPoint (NSPoint p);
extern AvnPoint ConvertPointY (AvnPoint p);
extern NSSize ToNSSize (AvnSize 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 5043246c53..70bd1e67f6 100644
--- a/native/Avalonia.Native/src/OSX/main.mm
+++ b/native/Avalonia.Native/src/OSX/main.mm
@@ -5,21 +5,14 @@
#define COM_GUIDS_MATERIALIZE
#include "common.h"
-static BOOL ShowInDock = 1;
-
-static void SetActivationPolicy()
-{
- [[NSApplication sharedApplication] setActivationPolicy: (ShowInDock ? NSApplicationActivationPolicyRegular : NSApplicationActivationPolicyAccessory)];
-}
-
class MacOptions : public ComSingleObject
{
public:
FORWARD_IUNKNOWN()
virtual HRESULT SetShowInDock(int show) override
{
- ShowInDock = show;
- SetActivationPolicy();
+ AvnDesiredActivationPolicy = show
+ ? NSApplicationActivationPolicyRegular : NSApplicationActivationPolicyAccessory;
return S_OK;
}
};
@@ -64,8 +57,9 @@ public:
{
@autoreleasepool{
[[ThreadingInitializer new] do];
- return S_OK;
}
+ InitializeAvnApp();
+ return S_OK;
};
virtual IAvnMacOptions* GetMacOptions() override
diff --git a/native/Avalonia.Native/src/OSX/platformthreading.mm b/native/Avalonia.Native/src/OSX/platformthreading.mm
index 0c814b2088..297097584a 100644
--- a/native/Avalonia.Native/src/OSX/platformthreading.mm
+++ b/native/Avalonia.Native/src/OSX/platformthreading.mm
@@ -57,16 +57,36 @@ class PlatformThreadingInterface : public ComSingleObject
{
public:
FORWARD_IUNKNOWN()
- bool Cancelled = 0;
- virtual void Cancel() override
+ bool Running = false;
+ bool Cancelled = false;
+ virtual void Cancel()
{
- Cancelled = 1;
+ Cancelled = true;
+ if(Running)
+ {
+ Running = false;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [[NSApplication sharedApplication] stop:nil];
+ NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined
+ location:NSMakePoint(0, 0)
+ modifierFlags:0
+ timestamp:0
+ windowNumber:0
+ context:nil
+ subtype:0
+ data1:0
+ data2:0];
+ [NSApp postEvent:event atStart:YES];
+ });
+ }
}
+
};
public:
@@ -99,30 +119,17 @@ public:
return new LoopCancellation();
}
- virtual void RunLoop(IAvnLoopCancellation* cancel) override
+ virtual HRESULT RunLoop(IAvnLoopCancellation* cancel) override
{
- @autoreleasepool {
- auto can = dynamic_cast(cancel);
- [[NSApplication sharedApplication] activateIgnoringOtherApps:true];
- while(true)
- {
- @autoreleasepool
- {
- if(can != NULL && can->Cancelled)
- return;
- NSEvent* ev = [[NSApplication sharedApplication]
- nextEventMatchingMask:NSEventMaskAny
- untilDate: [NSDate dateWithTimeIntervalSinceNow:1]
- inMode:NSDefaultRunLoopMode
- dequeue:true];
- if(can != NULL && can->Cancelled)
- return;
- if(ev != NULL)
- [[NSApplication sharedApplication] sendEvent:ev];
- }
- }
- NSDebugLog(@"RunLoop exited");
- }
+ auto can = dynamic_cast(cancel);
+ if(can->Cancelled)
+ return S_OK;
+ if(_wasRunningAtLeastOnce)
+ return E_FAIL;
+ can->Running = true;
+ _wasRunningAtLeastOnce = true;
+ [NSApp run];
+ return S_OK;
}
virtual void Signal(int priority) override
diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm
index bfa33eb259..3347d58004 100644
--- a/native/Avalonia.Native/src/OSX/window.mm
+++ b/native/Avalonia.Native/src/OSX/window.mm
@@ -54,7 +54,6 @@ public:
FORWARD_IUNKNOWN()
virtual ~WindowBaseImpl()
{
- NSDebugLog(@"~WindowBaseImpl()");
View = NULL;
Window = NULL;
}
@@ -161,22 +160,6 @@ public:
}
}
- virtual HRESULT GetMaxClientSize(AvnSize* ret) override
- {
- @autoreleasepool
- {
- if(ret == nullptr)
- return E_POINTER;
-
- auto size = [NSScreen.screens objectAtIndex:0].frame.size;
-
- ret->Height = size.height;
- ret->Width = size.width;
-
- return S_OK;
- }
- }
-
virtual HRESULT GetScaling (double* ret) override
{
@autoreleasepool
@@ -369,12 +352,9 @@ public:
virtual void UpdateCursor()
{
- [View resetCursorRects];
if (cursor != nil)
{
- auto rect = [Window frame];
- [View addCursorRect:rect cursor:cursor];
- [cursor set];
+ [cursor set];
}
}
@@ -416,8 +396,8 @@ private:
INHERIT_INTERFACE_MAP(WindowBaseImpl)
INTERFACE_MAP_ENTRY(IAvnWindow, IID_IAvnWindow)
END_INTERFACE_MAP()
- virtual ~WindowImpl(){
- NSDebugLog(@"~WindowImpl");
+ virtual ~WindowImpl()
+ {
}
ComPtr WindowEvents;
@@ -425,6 +405,7 @@ private:
{
WindowEvents = events;
[Window setCanBecomeKeyAndMain];
+ [Window disableCursorRects];
}
virtual HRESULT Show () override
@@ -664,10 +645,8 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
- (void)dealloc
{
- NSDebugLog(@"AvnView dealloc");
}
-
- (void)onClosed
{
_parent = NULL;
@@ -1067,7 +1046,6 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
- (void)dealloc
{
- NSDebugLog(@"AvnWindow dealloc");
}
- (void)pollModalSession:(nonnull NSModalSession)session
diff --git a/samples/BindingDemo/MainWindow.xaml b/samples/BindingDemo/MainWindow.xaml
index a232a06383..b57a9a0a9e 100644
--- a/samples/BindingDemo/MainWindow.xaml
+++ b/samples/BindingDemo/MainWindow.xaml
@@ -24,6 +24,9 @@
+
diff --git a/samples/BindingDemo/ViewModels/MainWindowViewModel.cs b/samples/BindingDemo/ViewModels/MainWindowViewModel.cs
index 858fb5159a..22d01e0765 100644
--- a/samples/BindingDemo/ViewModels/MainWindowViewModel.cs
+++ b/samples/BindingDemo/ViewModels/MainWindowViewModel.cs
@@ -1,10 +1,11 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
-using ReactiveUI;
+using System.Reactive;
using System.Reactive.Linq;
using System.Threading.Tasks;
using System.Threading;
+using ReactiveUI;
namespace BindingDemo.ViewModels
{
@@ -56,7 +57,7 @@ namespace BindingDemo.ViewModels
public ObservableCollection Items { get; }
public ObservableCollection SelectedItems { get; }
- public ReactiveCommand ShuffleItems { get; }
+ public ReactiveCommand ShuffleItems { get; }
public string BooleanString
{
@@ -89,7 +90,7 @@ namespace BindingDemo.ViewModels
}
public IObservable CurrentTimeObservable { get; }
- public ReactiveCommand StringValueCommand { get; }
+ public ReactiveCommand