From 950432e40723ab8fabdff72a98e304c8cff4b20b Mon Sep 17 00:00:00 2001 From: David Elliott Date: Fri, 15 Oct 2004 03:06:50 +0000 Subject: [PATCH] Allow the wxMenu to be owned by the NSMenu so that it can be returned from methods which Cocoa calls when a menu is to be popped up. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@29867 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/cocoa/menu.h | 7 ++++++- src/cocoa/menu.mm | 32 +++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/include/wx/cocoa/menu.h b/include/wx/cocoa/menu.h index 819a36ddf9..e05cd49d70 100644 --- a/include/wx/cocoa/menu.h +++ b/include/wx/cocoa/menu.h @@ -27,7 +27,9 @@ class WXDLLEXPORT wxMenu : public wxMenuBase, public wxCocoaNSMenu public: // ctors and dtor wxMenu(const wxString& title, long style = 0) - : wxMenuBase(title, style) { Create(title,style); } + : wxMenuBase(title, style) + , m_cocoaDeletes(false) + { Create(title,style); } bool Create(const wxString& title, long style = 0); wxMenu(long style = 0) : wxMenuBase(style) { Create(wxEmptyString, style); } @@ -39,8 +41,11 @@ public: // ------------------------------------------------------------------------ public: inline WX_NSMenu GetNSMenu() { return m_cocoaNSMenu; } + void SetCocoaDeletes(bool cocoaDeletes); + virtual void Cocoa_dealloc(); protected: WX_NSMenu m_cocoaNSMenu; + bool m_cocoaDeletes; // ------------------------------------------------------------------------ // Implementation // ------------------------------------------------------------------------ diff --git a/src/cocoa/menu.mm b/src/cocoa/menu.mm index dee3802127..529f422350 100644 --- a/src/cocoa/menu.mm +++ b/src/cocoa/menu.mm @@ -45,12 +45,15 @@ bool wxMenu::Create(const wxString& title, long style) { wxAutoNSAutoreleasePool pool; m_cocoaNSMenu = [[NSMenu alloc] initWithTitle: wxNSStringWithWxString(title)]; + AssociateNSMenu(m_cocoaNSMenu); return true; } wxMenu::~wxMenu() { - [m_cocoaNSMenu release]; + DisassociateNSMenu(m_cocoaNSMenu); + if(!m_cocoaDeletes) + [m_cocoaNSMenu release]; } wxMenuItem* wxMenu::DoAppend(wxMenuItem *item) @@ -80,6 +83,33 @@ wxMenuItem* wxMenu::DoRemove(wxMenuItem *item) return retitem; } +// This autoreleases the menu on the assumption that something is +// going to retain it shortly (for instance, it is going to be returned from +// an overloaded [NSStatusItem menu] or from the applicationDockMenu: +// NSApplication delegate method. +// +// It then sets a bool flag m_cocoaDeletes. When the NSMenu is dealloc'd +// (dealloc is the Cocoa destructor) we delete ourselves. In this manner we +// can be available for Cocoa calls until Cocoa is finished with us. +// +// I can see very few reasons to undo this. Nevertheless, it is implemented. +void wxMenu::SetCocoaDeletes(bool cocoaDeletes) +{ + if(m_cocoaDeletes==cocoaDeletes) + return; + m_cocoaDeletes = cocoaDeletes; + if(m_cocoaDeletes) + [m_cocoaNSMenu autorelease]; + else + [m_cocoaNSMenu retain]; +} + +void wxMenu::Cocoa_dealloc() +{ + if(m_cocoaDeletes) + delete this; +} + // ============================================================================ // wxMenuBar implementation // ============================================================================ -- 2.45.2