Browse Source

[OSX] Fixed NativeMenu memory leak

pull/9451/head
Nikita Tsukanov 3 years ago
parent
commit
c7d76e49e4
  1. 13
      native/Avalonia.Native/src/OSX/menu.h
  2. 26
      native/Avalonia.Native/src/OSX/menu.mm
  3. 2
      src/Avalonia.MicroCom/CallbackBase.cs
  4. 13
      src/Avalonia.Native/IAvnMenu.cs

13
native/Avalonia.Native/src/OSX/menu.h

@ -59,11 +59,20 @@ public:
void RaiseOnClicked();
};
class AvnAppMenu;
@interface AvnMenuDelegate : NSObject<NSMenuDelegate>
- (id) initWithParent: (AvnAppMenu*) parent;
- (void) parentDestroyed;
@end
class AvnAppMenu : public ComSingleObject<IAvnMenu, &IID_IAvnMenu>
{
private:
AvnMenu* _native;
ComPtr<IAvnMenuEvents> _baseEvents;
AvnMenuDelegate* _delegate;
public:
FORWARD_IUNKNOWN()
@ -83,12 +92,10 @@ public:
virtual HRESULT SetTitle (char* utf8String) override;
virtual HRESULT Clear () override;
virtual ~AvnAppMenu() override;
};
@interface AvnMenuDelegate : NSObject<NSMenuDelegate>
- (id) initWithParent: (AvnAppMenu*) parent;
@end
#endif

26
native/Avalonia.Native/src/OSX/menu.mm

@ -292,8 +292,13 @@ void AvnAppMenuItem::RaiseOnClicked()
AvnAppMenu::AvnAppMenu(IAvnMenuEvents* events)
{
_baseEvents = events;
id del = [[AvnMenuDelegate alloc] initWithParent: this];
_native = [[AvnMenu alloc] initWithDelegate: del];
_delegate = [[AvnMenuDelegate alloc] initWithParent: this];
_native = [[AvnMenu alloc] initWithDelegate: _delegate];
}
AvnAppMenu::~AvnAppMenu()
{
[_delegate parentDestroyed];
}
@ -394,7 +399,7 @@ HRESULT AvnAppMenu::Clear()
@implementation AvnMenuDelegate
{
ComPtr<AvnAppMenu> _parent;
AvnAppMenu* _parent;
}
- (id) initWithParent:(AvnAppMenu *)parent
{
@ -402,6 +407,12 @@ HRESULT AvnAppMenu::Clear()
_parent = parent;
return self;
}
- (void) parentDestroyed
{
_parent = nullptr;
}
- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
{
if(shouldCancel)
@ -416,17 +427,20 @@ HRESULT AvnAppMenu::Clear()
- (void)menuNeedsUpdate:(NSMenu *)menu
{
_parent->RaiseNeedsUpdate();
if(_parent)
_parent->RaiseNeedsUpdate();
}
- (void)menuWillOpen:(NSMenu *)menu
{
_parent->RaiseOpening();
if(_parent)
_parent->RaiseOpening();
}
- (void)menuDidClose:(NSMenu *)menu
{
_parent->RaiseClosed();
if(_parent)
_parent->RaiseClosed();
}
@end

2
src/Avalonia.MicroCom/CallbackBase.cs

@ -32,6 +32,8 @@ namespace Avalonia.MicroCom
if (_referencedFromManaged == false && _referencedFromNative == false)
{
_destroyed = true;
Shadow?.Dispose();
Shadow = null;
Destroyed();
}
}

13
src/Avalonia.Native/IAvnMenu.cs

@ -44,7 +44,6 @@ namespace Avalonia.Native.Interop.Impl
{
partial class __MicroComIAvnMenuProxy
{
private MenuEvents _events;
private AvaloniaNativeMenuExporter _exporter;
private List<__MicroComIAvnMenuItemProxy> _menuItems = new List<__MicroComIAvnMenuItemProxy>();
private Dictionary<NativeMenuItemBase, __MicroComIAvnMenuItemProxy> _menuItemLookup = new Dictionary<NativeMenuItemBase, __MicroComIAvnMenuItemProxy>();
@ -71,25 +70,15 @@ namespace Avalonia.Native.Interop.Impl
public static __MicroComIAvnMenuProxy Create(IAvaloniaNativeFactory factory)
{
var events = new MenuEvents();
using var events = new MenuEvents();
var menu = (__MicroComIAvnMenuProxy)factory.CreateMenu(events);
events.Initialise(menu);
menu._events = events;
return menu;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_events.Dispose();
}
}
private void RemoveAndDispose(__MicroComIAvnMenuItemProxy item)
{
_menuItemLookup.Remove(item.ManagedMenuItem);

Loading…
Cancel
Save