performExternalDragDropOfFiles, in juce_mac_Windowing.mm, has an issue when dragging multiple files from a JUCE window into, say, the finder. Only the first file in the list was dropped.
In the article found here: Dragging Files in the “Dragging File Paths” section, it is stated as below:
“To initiate a drag operation on multiple files, you need to use the NSView or NSWindow method dragImage:at:offset:event:pasteboard:source:slideBack:. You must place the array of file paths onto the pasteboard yourself, using the NSPasteboard method setPropertyList:forType: …”
So I changed the function source from:
bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool /canMoveFiles/)
{
if (files.size() == 0)
return false;
MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource(0);
if (draggingSource == nullptr) { jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event! return false; }
Component* sourceComp = draggingSource->getComponentUnderMouse();
if (sourceComp == nullptr) { jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event! return false; }
JUCE_AUTORELEASEPOOL { if (NSView* view = (NSView*) sourceComp->getWindowHandle()) { if (NSEvent* event = [[view window] currentEvent]) { NSPoint eventPos = [event locationInWindow]; NSRect dragRect = [view convertRect: NSMakeRect (eventPos.x - 16.0f, eventPos.y - 16.0f, 32.0f, 32.0f) fromView: nil];
for (int i = 0; i < files.size(); ++i) { if (! [view dragFile: juceStringToNS (files[i]) fromRect: dragRect slideBack: YES event: event]) return false; }
return true; } } }
return false;
}
to:
bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool /canMoveFiles/)
{
if (files.size() == 0)
return false;
MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource(0);
if (draggingSource == nullptr) { jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event! return false; }
Component* sourceComp = draggingSource->getComponentUnderMouse();
if (sourceComp == nullptr) { jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event! return false; }
JUCE_AUTORELEASEPOOL { if (NSView* view = (NSView*) sourceComp->getWindowHandle()) { if (NSEvent* event = [[view window] currentEvent]) { NSPoint eventPos = [event locationInWindow]; NSRect dragRect = [view convertRect: NSMakeRect (eventPos.x - 16.0f, eventPos.y - 16.0f, 32.0f, 32.0f) fromView: nil];
if (files.size() == 1){ if (! [view dragFile: juceStringToNS (files[0]) fromRect: dragRect slideBack: YES event: event]) return false; } else { NSMutableArray *fileList = [[NSMutableArray alloc] init]; for (int i = 0; i < files.size(); ++i){ [fileList addObject:juceStringToNS(files[i])]; }
// Write data to the pasteboard NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; [pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil]; [pboard setPropertyList:fileList forType:NSFilenamesPboardType]; // Start the multiple drag operation NSImage *dragImage = [[NSWorkspace sharedWorkspace] iconForFile:juceStringToNS(files[0])]; [view dragImage:dragImage at:eventPos offset:NSZeroSize event:event pasteboard:pboard source:view slideBack:YES]; } return true; } } }
return false;
}
Now all files are copied to the destination, in finder, or in a DAW when dragging mp3 or wav files.
I’m hoping this will solve the issue for anyone who encountered the same problem.
Cheers,
Jacques