diff --git a/build/SharedVersion.props b/build/SharedVersion.props index 44d5c239ef..897e70ff81 100644 --- a/build/SharedVersion.props +++ b/build/SharedVersion.props @@ -2,7 +2,7 @@ xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> Avalonia - 0.8.999 + 0.9.999 Copyright 2019 © The AvaloniaUI Project https://avaloniaui.net https://github.com/AvaloniaUI/Avalonia/ diff --git a/native/Avalonia.Native/inc/avalonia-native.h b/native/Avalonia.Native/inc/avalonia-native.h index f1c7664c3e..06d6bdf311 100644 --- a/native/Avalonia.Native/inc/avalonia-native.h +++ b/native/Avalonia.Native/inc/avalonia-native.h @@ -212,6 +212,10 @@ AVNCOM(IAvnWindowBase, 02) : IUnknown virtual HRESULT GetSoftwareFramebuffer(AvnFramebuffer*ret) = 0; virtual HRESULT SetMainMenu(IAvnAppMenu* menu) = 0; virtual HRESULT ObtainMainMenu(IAvnAppMenu** retOut) = 0; + virtual HRESULT ObtainNSWindowHandle(void** retOut) = 0; + virtual HRESULT ObtainNSWindowHandleRetained(void** retOut) = 0; + virtual HRESULT ObtainNSViewHandle(void** retOut) = 0; + virtual HRESULT ObtainNSViewHandleRetained(void** retOut) = 0; virtual bool TryLock() = 0; virtual void Unlock() = 0; }; diff --git a/native/Avalonia.Native/src/OSX/app.mm b/native/Avalonia.Native/src/OSX/app.mm index 81855995b7..5c50aad4cc 100644 --- a/native/Avalonia.Native/src/OSX/app.mm +++ b/native/Avalonia.Native/src/OSX/app.mm @@ -1,16 +1,25 @@ #include "common.h" @interface AvnAppDelegate : NSObject @end + extern NSApplicationActivationPolicy AvnDesiredActivationPolicy = NSApplicationActivationPolicyRegular; @implementation AvnAppDelegate - (void)applicationWillFinishLaunching:(NSNotification *)notification { - [[NSApplication sharedApplication] setActivationPolicy: AvnDesiredActivationPolicy]; + if([[NSApplication sharedApplication] activationPolicy] != AvnDesiredActivationPolicy) + { + for (NSRunningApplication * app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"]) { + [app activateWithOptions:NSApplicationActivateIgnoringOtherApps]; + break; + } + + [[NSApplication sharedApplication] setActivationPolicy: AvnDesiredActivationPolicy]; + } } - (void)applicationDidFinishLaunching:(NSNotification *)notification { - [NSApp activateIgnoringOtherApps:true]; + [[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps]; } @end @@ -20,5 +29,4 @@ extern void InitializeAvnApp() NSApplication* app = [NSApplication sharedApplication]; id delegate = [AvnAppDelegate new]; [app setDelegate:delegate]; - } diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm index 0e85332555..021f6e5603 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -83,6 +83,54 @@ public: [Window setContentView: View]; } + virtual HRESULT ObtainNSWindowHandle(void** ret) override + { + if (ret == nullptr) + { + return E_POINTER; + } + + *ret = (__bridge void*)Window; + + return S_OK; + } + + virtual HRESULT ObtainNSWindowHandleRetained(void** ret) override + { + if (ret == nullptr) + { + return E_POINTER; + } + + *ret = (__bridge_retained void*)Window; + + return S_OK; + } + + virtual HRESULT ObtainNSViewHandle(void** ret) override + { + if (ret == nullptr) + { + return E_POINTER; + } + + *ret = (__bridge void*)View; + + return S_OK; + } + + virtual HRESULT ObtainNSViewHandleRetained(void** ret) override + { + if (ret == nullptr) + { + return E_POINTER; + } + + *ret = (__bridge_retained void*)View; + + return S_OK; + } + virtual AvnWindow* GetNSWindow() override { return Window; diff --git a/src/Avalonia.Base/Platform/IMacOSTopLevelPlatformHandle.cs b/src/Avalonia.Base/Platform/IMacOSTopLevelPlatformHandle.cs new file mode 100644 index 0000000000..837ea1abcd --- /dev/null +++ b/src/Avalonia.Base/Platform/IMacOSTopLevelPlatformHandle.cs @@ -0,0 +1,15 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Platform +{ + public interface IMacOSTopLevelPlatformHandle + { + IntPtr NSView { get; } + IntPtr GetNSViewRetained(); + IntPtr NSWindow { get; } + IntPtr GetNSWindowRetained(); + } +} diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index 1816a6c81d..f66a248aaf 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -336,7 +336,6 @@ namespace Avalonia.Controls if (close) { PlatformImpl?.Dispose(); - HandleClosed(); } } } diff --git a/src/Avalonia.Input/InputElement.cs b/src/Avalonia.Input/InputElement.cs index 535b930f8b..1e2a621bd1 100644 --- a/src/Avalonia.Input/InputElement.cs +++ b/src/Avalonia.Input/InputElement.cs @@ -342,7 +342,7 @@ namespace Avalonia.Input } /// - /// Gets or sets a value indicating whether the control is focused. + /// Gets a value indicating whether the control is focused. /// public bool IsFocused { @@ -360,7 +360,7 @@ namespace Avalonia.Input } /// - /// Gets or sets a value indicating whether the pointer is currently over the control. + /// Gets a value indicating whether the pointer is currently over the control. /// public bool IsPointerOver { diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs index 8b397403ca..e72fefe3ce 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -16,6 +16,34 @@ using Avalonia.Threading; namespace Avalonia.Native { + public class MacOSTopLevelWindowHandle : IPlatformHandle, IMacOSTopLevelPlatformHandle + { + IAvnWindowBase _native; + + public MacOSTopLevelWindowHandle(IAvnWindowBase native) + { + _native = native; + } + + public IntPtr Handle => NSWindow; + + public string HandleDescriptor => "NSWindow"; + + public IntPtr NSView => _native.ObtainNSViewHandle(); + + public IntPtr NSWindow => _native.ObtainNSWindowHandle(); + + public IntPtr GetNSViewRetained() + { + return _native.ObtainNSViewHandleRetained(); + } + + public IntPtr GetNSWindowRetained() + { + return _native.ObtainNSWindowHandleRetained(); + } + } + public abstract class WindowBaseImpl : IWindowBaseImpl, IFramebufferPlatformSurface { @@ -45,6 +73,9 @@ namespace Avalonia.Native protected void Init(IAvnWindowBase window, IAvnScreens screens) { _native = window; + + Handle = new MacOSTopLevelWindowHandle(window); + _glSurface = new GlPlatformSurface(window); Screen = new ScreenImpl(screens); _savedLogicalSize = ClientSize; @@ -349,6 +380,6 @@ namespace Avalonia.Native } - public IPlatformHandle Handle => new PlatformHandle(IntPtr.Zero, "NOT SUPPORTED"); + public IPlatformHandle Handle { get; private set; } } } diff --git a/tests/Avalonia.Controls.UnitTests/WindowTests.cs b/tests/Avalonia.Controls.UnitTests/WindowTests.cs index d87014f646..0508edd92f 100644 --- a/tests/Avalonia.Controls.UnitTests/WindowTests.cs +++ b/tests/Avalonia.Controls.UnitTests/WindowTests.cs @@ -228,8 +228,7 @@ namespace Avalonia.Controls.UnitTests { using (UnitTestApplication.Start(TestServices.StyledWindow)) { - var windowImpl = Mock.Of(x => x.Scaling == 1); - var target = new Window(windowImpl); + var target = new Window(); target.Show(); target.Close(); diff --git a/tests/Avalonia.UnitTests/MockWindowingPlatform.cs b/tests/Avalonia.UnitTests/MockWindowingPlatform.cs index c33ec72141..a6701ef655 100644 --- a/tests/Avalonia.UnitTests/MockWindowingPlatform.cs +++ b/tests/Avalonia.UnitTests/MockWindowingPlatform.cs @@ -28,6 +28,10 @@ namespace Avalonia.UnitTests return CreatePopupMock().Object; }); + mock.Setup(x => x.Dispose()).Callback(() => + { + mock.Object.Closed?.Invoke(); + }); PixelPoint pos = default; mock.SetupGet(x => x.Position).Returns(() => pos); mock.Setup(x => x.Move(It.IsAny())).Callback(new Action(np => pos = np));