diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormat.h b/modules/juce_audio_processors/format/juce_AudioPluginFormat.h index f3bc826820..7bd45452f2 100644 --- a/modules/juce_audio_processors/format/juce_AudioPluginFormat.h +++ b/modules/juce_audio_processors/format/juce_AudioPluginFormat.h @@ -115,6 +115,9 @@ public: */ virtual bool isTrivialToScan() const = 0; + /** Should return true if plugins in this format can be scanned on a background thread. */ + virtual bool canScanOnBackgroundThread() const { return true; } + /** Searches a suggested set of directories for any plugins in this format. The path might be ignored, e.g. by AUs, which are found by the OS rather than manually. diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h index 9c2be59493..e58736d96c 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h @@ -61,6 +61,13 @@ public: bool canScanForPlugins() const override { return true; } bool isTrivialToScan() const override { return false; } + /** Although there doesn't seem to be any official documentation on the matter, + Native Instruments Kontakt VST3 crashes on macOS when its bundleEntry is called on a + background thread. To allow this plugin (and other ones with similar problems) to be + discovered, it's a good idea to scan VST3 plugins on the main thread. + */ + bool canScanOnBackgroundThread() const override { return false; } + void findAllTypesForFile (OwnedArray&, const String& fileOrIdentifier) override; bool fileMightContainThisPluginType (const String& fileOrIdentifier) override; String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override; diff --git a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp index 5f6c8a3a7a..103a53546d 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp +++ b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp @@ -387,10 +387,14 @@ public: Scanner (PluginListComponent& plc, AudioPluginFormat& format, const StringArray& filesOrIdentifiers, PropertiesFile* properties, bool allowPluginsWhichRequireAsynchronousInstantiation, int threads, const String& title, const String& text) - : owner (plc), formatToScan (format), filesOrIdentifiersToScan (filesOrIdentifiers), propertiesToUse (properties), + : owner (plc), + formatToScan (format), + filesOrIdentifiersToScan (filesOrIdentifiers), + propertiesToUse (properties), pathChooserWindow (TRANS("Select folders to scan..."), String(), MessageBoxIconType::NoIcon), progressWindow (title, text, MessageBoxIconType::NoIcon), - numThreads (threads), allowAsync (allowPluginsWhichRequireAsynchronousInstantiation) + numThreads (format.canScanOnBackgroundThread() ? threads : 0), + allowAsync (format.canScanOnBackgroundThread() && allowPluginsWhichRequireAsynchronousInstantiation) { FileSearchPath path (formatToScan.getDefaultLocationsToSearch()); @@ -443,7 +447,7 @@ private: FileSearchPathListComponent pathList; String pluginBeingScanned; double progress = 0; - int numThreads; + const int numThreads; bool allowAsync, finished = false, timerReentrancyCheck = false; std::unique_ptr pool;