From f45a53d6c3748d3150f0054d15326fac32e2c048 Mon Sep 17 00:00:00 2001 From: scheffle Date: Fri, 28 Apr 2023 12:54:40 +0200 Subject: [PATCH 1/2] add leak detector for macos standalone applications --- .../source/platform/mac/macapplication.mm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/vstgui/standalone/source/platform/mac/macapplication.mm b/vstgui/standalone/source/platform/mac/macapplication.mm index acbc2ec3a..0548f0829 100644 --- a/vstgui/standalone/source/platform/mac/macapplication.mm +++ b/vstgui/standalone/source/platform/mac/macapplication.mm @@ -704,6 +704,24 @@ - (void)application:(nonnull NSApplication*)sender openFiles:(nonnull NSArray Date: Fri, 28 Apr 2023 12:54:48 +0200 Subject: [PATCH 2/2] fix leaks --- vstgui/contrib/datepicker.mm | 3 ++ .../mac/cocoa/nsviewdraggingsession.mm | 2 +- .../editing/uieditmenucontroller.cpp | 30 +++++++++++++++++++ .../editing/uieditmenucontroller.h | 9 ++++-- vstgui/uidescription/uidescription.cpp | 4 +-- vstgui/uidescription/uidescription.h | 3 +- 6 files changed, 45 insertions(+), 6 deletions(-) diff --git a/vstgui/contrib/datepicker.mm b/vstgui/contrib/datepicker.mm index aa1a4a245..9aa020149 100644 --- a/vstgui/contrib/datepicker.mm +++ b/vstgui/contrib/datepicker.mm @@ -141,6 +141,9 @@ static void validate (id self, SEL cmd, NSDatePickerCell* datePickerCell, dateComponents.month = date.month; dateComponents.year = date.year; impl->view.dateValue = [calendar dateFromComponents:dateComponents]; +#if !__has_feature(objc_arc) + [dateComponents release]; +#endif } //------------------------------------------------------------------------ diff --git a/vstgui/lib/platform/mac/cocoa/nsviewdraggingsession.mm b/vstgui/lib/platform/mac/cocoa/nsviewdraggingsession.mm index 6ab7ab439..3aa4fff2a 100644 --- a/vstgui/lib/platform/mac/cocoa/nsviewdraggingsession.mm +++ b/vstgui/lib/platform/mac/cocoa/nsviewdraggingsession.mm @@ -252,7 +252,7 @@ static Class CreateClass () //----------------------------------------------------------------------------- NSImage* NSViewDraggingSession::nsImageForDragOperation (CBitmap* bitmap) { - return bitmapToNSImage (bitmap); + return [bitmapToNSImage (bitmap) autorelease]; } //------------------------------------------------------------------------ diff --git a/vstgui/uidescription/editing/uieditmenucontroller.cpp b/vstgui/uidescription/editing/uieditmenucontroller.cpp index d8dbadc18..59bb6f569 100644 --- a/vstgui/uidescription/editing/uieditmenucontroller.cpp +++ b/vstgui/uidescription/editing/uieditmenucontroller.cpp @@ -30,6 +30,15 @@ UIEditMenuController::UIEditMenuController (IController* baseController, UISelec { } +//------------------------------------------------------------------------ +UIEditMenuController::~UIEditMenuController () noexcept +{ + if (editMenu) + editMenu->unregisterViewListener (this); + if (fileMenu) + fileMenu->unregisterViewListener (this); +} + //---------------------------------------------------------------------------------------------------- static void addEntriesToMenu (const UIEditing::MenuEntry* entries, COptionMenu* menu, ICommandMenuItemTarget* menuItemTarget, int32_t& index) { @@ -615,6 +624,21 @@ static void copyMenuItems (COptionMenu* src, COptionMenu* dst) } } +//------------------------------------------------------------------------ +void UIEditMenuController::viewRemoved (CView* view) +{ + if (view == editMenu) + { + view->unregisterViewListener (this); + editMenu = nullptr; + } + else if (view == fileMenu) + { + view->unregisterViewListener (this); + fileMenu = nullptr; + } +} + //---------------------------------------------------------------------------------------------------- CView* UIEditMenuController::verifyView (CView* view, const UIAttributes& attributes, const IUIDescription*) { @@ -628,7 +652,10 @@ CView* UIEditMenuController::verifyView (CView* view, const UIAttributes& attrib if (editMenu) copyMenuItems (editMenu, menu); else + { createEditMenu (menu); + menu->registerViewListener (this); + } editMenu = menu; break; } @@ -637,7 +664,10 @@ CView* UIEditMenuController::verifyView (CView* view, const UIAttributes& attrib if (fileMenu) copyMenuItems (fileMenu, menu); else + { createFileMenu (menu); + menu->registerViewListener (this); + } fileMenu = menu; break; } diff --git a/vstgui/uidescription/editing/uieditmenucontroller.h b/vstgui/uidescription/editing/uieditmenucontroller.h index e54ac86d8..f9cc94e95 100644 --- a/vstgui/uidescription/editing/uieditmenucontroller.h +++ b/vstgui/uidescription/editing/uieditmenucontroller.h @@ -13,6 +13,7 @@ #include "../delegationcontroller.h" #include "../../lib/controls/icommandmenuitemtarget.h" #include "../../lib/events.h" +#include "../../lib/iviewlistener.h" namespace VSTGUI { class IActionPerformer; @@ -144,11 +145,14 @@ static const MenuEntry fileMenu[] = { } // UIEditing //---------------------------------------------------------------------------------------------------- -class UIEditMenuController : public CBaseObject, public DelegationController, public CommandMenuItemTargetAdapter +class UIEditMenuController : public CBaseObject, + public DelegationController, + public CommandMenuItemTargetAdapter, + public ViewListenerAdapter { public: UIEditMenuController (IController* baseController, UISelection* selection, UIUndoManager* undoManager, UIDescription* description, IActionPerformer* actionPerformer); - ~UIEditMenuController () noexcept override = default; + ~UIEditMenuController () noexcept override; COptionMenu* getFileMenu () const { return fileMenu; } COptionMenu* getEditMenu () const { return editMenu; } @@ -170,6 +174,7 @@ class UIEditMenuController : public CBaseObject, public DelegationController, pu void createEditMenu (COptionMenu* menu); void createFileMenu (COptionMenu* menu); + void viewRemoved (CView* view) override; CView* verifyView (CView* view, const UIAttributes& attributes, const IUIDescription* description) override; IControlListener* getControlListener (UTF8StringPtr name) override { return this; } void controlBeginEdit (CControl* pControl) override; diff --git a/vstgui/uidescription/uidescription.cpp b/vstgui/uidescription/uidescription.cpp index 7adf10bcb..adec79c5e 100644 --- a/vstgui/uidescription/uidescription.cpp +++ b/vstgui/uidescription/uidescription.cpp @@ -567,7 +567,8 @@ Detail::UINode* UIDescription::findNodeForView (CView* view) const } //----------------------------------------------------------------------------- -bool UIDescription::storeViews (const std::list& views, OutputStream& stream, UIAttributes* customData) const +bool UIDescription::storeViews (const std::list& views, OutputStream& stream, + SharedPointer customData) const { auto nodeList = makeOwned (false); for (auto& view : views) @@ -599,7 +600,6 @@ bool UIDescription::storeViews (const std::list& views, OutputStream& st UINode* customNode = new UINode (Detail::MainNodeNames::kCustom, customData); nodeList->add (customNode); customNode->forget (); - customData->remember (); } UINode baseNode ("vstgui-ui-description-view-list", nodeList); return Detail::UIJsonDescWriter::write (stream, &baseNode, false); diff --git a/vstgui/uidescription/uidescription.h b/vstgui/uidescription/uidescription.h index afcb2f665..5ad547dc3 100644 --- a/vstgui/uidescription/uidescription.h +++ b/vstgui/uidescription/uidescription.h @@ -52,7 +52,8 @@ class UIDescription : public NonAtomicReferenceCounted, public IUIDescription AttributeSaveFilterFunc func = nullptr); virtual bool saveWindowsRCFile (UTF8StringPtr filename); - bool storeViews (const std::list& views, OutputStream& stream, UIAttributes* customData = nullptr) const; + bool storeViews (const std::list& views, OutputStream& stream, + SharedPointer customData = {}) const; bool restoreViews (InputStream& stream, std::list >& views, UIAttributes** customData = nullptr); UTF8StringPtr getFilePath () const;