performExternalDragDropOfFiles crashes in Ableton after specific UI scenarios

I’m having a strange issue in which I use performExternalDragDropOfFiles() within a mouseDrag(). This works just fine every time.

However, if I launch a juce::FileBrowserComponent, and then proceed to drag out the file after using and closing it, Ableton crashes. This isn’t limited to just the juce::FileBrowserComponent either, as if I have a PopUpMenu with sub PopUpMenu’s inside of it, it will also crash after the sub menu has been shown. So it appears only certain situations will trigger the crash after certain components have been shown.

I created a very simple example project to eliminate if it was anything within my code that was causing it but still ran into the same issue with a bare bones project with just a file chooser and a drag out component using .wav from my desktop.

This only appears to be happening on Windows 10 (and tested in 11) with Ableton 11 and Ableton 12. I have tried many ways to come up with a work around to prevent the crash, but have had no success.

Has anyone else experienced this issue, or have any ideas on how to fix this?

// How the file chooser is created:

void TestDragAudioProcessorEditor::buttonClicked(juce::Button* button)
{
    chooser = std::make_unique<juce::FileChooser>("Select a .wav file", juce::File{}, "*.wav");
    auto chooserFlags = juce::FileBrowserComponent::openMode | juce::FileBrowserComponent::canSelectFiles;

    chooser->launchAsync(chooserFlags, [](const juce::FileChooser& fc)
        {
            //Do nothing, here for testing purposes
        });
}

// For the mouse drag of a component:

void DraggableComponent::mouseDrag(const juce::MouseEvent& e)
{
	juce::File testFile("C:\\Users\Tensorpunk\\Desktop\\test.wav");

    if (testFile.existsAsFile())
    {
        juce::StringArray files;
        files.add(testFile.getFullPathName());

        auto editor = findParentComponentOfClass<TestDragAudioProcessorEditor>();
        juce::Point<int> mousePosition = e.getScreenPosition();
        juce::Rectangle<int> windowBounds = editor->getScreenBounds();

        if (!windowBounds.contains(mousePosition))
        {
            // Crash happens after this has been called after the chooser has been shown once, otherwise works perfectly fine
            performExternalDragDropOfFiles(files, true, this);
        }
    }
}

Hi, Have you run in the debugger to trace what is actually causing the crash?

Yes, I have run the plugin in Ableton under the VS debugger (attached) and monitored the crash. Unfortunately, the call stack points into Ableton’s code, and since we don’t have Ableton’s debug symbols (Ableton.pdb), the debugger shows no frames from my plugin code. Once it hits the exception, the stack is entirely within Ableton’s process space—none of my plugin functions appear.

Again, its shortly after performExternalDragDropOfFiles() is called. I’ve tried DBG statements with the callback and those actually print successfully after the line is called.

Ultimately it happens inside Ableton’s code with no traceable entry point from my end.

I’m wondering if it is because in Ableton, when you drag and drop off of the plugin, Ableton automatically closes the plugin UI. Perhaps with certain components such as the FileChooser there is a dangling pointer? I also have a color picker in my settings that if shown/used it will cause the crash as well. It seems like asynchronous views being shown are more prone to cause the crash.

(and tested in 11) with Ableton 11 and Ableton 12

So just to be sure, are you seeing this issue on Windows 11 and Ableton 12?

I’d like to get to the bottom of this, but my first attempt to reproduce the issue failed. I’m using Live 12.1.5 (probably the latest build) and Windows 11 23H2.

I built a plugin incorporating your example code, used the FileBrowserComponent and then the drag and drop operation.

I also noticed that Ableton leaves the plugin UI open for me after the drop operation, contrary to your description.

I think the details could be important here, so if you could share additional details, an example JUCE project or a video recording about how the crash happens in your situation, those could be very helpful.

I can confirm I’m seeing this on Windows 11 23H2 and Ableton 12.0.15.

For the other machine it is Windows 10 22h2 / Ableton 11.2.

Ableton will leave the window open if you are dragging to the track the plugin is on (if it’s an audio plugin and not instrument for audio to work). If you drag it to another track however, it does close the window as you can see in the video below.

I downloaded the latest of JUCE (my Windows 10 machine doesn’t have the latest) and rebuilt the Test drag and drop plugin on the Windows 11 PC just in case to see if that would affect it. It did not.

One thing I want to note is that it doesn’t always crash right away. Sometimes I launch Ableton and it will crash immediately after showing a file dialog and dragging out, sometimes not at all seemingly for that instance. Usually, I can get it pretty fast though, especially on my main plugin I am troubleshooting this with.

The inconsistency in crashing has also lead to quite the bit of gaslighting towards myself thinking I had solved it several times, only to launch Ableton again without any changes, and get the crash again. :sweat_smile:

This is running on the Windows 11 PC. Here is a video of it happening, as you can see towards the end Ableton freezes and crashes. It does actually not crash after the file dialog for the first few times in this scenario, but eventually crashes.

I would say, perhaps with your version to try multiple times to try and see if it eventually happens (and dragging to other tracks). Also try restarting Ableton again if it never happens (I’ve had some rare instances where it never does at all)

Here is a version of the plugin from video just in case for some reason there is a difference between our two if you would like to test it. This was built with the latest JUCE.

TestDrag_vst.zip (4.1 MB)

Lastly, I found something interesting last night which is leading me to believe this is some type of focus bug within Ableton itself:

  • I have Ableton open and the plugin UI open (no file dialog shown yet or any other UI components that trigger it)
  • I click off of Ableton to another open window on my desktop
  • If I click back on Ableton itself first, then drag out, no crash
  • If I instead click on the plugin UI window first (not Ableton itself) and then drag out, I will get a crash

One last note, that after showing a file dialog, if I manually close the plugin UI and reopen it and do not do a file dialog again, it does not crash until a file dialog or another UI component such as a sub menu is shown again. So something about that seems to “refresh” the bug from happening.

I appreciate your help, this has lead me to a very frustrating past two weeks trying to pin down a work around. I’m almost at the point to where I’m going to disable the feature for Windows + Ableton users for the plugin, which would be a massive bummer as being able to drag audio out is a majorly requested feature for it.

1 Like

Thank you, I can reproduce the issue now, but I can’t speak for the cause yet.

Just for reference, I’m sharing a patch for modifying the AudioPluginExample on develop in a way that the crash can be triggered.

AbletonDndCrash.patch (3.2 KB)

What really did the trick for me was what you said about focusing on another window, and then immediately clicking the plugin’s drag n drop area right away, without giving focus to Live at all. Then the drop operation in an empty track area would be likely to cause a crash.

The key seems to be giving away the focus to some other window, and the PopupMenu or FileBrowserComponent doesn’t have to be at play at all.

I’m seeing the crash on either the AudioCalc or the winmm.dll thread.

I am glad you are able to reproduce the bug, makes me feel less crazy to verify its not only me. :sunglasses:

I think you are right, those components aren’t the problem but the fact another window has focus. If there is anything on the JUCE side of things that can be programmatically done before the performExternalDragDropOfFiles to fix this for now would be awesome until the full fix is figured out.

I will delay my release a bit longer in hope to find a solution soon and if I figure out anything new will update this thread in the mean time.

I am happy to report I have found a solution – granted it is a little hacky.

The idea is to use the Windows API to find the Ableton window and then use SetFocus() to manually ensure the focus is set before performExternalDragDropOfFiles()

#ifdef JUCE_WINDOWS
    #include <windows.h>
    #include <tchar.h>
    #include <string>

    static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
    {
        // Only consider visible windows.
        if (!::IsWindowVisible(hwnd))
            return TRUE;

        // Get the length of the window title.
        int length = ::GetWindowTextLength(hwnd);
        if (length == 0)
            return TRUE; // Skip windows without a title.

        // Retrieve the window title.
        TCHAR* title = new TCHAR[length + 1];
        ::GetWindowText(hwnd, title, length + 1);
        std::basic_string<TCHAR> windowTitle(title);
        delete[] title;

        // Check if the window title contains "Ableton Live".
        if (windowTitle.find(_T("Ableton Live")) != std::basic_string<TCHAR>::npos)
        {
            // If found, store the HWND and stop enumeration.
            HWND* pFoundHwnd = reinterpret_cast<HWND*>(lParam);
            *pFoundHwnd = hwnd;
            return FALSE; // Stop enumerating further windows.
        }

        return TRUE; // Continue enumeration.
    }

    static HWND findAbletonMainWindow()
    {
        HWND abletonHwnd = nullptr;
        // Use the global callback function explicitly.
        EnumWindows(::EnumWindowsProc, reinterpret_cast<LPARAM>(&abletonHwnd));
        return abletonHwnd;
    }

    // A helper function that checks if the host is Ableton and sets focus accordingly.
    static void ensureAbletonWindowFocus()
    {
        // Create a PluginHostType instance to query the host.
        juce::PluginHostType hostType;

        // Check if the host is Ableton Live.
        if (hostType.isAbletonLive())
        {
            HWND abletonWindow = findAbletonMainWindow();
            if (abletonWindow != nullptr)
            {
                DBG("Ableton window found! Ensuring focus is set.");
                ::SetFocus(abletonWindow);
            }
            else
            {
                DBG("Ableton window not found.");
            }
        }
    }
#endif

...

void DraggableComponent::mouseDrag(const juce::MouseEvent& e)
{
    juce::File testFile("C:\\Dev\\test.wav");
    
    if (testFile.existsAsFile())
    {
        juce::StringArray files;
        files.add(testFile.getFullPathName());

        auto editor = findParentComponentOfClass<TestDragAudioProcessorEditor>();
        juce::Point<int> mousePosition = e.getScreenPosition();
        juce::Rectangle<int> windowBounds = editor->getScreenBounds();

        if (!windowBounds.contains(mousePosition))
        {
            #ifdef JUCE_WINDOWS
                        ensureAbletonWindowFocus();
            #endif   

            performExternalDragDropOfFiles(files, true, this);
        }
    }
}



From my testing this works and fixes any crashes!

1 Like

I encountered the same issue, thanks for sharing your hotfix! Did you report this issue with ableton?