From fa468a529be9e210170f251aff21ba7e97aca73b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 3 Jul 2016 13:58:31 +0900 Subject: [PATCH] Support dragging multiple files --- atom/browser/api/atom_api_web_contents.cc | 29 ++++++++++++++++++++--- atom/browser/api/atom_api_web_contents.h | 4 +--- atom/browser/ui/drag_util.h | 8 ++++--- atom/browser/ui/drag_util_mac.mm | 16 +++++++------ 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 370cac33fcb3..7b710e5f85a8 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1206,11 +1206,34 @@ void WebContents::EndFrameSubscription() { view->EndFrameSubscription(); } -void WebContents::StartDrag(const base::FilePath& file, - mate::Handle image) { +void WebContents::StartDrag(const mate::Dictionary& item, + mate::Arguments* args) { base::MessageLoop::ScopedNestableTaskAllower allow( base::MessageLoop::current()); - DragItem(file, image->image(), web_contents()->GetNativeView()); + + base::FilePath file; + std::vector files; + if (!item.Get("files", &files) && item.Get("file", &file)) { + files.push_back(file); + } + + mate::Handle icon; + if (!item.Get("icon", &icon) && !file.empty()) { + // TODO(zcbenz): Set default icon from file. + } + + // Error checking. + if (icon.IsEmpty()) { + args->ThrowError("icon must be set"); + return; + } + + // Start dragging. + if (!files.empty()) { + DragFileItems(files, icon->image(), web_contents()->GetNativeView()); + } else { + args->ThrowError("There is nothing to drag"); + } } void WebContents::OnCursorChange(const content::WebCursor& cursor) { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 88eec80d3370..2917aa860a81 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -39,8 +39,6 @@ class WebViewGuestDelegate; namespace api { -class NativeImage; - class WebContents : public mate::TrackableObject, public CommonWebContentsDelegate, public content::WebContentsObserver { @@ -145,7 +143,7 @@ class WebContents : public mate::TrackableObject, void EndFrameSubscription(); // Dragging native items. - void StartDrag(const base::FilePath& file, mate::Handle image); + void StartDrag(const mate::Dictionary& item, mate::Arguments* args); // Methods for creating . void SetSize(const SetSizeParams& params); diff --git a/atom/browser/ui/drag_util.h b/atom/browser/ui/drag_util.h index 50f87c4d6339..df5303c65e45 100644 --- a/atom/browser/ui/drag_util.h +++ b/atom/browser/ui/drag_util.h @@ -5,6 +5,8 @@ #ifndef ATOM_BROWSER_UI_DRAG_UTIL_H_ #define ATOM_BROWSER_UI_DRAG_UTIL_H_ +#include + #include "ui/gfx/image/image.h" namespace base { @@ -13,9 +15,9 @@ class FilePath; namespace atom { -void DragItem(const base::FilePath& path, - const gfx::Image& icon, - gfx::NativeView view); +void DragFileItems(const std::vector& files, + const gfx::Image& icon, + gfx::NativeView view); } // namespace atom diff --git a/atom/browser/ui/drag_util_mac.mm b/atom/browser/ui/drag_util_mac.mm index fe4254b43cbe..7197e79af68c 100644 --- a/atom/browser/ui/drag_util_mac.mm +++ b/atom/browser/ui/drag_util_mac.mm @@ -13,9 +13,11 @@ namespace atom { namespace { // Write information about the file being dragged to the pasteboard. -void AddFileToPasteboard(NSPasteboard* pasteboard, const base::FilePath& path) { - NSString* file = base::SysUTF8ToNSString(path.value()); - NSArray* fileList = [NSArray arrayWithObject:file]; +void AddFilesToPasteboard(NSPasteboard* pasteboard, + const std::vector& files) { + NSMutableArray* fileList = [NSMutableArray array]; + for (const base::FilePath& file : files) + [fileList addObject:base::SysUTF8ToNSString(file.value())]; [pasteboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil]; [pasteboard setPropertyList:fileList forType:NSFilenamesPboardType]; @@ -23,11 +25,11 @@ void AddFileToPasteboard(NSPasteboard* pasteboard, const base::FilePath& path) { } // namespace -void DragItem(const base::FilePath& path, - const gfx::Image& icon, - gfx::NativeView view) { +void DragFileItems(const std::vector& files, + const gfx::Image& icon, + gfx::NativeView view) { NSPasteboard* pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard]; - AddFileToPasteboard(pasteboard, path); + AddFilesToPasteboard(pasteboard, files); // Synthesize a drag event, since we don't have access to the actual event // that initiated a drag (possibly consumed by the Web UI, for example).