[vlc-commits] [Git][videolan/vlc][master] macosx/playqueue: fix drag and drop of multiple library items

Steve Lhomme (@robUx4) gitlab at videolan.org
Fri Apr 17 07:43:16 UTC 2026



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
df5b478f by Serhii Bykov at 2026-04-17T07:00:46+00:00
macosx/playqueue: fix drag and drop of multiple library items

- - - - -


5 changed files:

- modules/gui/macosx/extensions/NSPasteboardItem+VLCAdditions.m
- modules/gui/macosx/library/VLCLibraryCollectionViewDelegate.m
- modules/gui/macosx/library/VLCLibraryDataTypes.h
- modules/gui/macosx/library/VLCLibraryDataTypes.m
- modules/gui/macosx/playqueue/VLCPlayQueueDataSource.m


Changes:

=====================================
modules/gui/macosx/extensions/NSPasteboardItem+VLCAdditions.m
=====================================
@@ -35,7 +35,14 @@
         [encodedLibraryItemsArray addObject:mediaItem];
     }];
 
-    NSData * const data = [NSKeyedArchiver archivedDataWithRootObject:encodedLibraryItemsArray];
+    NSError *archiveError = nil;
+    NSData * const data = [NSKeyedArchiver archivedDataWithRootObject:encodedLibraryItemsArray
+                                                requiringSecureCoding:YES
+                                                                error:&archiveError];
+    if (data == nil) {
+        NSLog(@"Failed to archive MediaLibrary Item drag payload: %@", archiveError);
+        return nil;
+    }
     [pboardItem setData:data forType:VLCMediaLibraryMediaItemUTI];
     return pboardItem;
 }


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewDelegate.m
=====================================
@@ -140,7 +140,14 @@ writeItemsAtIndexPaths:(NSSet<NSIndexPath *> *)indexPaths
         }];
     }
 
-    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:encodedLibraryItemsArray];
+    NSError *archiveError = nil;
+    NSData * const data = [NSKeyedArchiver archivedDataWithRootObject:encodedLibraryItemsArray
+                                                requiringSecureCoding:YES
+                                                                error:&archiveError];
+    if (data == nil) {
+        NSLog(@"Failed to archive MediaLibrary Item drag payload: %@", archiveError);
+        return NO;
+    }
     [pasteboard declareTypes:@[VLCMediaLibraryMediaItemPasteboardType, NSFilenamesPboardType] owner:self];
     [pasteboard setPropertyList:filePathsArray forType:NSFilenamesPboardType];
     [pasteboard setData:data forType:VLCMediaLibraryMediaItemPasteboardType];


=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.h
=====================================
@@ -290,7 +290,7 @@ typedef NS_ENUM(NSUInteger, VLCMediaLibraryParentGroupType) {
 
 @end
 
- at interface VLCMediaLibraryMediaItem : NSObject<VLCMediaLibraryItemProtocol>
+ at interface VLCMediaLibraryMediaItem : NSObject<VLCMediaLibraryItemProtocol, NSSecureCoding>
 
 + (nullable instancetype)mediaItemForLibraryID:(int64_t)libraryID;
 + (nullable instancetype)mediaItemForURL:(NSURL *)url;


=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.m
=====================================
@@ -1112,6 +1112,11 @@ static NSString *genreArrayDisplayString(NSArray<VLCMediaLibraryGenre *> * const
 @synthesize favorited = _favorited;
 @synthesize isFileBacked = _isFileBacked;
 
++ (BOOL)supportsSecureCoding
+{
+    return YES;
+}
+
 #pragma mark - initialization
 
 + (nullable instancetype)mediaItemForLibraryID:(int64_t)libraryID


=====================================
modules/gui/macosx/playqueue/VLCPlayQueueDataSource.m
=====================================
@@ -137,58 +137,72 @@ static NSString *VLCPlayQueueCellIdentifier = @"VLCPlayQueueCellIdentifier";
         return YES;
     }
 
-    /* check whether the receive data is a library item from the left-hand side */
-    NSData *data = [info.draggingPasteboard dataForType:VLCMediaLibraryMediaItemPasteboardType];
-    if (!data) {
-        data = [info.draggingPasteboard dataForType:VLCMediaLibraryMediaItemUTI];
-    }
-
-    if (!data) {
-        /* it's not, so check if it is a file handle from the Finder */
-        id propertyList = [info.draggingPasteboard propertyListForType:NSFilenamesPboardType];
-        if (propertyList == nil) {
-            return NO;
+    /* Collect library media items from all pasteboard items.
+     * Table view drags create one NSPasteboardItem per selected row, so we
+     * must iterate all of them to capture every dragged item. */
+    NSMutableArray<VLCMediaLibraryMediaItem *> * const allMediaItems = [NSMutableArray array];
+
+    for (NSPasteboardItem * const pboardItem in info.draggingPasteboard.pasteboardItems) {
+        NSData *itemData = [pboardItem dataForType:VLCMediaLibraryMediaItemPasteboardType];
+        if (!itemData) {
+            itemData = [pboardItem dataForType:VLCMediaLibraryMediaItemUTI];
+        }
+        if (!itemData) {
+            continue;
         }
 
-        NSArray *mediaPaths = [propertyList sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
-        NSUInteger mediaCount = [mediaPaths count];
-        if (mediaCount > 0) {
-            NSMutableArray *metadataArray = [NSMutableArray arrayWithCapacity:mediaCount];
-            for (NSString *mediaPath in mediaPaths) {
-                VLCOpenInputMetadata *inputMetadata;
-                NSURL *url = [NSURL fileURLWithPath:mediaPath isDirectory:NO];
-                if (!url) {
-                    continue;
-                }
-                inputMetadata = [[VLCOpenInputMetadata alloc] init];
-                inputMetadata.MRLString = url.absoluteString;
-                [metadataArray addObject:inputMetadata];
-            }
-            [_playQueueController addPlayQueueItems:metadataArray];
+        /* It is a media library item, so unarchive it and add it to the playlist */
+        NSError *unarchiveError = nil;
+        NSArray<VLCMediaLibraryMediaItem *> * const items =
+            [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithObjects:[NSArray class], [VLCMediaLibraryMediaItem class], nil]
+                                                fromData:itemData
+                                                   error:&unarchiveError];
+        if (unarchiveError != nil) {
+            msg_Err(getIntf(), "Failed to unarchive MediaLibrary Item: %s",
+                    unarchiveError.localizedDescription.UTF8String);
+            continue;
+        }
 
-            return YES;
+        if (items) {
+            [allMediaItems addObjectsFromArray:items];
         }
-        return NO;
     }
 
-    /* it is a media library item, so unarchive it and add it to the playlist */
-    NSArray *array = nil;
-    @try {
-        array = [NSKeyedUnarchiver unarchiveObjectWithData:data];
-    } @catch (NSException *exception) {
-        if ([exception.name isEqualToString:NSInvalidArgumentException]) {
-            msg_Err(getIntf(), "Failed to unarchive MediaLibrary Item: %s",
-                    [[exception reason] UTF8String]);
-            return NO;
+    if (allMediaItems.count > 0) {
+        NSInteger insertionIndex = (NSInteger)row;
+        for (VLCMediaLibraryMediaItem * const mediaItem in allMediaItems) {
+            [_playQueueController addInputItem:mediaItem.inputItem.vlcInputItem
+                                    atPosition:insertionIndex
+                                 startPlayback:NO];
+            insertionIndex++;
         }
-        @throw;
+        return YES;
     }
 
-    for (VLCMediaLibraryMediaItem *mediaItem in array) {
-        [_playQueueController addInputItem:mediaItem.inputItem.vlcInputItem atPosition:row startPlayback:NO];
+    /* Not a library item — check if it is a file handle from the Finder */
+    const id propertyList = [info.draggingPasteboard propertyListForType:NSFilenamesPboardType];
+    if (propertyList == nil) {
+        return NO;
     }
 
-    return YES;
+    const NSUInteger mediaCount = [propertyList count];
+    if (mediaCount > 0) {
+        NSMutableArray * const metadataArray = [NSMutableArray arrayWithCapacity:mediaCount];
+        for (NSString * const mediaPath in propertyList) {
+            VLCOpenInputMetadata *inputMetadata;
+            NSURL * const url = [NSURL fileURLWithPath:mediaPath isDirectory:NO];
+            if (!url) {
+                continue;
+            }
+            inputMetadata = [[VLCOpenInputMetadata alloc] init];
+            inputMetadata.MRLString = url.absoluteString;
+            [metadataArray addObject:inputMetadata];
+        }
+        [_playQueueController addPlayQueueItems:metadataArray];
+
+        return YES;
+    }
+    return NO;
 }
 
 - (NSArray<NSTableViewRowAction *> *)tableView:(NSTableView *)tableView



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/df5b478f17c833b3d20c27b5a3fc006b2492d7e2

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/df5b478f17c833b3d20c27b5a3fc006b2492d7e2
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list