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)
{
WindowEvents = events;
[Window setLevel:NSPopUpMenuWindowLevel];
UpdateWindowLevel();
}
protected:
virtual NSWindowLevel GetBaseWindowLevel() override
{
return NSPopUpMenuWindowLevel;
}
virtual NSWindowStyleMask CalculateStyleMask() override
{
return NSWindowStyleMaskBorderless;

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

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

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

@ -18,6 +18,7 @@
#include "WindowImpl.h"
#include "AvnTextInputMethod.h"
#include "AvnView.h"
#include <algorithm>
@class AutoFitContentView;
@ -206,12 +207,41 @@ HRESULT WindowBaseImpl::SetTopMost(bool value) {
START_COM_CALL;
@autoreleasepool {
[Window setLevel:value ? NSFloatingWindowLevel : NSNormalWindowLevel];
_isTopmost = value;
UpdateWindowLevel();
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() {
START_COM_CALL;
@ -527,6 +557,8 @@ HRESULT WindowBaseImpl::SetParent(IAvnWindowBase *parent) {
UpdateAppearance();
}
UpdateWindowLevel();
return S_OK;
}
}

Loading…
Cancel
Save