From da46ee6c7ab696c9c3eb8bf80cb612e7d254d743 Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 18 Nov 2021 19:34:20 +0000 Subject: [PATCH] FileChooser: Launch chooser asynchronously When FileChooser instances were created, launched, and hidden all inside the same event callback on macOS 12.0.1, the chooser dialog sometimes remained open. This could cause problems including crashes, as closing the dialog would attempt to call a completion handler block referencing an already-deleted FileChooser::Native instance. Opening the chooser panel later on the message thread seems to resolve the issue. --- .../native/juce_mac_FileChooser.mm | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/juce_gui_basics/native/juce_mac_FileChooser.mm b/modules/juce_gui_basics/native/juce_mac_FileChooser.mm index 3cf1337cad..c3565d557b 100644 --- a/modules/juce_gui_basics/native/juce_mac_FileChooser.mm +++ b/modules/juce_gui_basics/native/juce_mac_FileChooser.mm @@ -82,8 +82,9 @@ public: filters.trim(); filters.removeEmptyStrings(); - NSString* nsTitle = juceStringToNS (owner.title); + auto* nsTitle = juceStringToNS (owner.title); [panel setTitle: nsTitle]; + [panel setReleasedWhenClosed: YES]; JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") [panel setAllowedFileTypes: createAllowedTypesArray (filters)]; @@ -153,22 +154,14 @@ public: if (nsViewPreview != nil) { [panel setAccessoryView: nil]; - [nsViewPreview release]; - - nsViewPreview = nil; - preview = nullptr; } [panel close]; - [panel release]; } if (delegate != nil) - { [delegate release]; - delegate = nil; - } } void launch() override @@ -179,10 +172,17 @@ public: addToDesktop (0); enterModalState (true); - [panel beginWithCompletionHandler:CreateObjCBlock (this, &Native::finished)]; - if (preview != nullptr) - preview->toFront (true); + MessageManager::callAsync ([ref = SafePointer (this)] + { + if (ref == nullptr) + return; + + [ref->panel beginWithCompletionHandler: CreateObjCBlock (ref.getComponent(), &Native::finished)]; + + if (ref->preview != nullptr) + ref->preview->toFront (true); + }); } }