Browse Source

Merge branch 'master' into feature/nested-styles

pull/8024/head
Max Katz 4 years ago
committed by GitHub
parent
commit
0cab8ed885
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 34
      native/Avalonia.Native/src/OSX/AvnWindow.mm
  2. 21
      native/Avalonia.Native/src/OSX/PopupImpl.mm
  3. 40
      native/Avalonia.Native/src/OSX/WindowBaseImpl.h
  4. 25
      native/Avalonia.Native/src/OSX/WindowBaseImpl.mm
  5. 5
      native/Avalonia.Native/src/OSX/WindowImpl.h
  6. 30
      native/Avalonia.Native/src/OSX/WindowImpl.mm
  7. 4
      native/Avalonia.Native/src/OSX/WindowProtocol.h
  8. 46
      src/Avalonia.Base/Data/Core/ExpressionNode.cs
  9. 18
      src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs

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

@ -31,6 +31,7 @@
ComPtr<WindowBaseImpl> _parent;
bool _closed;
bool _isEnabled;
bool _canBecomeKeyWindow;
bool _isExtended;
AvnMenu* _menu;
}
@ -216,29 +217,38 @@
-(BOOL)canBecomeKeyWindow
{
// 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])
if(_canBecomeKeyWindow)
{
if (![uch conformsToProtocol:@protocol(AvnWindowProtocol)])
// 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])
{
continue;
}
if (![uch conformsToProtocol:@protocol(AvnWindowProtocol)])
{
continue;
}
id <AvnWindowProtocol> ch = (id <AvnWindowProtocol>) uch;
id <AvnWindowProtocol> ch = (id <AvnWindowProtocol>) uch;
return !ch.isDialog;
}
if(ch.isDialog)
return false;
}
return true;
return true;
}
return false;
}
#ifndef IS_NSPANEL
-(BOOL)canBecomeMainWindow
{
#ifdef IS_NSPANEL
return false;
#else
return true;
}
#endif
-(void)setCanBecomeKeyWindow:(bool)value
{
_canBecomeKeyWindow = value;
}
-(bool)shouldTryToHandleEvents

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

@ -26,29 +26,16 @@ private:
PopupImpl(IAvnWindowEvents* events, IAvnGlContext* gl) : WindowBaseImpl(events, gl)
{
WindowEvents = events;
[Window setLevel:NSPopUpMenuWindowLevel];
}
protected:
virtual NSWindowStyleMask GetStyle() override
{
return NSWindowStyleMaskBorderless;
}
virtual HRESULT Resize(double x, double y, AvnPlatformResizeReason reason) override
virtual void OnInitialiseNSWindow () override
{
START_COM_CALL;
@autoreleasepool
{
if (Window != nullptr)
{
[Window setContentSize:NSSize{x, y}];
[Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(lastPositionSet))];
}
return S_OK;
}
[Window setLevel:NSPopUpMenuWindowLevel];
}
public:
@ -71,4 +58,4 @@ extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events, IAvnGlContext* gl)
IAvnPopup* ptr = dynamic_cast<IAvnPopup*>(new PopupImpl(events, gl));
return ptr;
}
}
}

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

@ -16,8 +16,6 @@
class WindowBaseImpl : public virtual ComObject,
public virtual IAvnWindowBase,
public INSWindowHolder {
private:
NSCursor *cursor;
public:
FORWARD_IUNKNOWN()
@ -28,22 +26,6 @@ BEGIN_INTERFACE_MAP()
virtual ~WindowBaseImpl();
AutoFitContentView *StandardContainer;
AvnView *View;
NSWindow * Window;
ComPtr<IAvnWindowBaseEvents> BaseEvents;
ComPtr<IAvnGlContext> _glContext;
NSObject <IRenderTarget> *renderTarget;
AvnPoint lastPositionSet;
NSSize lastSize;
NSSize lastMinSize;
NSSize lastMaxSize;
AvnMenu* lastMenu;
NSString *_lastTitle;
bool _shown;
bool _inResize;
WindowBaseImpl(IAvnWindowBaseEvents *events, IAvnGlContext *gl);
virtual HRESULT ObtainNSWindowHandle(void **ret) override;
@ -122,11 +104,33 @@ protected:
virtual NSWindowStyleMask GetStyle();
void UpdateStyle();
virtual void OnInitialiseNSWindow ();
private:
void CreateNSWindow (bool isDialog);
void CleanNSWindow ();
void InitialiseNSWindow ();
NSCursor *cursor;
ComPtr<IAvnGlContext> _glContext;
bool hasPosition;
NSSize lastSize;
NSSize lastMinSize;
NSSize lastMaxSize;
AvnMenu* lastMenu;
bool _inResize;
protected:
AvnPoint lastPositionSet;
AutoFitContentView *StandardContainer;
bool _shown;
public:
NSObject <IRenderTarget> *renderTarget;
NSWindow * Window;
ComPtr<IAvnWindowBaseEvents> BaseEvents;
AvnView *View;
};
#endif //AVALONIA_NATIVE_OSX_WINDOWBASEIMPL_H

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

@ -30,12 +30,11 @@ WindowBaseImpl::WindowBaseImpl(IAvnWindowBaseEvents *events, IAvnGlContext *gl)
View = [[AvnView alloc] initWithParent:this];
StandardContainer = [[AutoFitContentView new] initWithContent:View];
lastPositionSet.X = -1;
lastPositionSet.Y = -1;
lastPositionSet = { 0, 0 };
hasPosition = false;
lastSize = NSSize { 100, 100 };
lastMaxSize = NSSize { CGFLOAT_MAX, CGFLOAT_MAX};
lastMinSize = NSSize { 0, 0 };
_lastTitle = @"";
Window = nullptr;
lastMenu = nullptr;
@ -92,15 +91,16 @@ HRESULT WindowBaseImpl::Show(bool activate, bool isDialog) {
CreateNSWindow(isDialog);
InitialiseNSWindow();
if(lastPositionSet.X >= 0 && lastPositionSet.Y >= 0)
if(hasPosition)
{
SetPosition(lastPositionSet);
} else
{
[Window center];
}
UpdateStyle();
[Window setTitle:_lastTitle];
if (ShouldTakeFocusOnShow() && activate) {
[Window orderFront:Window];
[Window makeKeyAndOrderFront:Window];
@ -288,12 +288,12 @@ HRESULT WindowBaseImpl::Resize(double x, double y, AvnPlatformResizeReason reaso
}
@try {
lastSize = NSSize {x, y};
if (!_shown) {
BaseEvents->Resized(AvnSize{x, y}, reason);
}
lastSize = NSSize {x, y};
if(Window != nullptr) {
[Window setContentSize:lastSize];
}
@ -385,6 +385,7 @@ HRESULT WindowBaseImpl::SetPosition(AvnPoint point) {
@autoreleasepool {
lastPositionSet = point;
hasPosition = true;
if(Window != nullptr) {
[Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(point))];
@ -566,6 +567,11 @@ void WindowBaseImpl::CreateNSWindow(bool isDialog) {
}
}
void WindowBaseImpl::OnInitialiseNSWindow()
{
}
void WindowBaseImpl::InitialiseNSWindow() {
if(Window != nullptr) {
[Window setContentView:StandardContainer];
@ -577,7 +583,6 @@ void WindowBaseImpl::InitialiseNSWindow() {
[Window setContentMaxSize:lastMaxSize];
[Window setOpaque:false];
[Window center];
if (lastMenu != nullptr) {
[GetWindowProtocol() applyMenu:lastMenu];
@ -586,6 +591,8 @@ void WindowBaseImpl::InitialiseNSWindow() {
[GetWindowProtocol() showWindowMenuWithAppMenu];
}
}
OnInitialiseNSWindow();
}
}

5
native/Avalonia.Native/src/OSX/WindowImpl.h

@ -88,9 +88,14 @@ BEGIN_INTERFACE_MAP()
virtual HRESULT SetWindowState (AvnWindowState state) override;
virtual bool IsDialog() override;
virtual void OnInitialiseNSWindow() override;
protected:
virtual NSWindowStyleMask GetStyle() override;
private:
NSString *_lastTitle;
};
#endif //AVALONIA_NATIVE_OSX_WINDOWIMPL_H

30
native/Avalonia.Native/src/OSX/WindowImpl.mm

@ -19,10 +19,8 @@ WindowImpl::WindowImpl(IAvnWindowEvents *events, IAvnGlContext *gl) : WindowBase
_inSetWindowState = false;
_lastWindowState = Normal;
_actualWindowState = Normal;
_lastTitle = @"";
WindowEvents = events;
[Window disableCursorRects];
[Window setTabbingMode:NSWindowTabbingModeDisallowed];
[Window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
}
void WindowImpl::HideOrShowTrafficLights() {
@ -50,25 +48,29 @@ void WindowImpl::HideOrShowTrafficLights() {
}
}
void WindowImpl::OnInitialiseNSWindow(){
[GetWindowProtocol() setCanBecomeKeyWindow:true];
[Window disableCursorRects];
[Window setTabbingMode:NSWindowTabbingModeDisallowed];
[Window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
[Window setTitle:_lastTitle];
if(_isClientAreaExtended)
{
[GetWindowProtocol() setIsExtended:true];
SetExtendClientArea(true);
}
}
HRESULT WindowImpl::Show(bool activate, bool isDialog) {
START_COM_CALL;
@autoreleasepool {
_isDialog = isDialog;
bool created = Window == nullptr;
WindowBaseImpl::Show(activate, isDialog);
if(created)
{
if(_isClientAreaExtended)
{
[GetWindowProtocol() setIsExtended:true];
SetExtendClientArea(true);
}
}
HideOrShowTrafficLights();
return SetWindowState(_lastWindowState);

4
native/Avalonia.Native/src/OSX/WindowProtocol.h

@ -22,4 +22,6 @@
-(void) setIsExtended:(bool)value;
-(void) disconnectParent;
-(bool) isDialog;
@end
-(void) setCanBecomeKeyWindow:(bool)value;
@end

46
src/Avalonia.Base/Data/Core/ExpressionNode.cs

@ -98,36 +98,36 @@ namespace Avalonia.Data.Core
private void ValueChanged(object? value, bool notify)
{
if (_subscriber is null)
return;
var notification = value as BindingNotification;
if (notification == null)
if (_subscriber is { } subscriber)
{
LastValue = value != null ? new WeakReference<object?>(value) : NullReference;
var notification = value as BindingNotification;
var next = Next;
if (Next != null)
if (notification == null)
{
Next.Target = LastValue;
LastValue = value != null ? new WeakReference<object?>(value) : NullReference;
if (next != null)
{
next.Target = LastValue;
}
else if (notify)
{
subscriber(value);
}
}
else if (notify)
else
{
_subscriber(value);
}
}
else
{
LastValue = notification.Value != null ? new WeakReference<object?>(notification.Value) : NullReference;
LastValue = notification.Value != null ? new WeakReference<object?>(notification.Value) : NullReference;
if (Next != null)
{
Next.Target = LastValue;
}
if (next != null)
{
next.Target = LastValue;
}
if (Next == null || notification.Error != null)
{
_subscriber(value);
if (next == null || notification.Error != null)
{
subscriber(value);
}
}
}
}

18
src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs

@ -56,6 +56,7 @@ namespace Avalonia.Controls.Platform
Menu.AddHandler(Avalonia.Controls.Menu.MenuOpenedEvent, this.MenuOpened);
Menu.AddHandler(MenuItem.PointerEnterItemEvent, PointerEnter);
Menu.AddHandler(MenuItem.PointerLeaveItemEvent, PointerLeave);
Menu.AddHandler(InputElement.PointerMovedEvent, PointerMoved);
_root = Menu.VisualRoot;
@ -91,6 +92,7 @@ namespace Avalonia.Controls.Platform
Menu.RemoveHandler(Avalonia.Controls.Menu.MenuOpenedEvent, this.MenuOpened);
Menu.RemoveHandler(MenuItem.PointerEnterItemEvent, PointerEnter);
Menu.RemoveHandler(MenuItem.PointerLeaveItemEvent, PointerLeave);
Menu.RemoveHandler(InputElement.PointerMovedEvent, PointerMoved);
if (_root is InputElement inputRoot)
{
@ -340,6 +342,22 @@ namespace Avalonia.Controls.Platform
}
}
protected internal virtual void PointerMoved(object? sender, PointerEventArgs e)
{
// HACK: #8179 needs to be addressed to correctly implement it in the PointerPressed method.
var item = GetMenuItem(e.Source as IControl) as MenuItem;
if (item?.TransformedBounds == null)
{
return;
}
var point = e.GetCurrentPoint(null);
if (point.Properties.IsLeftButtonPressed && item.TransformedBounds.Value.Contains(point.Position) == false)
{
e.Pointer.Capture(null);
}
}
protected internal virtual void PointerLeave(object? sender, PointerEventArgs e)
{
var item = GetMenuItem(e.Source as IControl);

Loading…
Cancel
Save