From 05e6c9cfd9ae784ba96e64252e3e52fe374e8381 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 17 May 2022 17:42:27 +0100 Subject: [PATCH 1/9] remove redundant api GetFrameSize. --- native/Avalonia.Native/src/OSX/WindowBaseImpl.h | 2 -- .../Avalonia.Native/src/OSX/WindowBaseImpl.mm | 17 +---------------- src/Avalonia.Native/avn.idl | 1 - 3 files changed, 1 insertion(+), 19 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.h b/native/Avalonia.Native/src/OSX/WindowBaseImpl.h index eff13bcb23..379bb227a8 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.h +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.h @@ -72,8 +72,6 @@ BEGIN_INTERFACE_MAP() 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; diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm index db5eb54e3f..f27aa01eb7 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm @@ -191,22 +191,7 @@ HRESULT WindowBaseImpl::GetClientSize(AvnSize *ret) { if (ret == nullptr) return E_POINTER; - auto frame = [View frame]; - ret->Width = frame.size.width; - ret->Height = frame.size.height; - - return S_OK; - } -} - -HRESULT WindowBaseImpl::GetFrameSize(AvnSize *ret) { - START_COM_CALL; - - @autoreleasepool { - if (ret == nullptr) - return E_POINTER; - - auto frame = [Window frame]; + auto frame = [View.frame]; ret->Width = frame.size.width; ret->Height = frame.size.height; diff --git a/src/Avalonia.Native/avn.idl b/src/Avalonia.Native/avn.idl index d6ef0f8918..a28bd06cd0 100644 --- a/src/Avalonia.Native/avn.idl +++ b/src/Avalonia.Native/avn.idl @@ -504,7 +504,6 @@ interface IAvnWindowBase : IUnknown HRESULT Close(); HRESULT Activate(); HRESULT GetClientSize(AvnSize*ret); - HRESULT GetFrameSize(AvnSize*ret); HRESULT GetScaling(double*ret); HRESULT SetMinMaxSize(AvnSize minSize, AvnSize maxSize); HRESULT Resize(double width, double height, AvnPlatformResizeReason reason); From b9bbd6ff0f27ef8c9071356e3cdcaec0bd54a925 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 17 May 2022 17:45:02 +0100 Subject: [PATCH 2/9] Revert "remove redundant api GetFrameSize." This reverts commit 05e6c9cfd9ae784ba96e64252e3e52fe374e8381. --- native/Avalonia.Native/src/OSX/WindowBaseImpl.h | 2 ++ .../Avalonia.Native/src/OSX/WindowBaseImpl.mm | 17 ++++++++++++++++- src/Avalonia.Native/avn.idl | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.h b/native/Avalonia.Native/src/OSX/WindowBaseImpl.h index 379bb227a8..eff13bcb23 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.h +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.h @@ -72,6 +72,8 @@ BEGIN_INTERFACE_MAP() 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; diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm index f27aa01eb7..db5eb54e3f 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm @@ -191,7 +191,22 @@ HRESULT WindowBaseImpl::GetClientSize(AvnSize *ret) { if (ret == nullptr) return E_POINTER; - auto frame = [View.frame]; + auto frame = [View frame]; + ret->Width = frame.size.width; + ret->Height = frame.size.height; + + return S_OK; + } +} + +HRESULT WindowBaseImpl::GetFrameSize(AvnSize *ret) { + START_COM_CALL; + + @autoreleasepool { + if (ret == nullptr) + return E_POINTER; + + auto frame = [Window frame]; ret->Width = frame.size.width; ret->Height = frame.size.height; diff --git a/src/Avalonia.Native/avn.idl b/src/Avalonia.Native/avn.idl index a28bd06cd0..d6ef0f8918 100644 --- a/src/Avalonia.Native/avn.idl +++ b/src/Avalonia.Native/avn.idl @@ -504,6 +504,7 @@ interface IAvnWindowBase : IUnknown HRESULT Close(); HRESULT Activate(); HRESULT GetClientSize(AvnSize*ret); + HRESULT GetFrameSize(AvnSize*ret); HRESULT GetScaling(double*ret); HRESULT SetMinMaxSize(AvnSize minSize, AvnSize maxSize); HRESULT Resize(double width, double height, AvnPlatformResizeReason reason); From 845be8ae0e21742e5d1c9001d5914e0908ebfb4c Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 17 May 2022 18:12:31 +0100 Subject: [PATCH 3/9] [OSX] until window is shown FrameSize is null. --- .../Avalonia.Native/src/OSX/WindowBaseImpl.mm | 17 +++++++++++------ src/Avalonia.Native/WindowImplBase.cs | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm index db5eb54e3f..0f934ce5a2 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm @@ -191,9 +191,8 @@ HRESULT WindowBaseImpl::GetClientSize(AvnSize *ret) { if (ret == nullptr) return E_POINTER; - auto frame = [View frame]; - ret->Width = frame.size.width; - ret->Height = frame.size.height; + ret->Width = lastSize.width; + ret->Height = lastSize.height; return S_OK; } @@ -206,9 +205,15 @@ HRESULT WindowBaseImpl::GetFrameSize(AvnSize *ret) { if (ret == nullptr) return E_POINTER; - auto frame = [Window frame]; - ret->Width = frame.size.width; - ret->Height = frame.size.height; + if(Window == nullptr){ + ret->Width = 0; + ret->Height = 0; + } + else { + auto frame = [Window frame]; + ret->Width = frame.size.width; + ret->Height = frame.size.height; + } return S_OK; } diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs index 735f11bcd5..36352f6397 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -117,7 +117,7 @@ namespace Avalonia.Native if (_native != null) { var s = _native.FrameSize; - return new Size(s.Width, s.Height); + return s.Width == 0 && s.Height == 0 ? null : new Size(s.Width, s.Height); } return default; From 3e8ce3deb1478a4a110b2e5ee4dad716368a08a4 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 17 May 2022 18:23:33 +0100 Subject: [PATCH 4/9] [OSX] GetFrameSize - explicitly detect when native side didnt touch result object to signal null. --- native/Avalonia.Native/src/OSX/WindowBaseImpl.mm | 6 +----- src/Avalonia.Native/WindowImplBase.cs | 8 ++++++-- src/Avalonia.Native/avn.idl | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm index 0f934ce5a2..b8dacbc132 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm @@ -205,11 +205,7 @@ HRESULT WindowBaseImpl::GetFrameSize(AvnSize *ret) { if (ret == nullptr) return E_POINTER; - if(Window == nullptr){ - ret->Width = 0; - ret->Height = 0; - } - else { + if(Window != nullptr){ auto frame = [Window frame]; ret->Width = frame.size.width; ret->Height = frame.size.height; diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs index 36352f6397..94a3a5ed9b 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -116,8 +116,12 @@ namespace Avalonia.Native { if (_native != null) { - var s = _native.FrameSize; - return s.Width == 0 && s.Height == 0 ? null : new Size(s.Width, s.Height); + unsafe + { + var s = new AvnSize { Width = -1, Height = -1 }; + _native.GetFrameSize(&s); + return s.Width < 0 && s.Height < 0 ? null : new Size(s.Width, s.Height); + } } return default; diff --git a/src/Avalonia.Native/avn.idl b/src/Avalonia.Native/avn.idl index d6ef0f8918..a1c73e1f03 100644 --- a/src/Avalonia.Native/avn.idl +++ b/src/Avalonia.Native/avn.idl @@ -504,7 +504,7 @@ interface IAvnWindowBase : IUnknown HRESULT Close(); HRESULT Activate(); HRESULT GetClientSize(AvnSize*ret); - HRESULT GetFrameSize(AvnSize*ret); + HRESULT GetFrameSize(AvnSize*result); HRESULT GetScaling(double*ret); HRESULT SetMinMaxSize(AvnSize minSize, AvnSize maxSize); HRESULT Resize(double width, double height, AvnPlatformResizeReason reason); From 8c47595ba3ccfa9bd48c291e28383b557266de76 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 17 May 2022 18:36:40 +0100 Subject: [PATCH 5/9] ensure windows open at center by default. --- native/Avalonia.Native/src/OSX/WindowBaseImpl.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm index b8dacbc132..223f169e45 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm @@ -92,7 +92,6 @@ HRESULT WindowBaseImpl::Show(bool activate, bool isDialog) { CreateNSWindow(isDialog); InitialiseNSWindow(); - SetPosition(lastPositionSet); UpdateStyle(); [Window setTitle:_lastTitle]; @@ -561,6 +560,8 @@ void WindowBaseImpl::InitialiseNSWindow() { [Window setOpaque:false]; + [Window center]; + if (lastMenu != nullptr) { [GetWindowProtocol() applyMenu:lastMenu]; From 7e95fd8c4f477ac571e5f54c6ad6087dfda0f226 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 17 May 2022 18:43:03 +0100 Subject: [PATCH 6/9] [OSX] NSWindow open at position specified by user. --- native/Avalonia.Native/src/OSX/WindowBaseImpl.mm | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm index 223f169e45..9001208ce1 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm @@ -30,8 +30,8 @@ WindowBaseImpl::WindowBaseImpl(IAvnWindowBaseEvents *events, IAvnGlContext *gl) View = [[AvnView alloc] initWithParent:this]; StandardContainer = [[AutoFitContentView new] initWithContent:View]; - lastPositionSet.X = 100; - lastPositionSet.Y = 100; + lastPositionSet.X = -1; + lastPositionSet.Y = -1; lastSize = NSSize { 100, 100 }; lastMaxSize = NSSize { CGFLOAT_MAX, CGFLOAT_MAX}; lastMinSize = NSSize { 0, 0 }; @@ -92,6 +92,11 @@ HRESULT WindowBaseImpl::Show(bool activate, bool isDialog) { CreateNSWindow(isDialog); InitialiseNSWindow(); + if(lastPositionSet.X >= 0 && lastPositionSet.Y >= 0) + { + SetPosition(lastPositionSet); + } + UpdateStyle(); [Window setTitle:_lastTitle]; @@ -370,7 +375,10 @@ HRESULT WindowBaseImpl::SetPosition(AvnPoint point) { @autoreleasepool { lastPositionSet = point; - [Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(point))]; + + if(Window != nullptr) { + [Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(point))]; + } return S_OK; } From 168b91fd52db2e157c2947205087b134fb67a5ce Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 18 May 2022 10:53:29 +0100 Subject: [PATCH 7/9] [OSX] ensure flyouts, menus and popups can be overlayed on fullscreen windows --- native/Avalonia.Native/src/OSX/AvnWindow.mm | 16 ++++++++++++---- native/Avalonia.Native/src/OSX/PopupImpl.mm | 6 ++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/AvnWindow.mm b/native/Avalonia.Native/src/OSX/AvnWindow.mm index 6ff19ead68..cba5fcfb64 100644 --- a/native/Avalonia.Native/src/OSX/AvnWindow.mm +++ b/native/Avalonia.Native/src/OSX/AvnWindow.mm @@ -174,6 +174,11 @@ [self setBackgroundColor: [NSColor clearColor]]; _isExtended = false; + +#ifdef IS_NSPANEL + [self setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces|NSWindowCollectionBehaviorFullScreenAuxiliary]; +#endif + return self; } @@ -212,11 +217,14 @@ // 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 = static_cast>(uch); - if(ch == nil) + if (![uch conformsToProtocol:@protocol(AvnWindowProtocol)]) + { continue; - if (ch.isDialog) - return false; + } + + id ch = (id ) uch; + + return !ch.isDialog; } return true; diff --git a/native/Avalonia.Native/src/OSX/PopupImpl.mm b/native/Avalonia.Native/src/OSX/PopupImpl.mm index 64a8780158..cf3ecefb3c 100644 --- a/native/Avalonia.Native/src/OSX/PopupImpl.mm +++ b/native/Avalonia.Native/src/OSX/PopupImpl.mm @@ -50,11 +50,17 @@ protected: return S_OK; } } + public: virtual bool ShouldTakeFocusOnShow() override { return false; } + + virtual HRESULT Show(bool activate, bool isDialog) override + { + return WindowBaseImpl::Show(activate, true); + } }; From 3faebf205a445932a17ccf8782f1fce772b40c37 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 18 May 2022 11:47:24 +0100 Subject: [PATCH 8/9] [OSX] ensure window state is obeyed. --- native/Avalonia.Native/src/OSX/AvnWindow.mm | 7 +++++++ native/Avalonia.Native/src/OSX/WindowBaseImpl.h | 2 ++ native/Avalonia.Native/src/OSX/WindowBaseImpl.mm | 6 +++++- native/Avalonia.Native/src/OSX/WindowImpl.mm | 6 +++--- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/AvnWindow.mm b/native/Avalonia.Native/src/OSX/AvnWindow.mm index cba5fcfb64..54bfe6e38a 100644 --- a/native/Avalonia.Native/src/OSX/AvnWindow.mm +++ b/native/Avalonia.Native/src/OSX/AvnWindow.mm @@ -199,6 +199,8 @@ [self backingScaleFactor]; } + + - (void)windowWillClose:(NSNotification *)notification { _closed = true; @@ -380,6 +382,11 @@ if(cparent != nullptr) { + if(!cparent->IsShown()) + { + return; + } + if(cparent->WindowState() == Maximized) { cparent->SetWindowState(Normal); diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.h b/native/Avalonia.Native/src/OSX/WindowBaseImpl.h index eff13bcb23..0e482f9f30 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.h +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.h @@ -60,6 +60,8 @@ BEGIN_INTERFACE_MAP() virtual HRESULT Show(bool activate, bool isDialog) override; + virtual bool IsShown (); + virtual bool ShouldTakeFocusOnShow(); virtual HRESULT Hide() override; diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm index 9001208ce1..982867b854 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm @@ -116,6 +116,11 @@ HRESULT WindowBaseImpl::Show(bool activate, bool isDialog) { } } +bool WindowBaseImpl::IsShown () +{ + return _shown; +} + bool WindowBaseImpl::ShouldTakeFocusOnShow() { return true; } @@ -567,7 +572,6 @@ void WindowBaseImpl::InitialiseNSWindow() { [Window setContentMaxSize:lastMaxSize]; [Window setOpaque:false]; - [Window center]; if (lastMenu != nullptr) { diff --git a/native/Avalonia.Native/src/OSX/WindowImpl.mm b/native/Avalonia.Native/src/OSX/WindowImpl.mm index 7ab2b2b5fc..5b15b4cdfc 100644 --- a/native/Avalonia.Native/src/OSX/WindowImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowImpl.mm @@ -430,6 +430,9 @@ HRESULT WindowImpl::SetWindowState(AvnWindowState state) { START_COM_CALL; @autoreleasepool { + auto currentState = _actualWindowState; + _lastWindowState = state; + if (Window == nullptr) { return S_OK; } @@ -440,9 +443,6 @@ HRESULT WindowImpl::SetWindowState(AvnWindowState state) { _inSetWindowState = true; - auto currentState = _actualWindowState; - _lastWindowState = state; - if (currentState == Normal) { _preZoomSize = [Window frame]; } From 3948f9878770283157616884340c9f63e5af67bb Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 18 May 2022 11:53:03 +0100 Subject: [PATCH 9/9] dont static cast to protocol --- native/Avalonia.Native/src/OSX/AutoFitContentView.mm | 2 +- native/Avalonia.Native/src/OSX/WindowBaseImpl.mm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/AutoFitContentView.mm b/native/Avalonia.Native/src/OSX/AutoFitContentView.mm index 314c579b76..0fa4540726 100644 --- a/native/Avalonia.Native/src/OSX/AutoFitContentView.mm +++ b/native/Avalonia.Native/src/OSX/AutoFitContentView.mm @@ -85,7 +85,7 @@ _settingSize = true; [super setFrameSize:newSize]; - auto window = static_cast>([self window]); + auto window = (id ) [self window]; // TODO get actual titlebar size diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm index 982867b854..0ab120038b 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm @@ -590,7 +590,7 @@ id WindowBaseImpl::GetWindowProtocol() { return nullptr; } - return static_cast>(Window); + return (id ) Window; } extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events, IAvnGlContext* gl)