diff --git a/src/MacVim/Info.plist b/src/MacVim/Info.plist index d42c43b0fc..2623d0f319 100644 --- a/src/MacVim/Info.plist +++ b/src/MacVim/Info.plist @@ -1299,6 +1299,7 @@ MacVim NSSendTypes + public.file-url NSFilenamesPboardType NSUserData diff --git a/src/MacVim/MMAppController.m b/src/MacVim/MMAppController.m index 7094d24f3f..dd668ad05d 100644 --- a/src/MacVim/MMAppController.m +++ b/src/MacVim/MMAppController.m @@ -1647,12 +1647,9 @@ fsEventCallback(ConstFSEventStreamRef streamRef, - (void)newFileHere:(NSPasteboard *)pboard userData:(NSString *)userData error:(NSString **)error { - if (![[pboard types] containsObject:NSFilenamesPboardType]) { - ASLogNotice(@"Pasteboard contains no NSFilenamesPboardType"); + NSArray *filenames = extractPasteboardFilenames(pboard); + if (filenames == nil || filenames.count == 0) return; - } - - NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType]; NSString *path = [filenames lastObject]; BOOL dirIndicator; diff --git a/src/MacVim/MMCoreTextView.m b/src/MacVim/MMCoreTextView.m index 65dfdf2f6a..a1089fb886 100644 --- a/src/MacVim/MMCoreTextView.m +++ b/src/MacVim/MMCoreTextView.m @@ -244,8 +244,8 @@ static void grid_free(Grid *grid) { helper = [[MMTextViewHelper alloc] init]; [helper setTextView:self]; - [self registerForDraggedTypes:[NSArray arrayWithObjects: - NSFilenamesPboardType, NSPasteboardTypeString, nil]]; + [self registerForDraggedTypes:@[getPasteboardFilenamesType(), + NSPasteboardTypeString]]; ligatures = NO; diff --git a/src/MacVim/MMTextView.m b/src/MacVim/MMTextView.m index a4bcbf79ba..4546787ed1 100644 --- a/src/MacVim/MMTextView.m +++ b/src/MacVim/MMTextView.m @@ -819,8 +819,7 @@ - (NSArray *)acceptableDragTypes { - return [NSArray arrayWithObjects:NSFilenamesPboardType, - NSPasteboardTypeString, nil]; + return @[getPasteboardFilenamesType(), NSPasteboardTypeString]; } - (BOOL)performDragOperation:(id )sender diff --git a/src/MacVim/MMTextViewHelper.m b/src/MacVim/MMTextViewHelper.m index 8cebd4c4da..f178db5b16 100644 --- a/src/MacVim/MMTextViewHelper.m +++ b/src/MacVim/MMTextViewHelper.m @@ -519,9 +519,9 @@ KeyboardInputSourcesEqual(TISInputSourceRef a, TISInputSourceRef b) NSString *string = [pboard stringForType:NSPasteboardTypeString]; [[self vimController] dropString:string]; return YES; - } else if ([[pboard types] containsObject:NSFilenamesPboardType]) { - NSArray *files = [pboard propertyListForType:NSFilenamesPboardType]; - [[self vimController] dropFiles:files forceOpen:NO]; + } else if ([[pboard types] containsObject:getPasteboardFilenamesType()]) { + NSArray *filenames = extractPasteboardFilenames(pboard); + [[self vimController] dropFiles:filenames forceOpen:NO]; return YES; } @@ -533,7 +533,7 @@ KeyboardInputSourcesEqual(TISInputSourceRef a, TISInputSourceRef b) NSDragOperation sourceDragMask = [sender draggingSourceOperationMask]; NSPasteboard *pboard = [sender draggingPasteboard]; - if ( [[pboard types] containsObject:NSFilenamesPboardType] + if ( [[pboard types] containsObject:getPasteboardFilenamesType()] && (sourceDragMask & NSDragOperationCopy) ) return NSDragOperationCopy; if ( [[pboard types] containsObject:NSPasteboardTypeString] @@ -548,7 +548,7 @@ KeyboardInputSourcesEqual(TISInputSourceRef a, TISInputSourceRef b) NSDragOperation sourceDragMask = [sender draggingSourceOperationMask]; NSPasteboard *pboard = [sender draggingPasteboard]; - if ( [[pboard types] containsObject:NSFilenamesPboardType] + if ( [[pboard types] containsObject:getPasteboardFilenamesType()] && (sourceDragMask & NSDragOperationCopy) ) return NSDragOperationCopy; if ( [[pboard types] containsObject:NSPasteboardTypeString] diff --git a/src/MacVim/MMVimView.m b/src/MacVim/MMVimView.m index 08772b0ae9..a74845be20 100644 --- a/src/MacVim/MMVimView.m +++ b/src/MacVim/MMVimView.m @@ -151,8 +151,7 @@ enum { [[tabBarControl addTabButton] setTarget:self]; [[tabBarControl addTabButton] setAction:@selector(addNewTab:)]; [tabBarControl setAllowsDragBetweenWindows:NO]; - [tabBarControl registerForDraggedTypes: - [NSArray arrayWithObject:NSFilenamesPboardType]]; + [tabBarControl registerForDraggedTypes:[NSArray arrayWithObject:getPasteboardFilenamesType()]]; [tabBarControl setAutoresizingMask:NSViewWidthSizable|NSViewMinYMargin]; @@ -588,7 +587,7 @@ enum { forTabAtIndex:(NSUInteger)tabIndex { NSPasteboard *pb = [sender draggingPasteboard]; - return [[pb types] containsObject:NSFilenamesPboardType] + return [[pb types] containsObject:getPasteboardFilenamesType()] ? NSDragOperationCopy : NSDragOperationNone; } @@ -598,22 +597,19 @@ enum { forTabAtIndex:(NSUInteger)tabIndex { NSPasteboard *pb = [sender draggingPasteboard]; - if ([[pb types] containsObject:NSFilenamesPboardType]) { - NSArray *filenames = [pb propertyListForType:NSFilenamesPboardType]; - if ([filenames count] == 0) - return NO; - if (tabIndex != NSNotFound) { - // If dropping on a specific tab, only open one file - [vimController file:[filenames objectAtIndex:0] - draggedToTabAtIndex:tabIndex]; - } else { - // Files were dropped on empty part of tab bar; open them all - [vimController filesDraggedToTabBar:filenames]; - } - return YES; - } else { + NSArray* filenames = extractPasteboardFilenames(pb); + if (filenames == nil || filenames.count == 0) return NO; + + if (tabIndex != NSNotFound) { + // If dropping on a specific tab, only open one file + [vimController file:[filenames objectAtIndex:0] + draggedToTabAtIndex:tabIndex]; + } else { + // Files were dropped on empty part of tab bar; open them all + [vimController filesDraggedToTabBar:filenames]; } + return YES; } diff --git a/src/MacVim/Miscellaneous.h b/src/MacVim/Miscellaneous.h index 3a75753837..b9a1816d09 100644 --- a/src/MacVim/Miscellaneous.h +++ b/src/MacVim/Miscellaneous.h @@ -169,8 +169,11 @@ NSView *showHiddenFilesView(); NSString *normalizeFilename(NSString *filename); NSArray *normalizeFilenames(NSArray *filenames); - BOOL shouldUseYosemiteTabBarStyle(); BOOL shouldUseMojaveTabBarStyle(); int getCurrentAppearance(NSAppearance *appearance); + +// Pasteboard helpers +NSPasteboardType getPasteboardFilenamesType(); +NSArray* extractPasteboardFilenames(NSPasteboard *pboard); diff --git a/src/MacVim/Miscellaneous.m b/src/MacVim/Miscellaneous.m index 98a0aad1ea..2b1bddee5e 100644 --- a/src/MacVim/Miscellaneous.m +++ b/src/MacVim/Miscellaneous.m @@ -350,3 +350,54 @@ getCurrentAppearance(NSAppearance *appearance){ #endif return flag; } + +/// Returns the pasteboard type to use for retrieving file names from a list of +/// files. +/// @return The pasteboard type that can be passed to NSPasteboard for registration. +NSPasteboardType getPasteboardFilenamesType() +{ +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_13 + return NSPasteboardTypeFileURL; +#else + return NSFilenamesPboardType; +#endif +} + +/// Extract the list of file names from a pasteboard. +NSArray* extractPasteboardFilenames(NSPasteboard *pboard) +{ + // NSPasteboardTypeFileURL is only available in 10.13, and + // NSFilenamesPboardType was deprecated soon after that (10.14). + + // As such if we are building with min deployed OS 10.13, we need to use + // the new method (using NSPasteboardTypeFileURL / + // readObjectsForClasses:options:) because otherwise we will get + // deprecation warnings. Otherwise, we just use NSFilenamesPboardType. It + // will still work if run in a newer OS since it's simply deprecated, and + // the OS still supports it. +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_13 + if (![pboard.types containsObject:NSPasteboardTypeFileURL]) { + ASLogNotice(@"Pasteboard contains no NSPasteboardTypeFileURL"); + return nil; + } + NSArray *fileurls = [pboard readObjectsForClasses:@[NSURL.class] + options:@{NSPasteboardURLReadingFileURLsOnlyKey: [NSNumber numberWithBool:YES]}]; + if (fileurls == nil || fileurls.count == 0) { + return nil; + } + NSMutableArray *filenames = [NSMutableArray arrayWithCapacity:fileurls.count]; + for (int i = 0; i < fileurls.count; i++) { + [filenames addObject:fileurls[i].path]; + } + return filenames; +#else + if (![pboard.types containsObject:NSFilenamesPboardType]) { + ASLogNotice(@"Pasteboard contains no NSFilenamesPboardType"); + return nil; + } + + NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType]; + return filenames; +#endif +} +