Browse Source

MacOS: Make sure macOS child window layer is not lower than parent window.

pull/22221/head
Max Katz 3 weeks ago
parent
commit
db65062a7e
  1. 7
      native/Avalonia.Native/src/OSX/PopupImpl.mm
  2. 7
      native/Avalonia.Native/src/OSX/WindowBaseImpl.h
  3. 34
      native/Avalonia.Native/src/OSX/WindowBaseImpl.mm

7
native/Avalonia.Native/src/OSX/PopupImpl.mm

@ -25,9 +25,14 @@ private:
PopupImpl(IAvnWindowEvents* events) : TopLevelImpl(events), WindowBaseImpl(events) PopupImpl(IAvnWindowEvents* events) : TopLevelImpl(events), WindowBaseImpl(events)
{ {
WindowEvents = events; WindowEvents = events;
[Window setLevel:NSPopUpMenuWindowLevel]; UpdateWindowLevel();
} }
protected: protected:
virtual NSWindowLevel GetBaseWindowLevel() override
{
return NSPopUpMenuWindowLevel;
}
virtual NSWindowStyleMask CalculateStyleMask() override virtual NSWindowStyleMask CalculateStyleMask() override
{ {
return NSWindowStyleMaskBorderless; return NSWindowStyleMaskBorderless;

7
native/Avalonia.Native/src/OSX/WindowBaseImpl.h

@ -80,8 +80,12 @@ public:
virtual bool CanZoom() { return false; } virtual bool CanZoom() { return false; }
virtual HRESULT SetParent(IAvnWindowBase* parent) override; virtual HRESULT SetParent(IAvnWindowBase* parent) override;
void UpdateWindowLevel();
protected: protected:
virtual NSWindowLevel GetBaseWindowLevel();
virtual NSWindowStyleMask CalculateStyleMask() = 0; virtual NSWindowStyleMask CalculateStyleMask() = 0;
virtual void UpdateAppearance() override; virtual void UpdateAppearance() override;
virtual void SetClientSize(NSSize size) override; virtual void SetClientSize(NSSize size) override;
@ -101,6 +105,7 @@ protected:
AutoFitContentView *StandardContainer; AutoFitContentView *StandardContainer;
AvnPoint lastPositionSet; AvnPoint lastPositionSet;
bool _shown; bool _shown;
bool _isTopmost = false;
std::list<ComObjectWeakPtr<WindowBaseImpl>> _children; std::list<ComObjectWeakPtr<WindowBaseImpl>> _children;
public: public:

34
native/Avalonia.Native/src/OSX/WindowBaseImpl.mm

@ -18,6 +18,7 @@
#include "WindowImpl.h" #include "WindowImpl.h"
#include "AvnTextInputMethod.h" #include "AvnTextInputMethod.h"
#include "AvnView.h" #include "AvnView.h"
#include <algorithm>
@class AutoFitContentView; @class AutoFitContentView;
@ -206,12 +207,41 @@ HRESULT WindowBaseImpl::SetTopMost(bool value) {
START_COM_CALL; START_COM_CALL;
@autoreleasepool { @autoreleasepool {
[Window setLevel:value ? NSFloatingWindowLevel : NSNormalWindowLevel]; _isTopmost = value;
UpdateWindowLevel();
return S_OK; return S_OK;
} }
} }
NSWindowLevel WindowBaseImpl::GetBaseWindowLevel() {
return _isTopmost ? NSFloatingWindowLevel : NSNormalWindowLevel;
}
void WindowBaseImpl::UpdateWindowLevel() {
if (Window == nullptr)
return;
auto level = GetBaseWindowLevel();
// An owned window must be able to come to the front of its owner.
// TODO: It shouldn't be necessary if we used `addChildWindow` API.
auto parent = Parent.tryGet();
if (parent != nullptr && parent->Window != nullptr)
level = std::max(level, [parent->Window level]);
[Window setLevel:level];
for (auto iterator = _children.begin(); iterator != _children.end(); iterator++) {
auto child = (*iterator).tryGet();
if (child != nullptr)
child->UpdateWindowLevel();
}
}
HRESULT WindowBaseImpl::Close() { HRESULT WindowBaseImpl::Close() {
START_COM_CALL; START_COM_CALL;
@ -527,6 +557,8 @@ HRESULT WindowBaseImpl::SetParent(IAvnWindowBase *parent) {
UpdateAppearance(); UpdateAppearance();
} }
UpdateWindowLevel();
return S_OK; return S_OK;
} }
} }

Loading…
Cancel
Save