[vlc-commits] [Git][videolan/vlc][master] macos: preserve play queue drop position for audio grid drags
Felix Paul Kühne (@fkuehne)
gitlab at videolan.org
Sat Aug 29 10:15:32 UTC 2026
Felix Paul Kühne pushed to branch master at VideoLAN / VLC
Commits:
d04779d5 by Serhii Bykov at 2026-08-29T12:05:29+02:00
macos: preserve play queue drop position for audio grid drags
- - - - -
4 changed files:
- modules/gui/macosx/library/VLCLibraryDataTypes.h
- modules/gui/macosx/library/VLCLibraryDataTypes.m
- modules/gui/macosx/playqueue/VLCPlayQueueDataSource.m
- modules/gui/macosx/views/VLCFileDragRecognisingView.m
Changes:
=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.h
=====================================
@@ -294,6 +294,7 @@ typedef NS_ENUM(NSUInteger, VLCMediaLibraryParentGroupType) {
+ (nullable instancetype)mediaItemForLibraryID:(int64_t)libraryID;
+ (nullable instancetype)mediaItemForURL:(NSURL *)url;
++ (nullable NSArray<VLCMediaLibraryMediaItem *> *)mediaItemsFromPasteboardData:(NSData *)data;
- (nullable instancetype)initWithMediaItem:(struct vlc_ml_media_t *)mediaItem;
- (nullable instancetype)initWithExternalURL:(NSURL *)url;
- (nullable instancetype)initWithStreamURL:(NSURL *)url;
=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.m
=====================================
@@ -1271,6 +1271,26 @@ static NSString *genreArrayDisplayString(NSArray<VLCMediaLibraryGenre *> * const
@synthesize favorited = _favorited;
@synthesize isFileBacked = _isFileBacked;
++ (nullable NSArray<VLCMediaLibraryMediaItem *> *)mediaItemsFromPasteboardData:(NSData *)data
+{
+ NSParameterAssert(data != nil);
+ if (data == nil) {
+ return nil;
+ }
+
+ NSError *unarchiveError = nil;
+ NSArray<VLCMediaLibraryMediaItem *> * const items =
+ [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithObjects:[NSArray class], [VLCMediaLibraryMediaItem class], nil]
+ fromData:data
+ error:&unarchiveError];
+ if (unarchiveError != nil) {
+ NSLog(@"Failed to unarchive MediaLibrary Item drag payload: %@", unarchiveError);
+ return nil;
+ }
+
+ return items;
+}
+
+ (BOOL)supportsSecureCoding
{
return YES;
=====================================
modules/gui/macosx/playqueue/VLCPlayQueueDataSource.m
=====================================
@@ -22,6 +22,7 @@
#import "VLCPlayQueueDataSource.h"
+#import "extensions/NSPasteboardItem+VLCAdditions.h"
#import "extensions/NSString+Helpers.h"
#import "extensions/NSView+VLCAdditions.h"
#import "main/VLCMain.h"
@@ -29,8 +30,10 @@
#import "playqueue/VLCPlayQueueTableCellView.h"
#import "playqueue/VLCPlayQueueItem.h"
#import "playqueue/VLCPlayQueueModel.h"
+#import "library/VLCInputItem.h"
#import "library/VLCLibraryDataTypes.h"
#import "views/VLCDragDropView.h"
+#import "views/VLCFileDragRecognisingView.h"
static NSString *VLCPlayQueueCellIdentifier = @"VLCPlayQueueCellIdentifier";
@@ -146,6 +149,54 @@ static NSString *VLCPlayQueueCellIdentifier = @"VLCPlayQueueCellIdentifier";
[_playQueueController moveItemWithID:uniqueID toPosition:row];
return YES;
}
+
+ /* 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<VLCMediaLibraryMediaItem *> * const items = [VLCMediaLibraryMediaItem mediaItemsFromPasteboardData:itemData];
+ if (items) {
+ [allMediaItems addObjectsFromArray:items];
+ }
+ }
+
+ /* Collection view drags write a single aggregated payload directly on the
+ * dragging pasteboard instead of creating one NSPasteboardItem per item. */
+ if (allMediaItems.count == 0) {
+ NSData *itemData = [info.draggingPasteboard dataForType:VLCMediaLibraryMediaItemPasteboardType];
+ if (!itemData) {
+ itemData = [info.draggingPasteboard dataForType:VLCMediaLibraryMediaItemUTI];
+ }
+
+ if (itemData) {
+ NSArray<VLCMediaLibraryMediaItem *> * const items = [VLCMediaLibraryMediaItem mediaItemsFromPasteboardData:itemData];
+ if (items) {
+ [allMediaItems addObjectsFromArray:items];
+ }
+ }
+ }
+
+ if (allMediaItems.count > 0) {
+ NSInteger insertionIndex = (NSInteger)row;
+ for (VLCMediaLibraryMediaItem * const mediaItem in allMediaItems) {
+ [_playQueueController addInputItem:mediaItem.inputItem.vlcInputItem
+ atPosition:insertionIndex
+ startPlayback:NO];
+ insertionIndex++;
+ }
+ return YES;
+ }
+
return [VLCFileDragRecognisingView
handlePasteboardFromDragSessionAsPlayQueueItems:info.draggingPasteboard];
}
=====================================
modules/gui/macosx/views/VLCFileDragRecognisingView.m
=====================================
@@ -42,17 +42,7 @@
continue;
}
- 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;
- }
-
+ NSArray<VLCMediaLibraryMediaItem *> * const items = [VLCMediaLibraryMediaItem mediaItemsFromPasteboardData:itemData];
if (items) {
[allMediaItems addObjectsFromArray:items];
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/d04779d596ae0d6c39097e61d5522a80435538e7
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/d04779d596ae0d6c39097e61d5522a80435538e7
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help
More information about the vlc-commits
mailing list