New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add `webContents.startDrag(item)` API #6333

Merged
merged 8 commits into from Jul 4, 2016

Conversation

Projects
None yet
6 participants
@zcbenz
Contributor

zcbenz commented Jul 3, 2016

Close #4622.

Dragging files out of the window

For certain kinds of apps that manipulate on files, it is important to be able
to drag files from Electron to other apps. To implement this feature in your
app, you need to call webContents.startDrag(item) API on ondragstart event.

In web page:

<a href="#" id="drag">item</a>
<script type="text/javascript" charset="utf-8">
  document.getElementById('drag').ondragstart = (event) => {
    event.preventDefault()
    ipcRenderer.send('ondragstart', '/path/to/item')
  }
</script>

In the main process:

ipcMain.on('ondragstart', (event, filePath) => {
  event.sender.startDrag({
    file: filePath,
    icon: '/path/to/icon.png'
  })
})
@bpasero

This comment has been minimized.

Contributor

bpasero commented Jul 3, 2016

Nice! Some questions:

  • I assume this solution does not prevent the normal HTML DND with dataTransfer to support DND inside the window?
  • when I use this mechanism and drop to another Electron window, will I be able to read the dragged files in the same way I can do it today (e.g. when someone drags a file from the desktop onto the window)?
  • how would this support DND of multiple files?
@zcbenz

This comment has been minimized.

Contributor

zcbenz commented Jul 3, 2016

I assume this solution does not prevent the normal HTML DND with dataTransfer to support DND inside the window?

No, this API just adds the file to current drag data, it doesn't remove existing data. So usually you need to call event.preventDefault() to prevent the default DND of DOM.

when I use this mechanism and drop to another Electron window, will I be able to read the dragged files in the same way I can do it today (e.g. when someone drags a file from the desktop onto the window)?

It should be exactly the same.

how would this support DND of multiple files?

I actually added the support, but somehow it doesn't work on Windows. The code path was never ran in Chromium, so I guess this is a bug of Chromium's dragging code.

You can try with startDrag({files: ['file1', 'file2']}).

@mattetti

This comment has been minimized.

mattetti commented Jul 3, 2016

Thanks @zcbenz that's exactly what I needed. I'll build Electron using your PR and run a few tests.The API is very straightforward and the doc very clear. Based on the fact that Chrome's downloads DnD to apps work, I don't see why this wouldn't.

Super exciting!

@zcbenz zcbenz merged commit 83ae14f into master Jul 4, 2016

8 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
electron-linux-arm Build #3586125 succeeded in 47s
Details
electron-linux-ia32 Build #3586126 succeeded in 41s
Details
electron-linux-x64 Build #3586127 succeeded in 127s
Details
electron-mas-x64 Build #1770 succeeded in 6 min 15 sec
Details
electron-osx-x64 Build #1779 succeeded in 6 min 32 sec
Details
electron-win-ia32 Build #784 succeeded in 6 min 18 sec
Details
electron-win-x64 Build #771 succeeded in 6 min 9 sec
Details

@zcbenz zcbenz deleted the drag-item branch Jul 4, 2016

@mattetti

This comment has been minimized.

mattetti commented Jul 4, 2016

Confirmed working well on macOS. Thanks @zcbenz

@quicksnap

This comment has been minimized.

Contributor

quicksnap commented Jul 5, 2016

@zcbenz Thank you so much for taking the time to implement this feature! We really appreciate it. Our organization created the chromium hack that this feature mostly obviates.

What kind of effort is involved in fixing drag-out for multiple files? Unfortunately, I believe I'll personally have a hard time tracking down, filing and/or fixing the bug in Chromium myself. But it still remains a requirement for our needs.

I'd love to get off our fork--your code is much nicer =) Can I help in any way at least to file a Chromium bug?

@quicksnap

This comment has been minimized.

Contributor

quicksnap commented Jul 5, 2016

Also, we have code that works in windows for multiple files, but it does so directly with Windows API and file paths. Not ideal to introduce to Electron, I imagine.

@zcbenz

This comment has been minimized.

Contributor

zcbenz commented Jul 6, 2016

@quicksnap Under the hood the API is calling into OSExchangeDataProviderWin::SetFilenames:
https://cs.chromium.org/chromium/src/ui/base/dragdrop/os_exchange_data_provider_win.cc?sq=package:chromium&dr=Ss

Chromium itself only uses SetFilename, so we are calling an untested code path.

@docmars

This comment has been minimized.

docmars commented Aug 17, 2016

This is fantastic! Thanks for implementing this.

Is there any chance in supporting DOM nodes for use in place of the drag icon image? The Drag & Drop API in browsers support passing a node in the img parameter with event.dataTransfer.setDragImage(img, xOffset, yOffset), which is really handy for building custom ghost images.

For instance, say you're making a presentation app and you want to drag a slide out into Finder/Explorer or another app. Using the node for the slide to represent the drag image would make the most sense. Let's say I'm dragging multiple slides. I would want to add a number counter to my drag image. This could all be done with just a few styled elements.

If there's already a way to do this that I'm missing, I'd be very interested!

@hems

This comment has been minimized.

hems commented Oct 12, 2017

@docmars 's suggestion is pretty cool! i would also be curious how to make it work with a list of files instead of a single file, is it possible somehow?

@tborychowski tborychowski referenced this pull request Dec 29, 2017

Open

Drag & Drop #3

0 of 3 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment