<AWT Dev> 4808793: Allow initiation of drags without local data

Damjan Jovanovic damjan.jov at gmail.com
Mon Dec 7 10:36:29 PST 2009

On Mon, Dec 7, 2009 at 6:16 PM, Denis S. Fokin <Denis.Fokin at sun.com> wrote:
> Hi Damjan,

Hello again Denis :-)

> just to make things easer.
> From the CR description I see that the submitter requests a couple of
> things.
> - to create a Transferable on the fly (it is possible right now)
> - to publish a Transferable as a native stream (it seems as a pretty
> independent task)

Transfer data, not Transferable.

> - to add a callback function to notify the source application that the drop
> operation has succeeded and that the promised DataFlavor must now be
> produced

That's more of a possible mechanism than a policy.

> It seems, that the last item could be implemented as a XdndActionAsk action
> from XDnD protocol.
> Do you agree that this request could be divided in these three parts?

Not exactly.

Maybe an example is best. I'm attaching some drop-side sample code and
a patch I've written that gets the XDS (X11 direct save) protocol

Basically in XDS the drop target first tells the drag source where to
save the files using a window property, and requesting the
XdndDirectSave0 format's data from the XSelection only starts the
transfer and returns the result. So I've had to abstract it so that
getting the Transferable's transfer data doesn't actually fetch the
data from the drag source yet, but instead returns an object on which
setting the save location causes the drag source's window property to
be set and only then we request the data, causing the files to be
written and the status reported. The other direction - when Java is
the drag source - is equally fun: we have to save files and update
window properties during the Transferable conversion and only return
the result as the actual transfer data.

As usual, Windows has to be radically different, so sadly I expect the
majority of this patch will end up dedicated to IStream <->
j.i.InputStream interop, VARIANTs with workarounds for Windows
Explorer bugs, and other COM escapades. I've also chosen specific
forms of transfer data so they will be able to work on Windows too.

So far I've used Nautilus to test with as the drop target, and File
Roller as the drag source. The patch works well against them.

> Thank you,
>        Denis.

Thank you

> Damjan Jovanovic wrote:
>> Hi
>> Is anybody working on this bug
>> (http://bugs.sun.com/view_bug.do?bug_id=4808793)?
>> If not I'd like to have a go at it. My idea is described below.
>> java.awt.datatransfer.DataFlavor.javaFileListFlavor has drop target
>> pull semantics, with the drop target being responsible for the
>> operation on the files. It needs the files to already exist. It's
>> essentially a "take these files and use them" action. For example, if
>> you drag files into a Java SVN client, the SVN client could check them
>> in. These semantics work when the drop target is not the local
>> filesystem.
>> But these semantics are exactly the opposite of what's needed when the
>> files in the drag source are not actual files from the local
>> filesystem - for example they are files in an FTP server or even
>> virtual files that don't exist yet. For this we need drag source push
>> semantics, with the drop target either telling the drag source where
>> to save the files, or using some sort of protocol to move the file
>> contents from the drag source to wherever they are to be saved or
>> used.
>> Windows, X11 and MacOS all support this latter option, and while it is
>> a less commonly used file drag scenario, some important applications
>> require it (eg. Microsoft Outlook) and others support it among other
>> possible formats (eg. Windows Explorer, GIMP, File Roller). The bug
>> has been open since early 2003 and has 60 votes; the drag from
>> Microsoft Outlook to Java bug
>> (http://bugs.sun.com/view_bug.do?bug_id=6242241) which relies on this
>> bug has another 20 votes.
>> this. Basically files are presented using their contents, in the form
>> of IStream, IStorage or HGLOBAL, with additional data describing the
>> file name and properties
>> (http://msdn.microsoft.com/en-us/library/bb776902(VS.85).aspx).
>> OS X has "promise data flavors"
>> (http://developer.apple.com/documentation/Carbon/Reference/Pasteboard_Reference/Reference/reference.html).
>> The drag source supplies a promise instead of data, and a callback
>> that's invoked to supply the data. When the callback is called, it can
>> get a URL where the files should be saved.
>> X11 has the X direct save protocol
>> (http://www.freedesktop.org/wiki/Specifications/XDS), which seems to
>> be a mixture of the Windows and OS X ways. The emphasis in the
>> protocol is on saving a file, rather than transferring a list of
>> files. First the drop target gives the drag source a URL where to save
>> the file(s), just like OS X would. If the drag source cannot access
>> that URL or doesn't have permission, it reports this to the drop
>> target, and the drop target then falls back to requesting the file
>> contents as application/octet-stream - similar to the Windows way, but
>> it only works for one file.
>> Obviously there are big differences on these platforms that AWT has to
>> unify. Here is a proposal of how.
>> Drop target
>> We add a new DataFlavor, called FileDropReferralFlavor. When the drop
>> target asks for this flavor, it gets back an object called
>> FileDropReferral, and must call a "public void setFileDropLocation(URL
>> location)" method to tell the drag source where it should save the
>> files. The file transfer proceeds asynchronously, and potentially
>> within the JVM (ie. the application shouldn't exit if it has
>> outstanding transfers). After the transfer is complete, some event to
>> that effect is sent to the drop application's EDT, maybe to a listener
>> registered with the FileDropReferral.
>> Drag source
>> The drag source uses a different DataFlavor to provide its files as
>> streams, say AsyncFileStreamsFlavor. After the drop it provides an
>> enumeration that can be used to lazy open InputStream objects, and
>> some kind of header at least naming each stream.
>> Implementation:
>> On all platforms, when Java is the drag source it spawns a separate
>> thread where possible, and writes the streams into the drop target or
>> URL. When Java is the drop target, on Windows, it spawns a separate
>> thread where possible and reads in the streams and saves them to the
>> target URL that the drop target set, while on X11 and MacOS it just
>> provides the target URL to the drag source and lets the drag source do
>> the saving.
>> These interfaces are unintuitive, asymmetric and ugly. But then again
>> desktops in different operating systems have given file transfers
>> little real thought so there isn't much better we can do now, and it's
>> still vastly uglier to do these in native code (using COM or low-level
>> X11 - yuck!) than in Java. Also this is an advanced DataFlavor, which
>> should be used by a minority of applications, and only in special
>> cases where javaFileListFlavor doesn't fit.
>> Finally, GTK+ still doesn't even have an API for this, SWT is
>> struggling and only works on Windows, and even Microsoft's .NET
>> doesn't support this
>> (http://www.pcreview.co.uk/forums/thread-1854594.php) so this is a
>> real opportunity for Java+AWT/Swing to be a shining example and lead
>> the way.
>> Any thoughts before I start hacking?
>> Regards
>> Damjan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 4808793-1.patch
Type: text/x-patch
Size: 23621 bytes
Desc: not available
Url : http://mail.openjdk.java.net/pipermail/awt-dev/attachments/20091207/165db9ed/4808793-1.patch 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Drop.java
Type: text/x-java
Size: 1567 bytes
Desc: not available
Url : http://mail.openjdk.java.net/pipermail/awt-dev/attachments/20091207/165db9ed/Drop.java 

More information about the awt-dev mailing list