Start file dragging from TreeView to another application (not mine)

I am using GTK# on Windows, but since probably very few people are using that language binding of GTK, I would also appreciate doing this in any language you are using.

What I want to do is drag an item that has a file name from my TreeView to another third-party application so that it can open the file. If I use WinForms, this can be done in two lines of code (if the file name is hard-coded, for simplicity) like this:

private void TreeView1_ItemDrag(object sender, ItemDragEventArgs e)
{
	var data = new DataObject(DataFormats.FileDrop, new string[] { @"C:\\Windows\\DirectX.log" });
	treeView1.DoDragDrop(data, DragDropEffects.Copy);
}

With the code above, if I drag a tree node and drop it on Notepad, Notepad opens the file “C:\Windows\DirectX.log”. How to do the same thing with GTK TreeView?

There is a problem here (see below), but this is how it would be done:
Make the treeview a drag source like this (ported to Gtk# but untested):

treeview.EnableModelDragSource(Gdk.ModifierType.Button1Mask, {}, Gdk.DragAction.Copy);
Gtk.Drag.SourceAddUriTargets(treeview);

Also connect to the drag-data-get signal on the treeview. In the handler, get a uri from your model for the selected row (using treeview.Selection.GetSelected()), and set it on the provided Gtk.SelectionData using SetSelectedUris. (Gtk.SelectionData.SetSelectedUris was added in gtk-sharp 2.12.42; you might be able to use SetUris in an older version)

However, the Gtk3 win32 backend has this comment:

 * Currently the conversion from text/uri-list to Shell IDList Array is not
 * implemented, so it's not possible to drag & drop files from GTK+
 * applications to non-GTK+ applications the same way one can drag files
 * from Windows Explorer.

On Windows, Gtk3 only supports the reverse direction; As far as I can tell, Gtk2 supports neither.

That’s a bummer… But thank you for letting me know that, because now I don’t have to try to do it vainly. I could use some dirty workaround like using WinForms just for that, on Windows.

But how about on Linux? Can GTK do that on Linux (file dragging to another application)?


I tried the following code on Linux (both Gnome and KDE). I tried to drag a node to Kate/Gedit (default text editor). The dragging seemed to work (showed a green plus icon), but when I released the mouse, my application crashed (exit code 139: segmentation fault) and the text editor did not get the file.

treeview1.EnableModelDragSource(Gdk.ModifierType.Button1Mask, new TargetEntry[]{}, Gdk.DragAction.Copy);
Gtk.Drag.SourceAddUriTargets(treeview1);


treeview1.DragBegin += (o, args) =>
{
	Debug.WriteLine("DragBegin");
};

treeview1.DragDataGet += (o, args) =>
{
	Debug.WriteLine("Setting file");
	args.SelectionData.SetUris(@"file:///home/test/test.txt");
}; 

The debug output was:

DragBegin
Setting file

What version of gtk-sharp are you using? I noticed that Gtk.SelectionData.SetUris() is documented as taking a string parameter, when it should be string[]. gtk-sharp 2.12.42 fixes this by adding SetSelectedUris, and implementing the former using the latter. I wasn’t sure if there originally was some magic that wrapped the string in an array, but it seems not.

It seems to be GtkSharp 3.22.24 in the NuGet. It did not seem to have SetSelectedUris, so I had to use SetUris instead.

This seems to be the source code of the SelectionData class on GitHub, but strangely, I cannot find the methods. The class is marked as partial class, but I could not find any other parts of the class.

According to a decompiler, the method is defined like this:

public bool SetUris(string uris)
{
  return SelectionData.gtk_selection_data_set_uris(this.Handle, Marshaller.StringToPtrGStrdup(uris));
}

Ah, that is a fork that adds support for GTK 3. I assumed you were using the original version (mono/gtk-sharp) that is stuck on GTK 2. mono/gtk-sharp has seen some development in its gtk-sharp-2-12-branch branch that isn’t in master, and therefore seems to have not made it to the fork.

gtk-sharp appears to use a code scanner that outputs xml (GtkSharp-api.xml), which is used along with GtkSharp.metadata and the manual overrides to generate the bindings.

The fix in mono/gtk-sharp is mainly: https://github.com/mono/gtk-sharp/commit/c9308e5374c3d5c08936433fd01248b12790608e and https://github.com/mono/gtk-sharp/commit/ff2bd1c5c59005ba88e9484ba65c4cbcade0d60e which prevents the api break.

You can open an issue on GtkSharp/GtkSharp to have it fixed there too.

Thanks. Microsoft’s official .NET Core project templates use that forked edition, probably because the Mono edition is old and does not support .NET Core.

I guess I have to report this to the project Issues.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.