[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