It is often useful to add drag & drop functionality in GUI applications. It allows the user to transfer data from other applications and to manipulate UI objects within the same application.
It is pretty simple to add drag and drop functionality in a Vala program. The following code creates a GTK3 window. Dragging files from a file manager (like Nautilus) and dropping the files on the window will display the file names in a TreeView widget. We'll look at the code first and then go through the details.
Save the following code as dragdrop.vala:
Image may be NSFW.
Clik here to view.![]()
targets is a struct of type Gtk.TargetEntry[]. It specifies the type of objects that can be dropped on the window.
After setting the drop-target, we need to create a function which will handle the drag-drop event. The following code connects the function on_drag_data_received to the drag_data_received window event.
Once we get the file path we are adding it to the tree view by calling the function add_file().
It is pretty simple to add drag and drop functionality in a Vala program. The following code creates a GTK3 window. Dragging files from a file manager (like Nautilus) and dropping the files on the window will display the file names in a TreeView widget. We'll look at the code first and then go through the details.
Save the following code as dragdrop.vala:
using Gtk;Compile it:
public class MainWindow : Gtk.Window
{
private Box vboxMain;
private ScrolledWindow swFiles;
private TreeView tvFiles;
private TreeViewColumn colName;
private const Gtk.TargetEntry[] targets = {
{"text/uri-list",0,0}
};
public static int main (string[] args)
{
Gtk.init(ref args);
var window = new MainWindow ();
window.show_all ();
Gtk.main();
return 0;
}
public MainWindow ()
{
this.title = "Drag files on this window";
this.window_position = WindowPosition.CENTER;
this.destroy.connect (Gtk.main_quit);
set_default_size (550, 400);
//vboxMain
vboxMain = new Box (Orientation.VERTICAL, 6);
vboxMain.margin = 6;
add (vboxMain);
//tvFiles
tvFiles = new TreeView();
//swFiles
swFiles = new ScrolledWindow(tvFiles.get_hadjustment (), tvFiles.get_vadjustment ());
swFiles.set_shadow_type (ShadowType.ETCHED_IN);
swFiles.set_size_request (550, 400);
swFiles.add(tvFiles);
vboxMain.add(swFiles);
//colName
colName = new TreeViewColumn();
colName.title ="File";
colName.expand = true;
CellRendererText cellName = new CellRendererText ();
colName.pack_start (cellName, false);
colName.set_attributes(cellName, "text", 0);
tvFiles.append_column(colName);
//inputStore
ListStore store = new ListStore (1, typeof (string));
tvFiles.model = store;
//connect drag drop handlers
Gtk.drag_dest_set (this,Gtk.DestDefaults.ALL, targets, Gdk.DragAction.COPY);
this.drag_data_received.connect(this.on_drag_data_received);
}
private void on_drag_data_received (Gdk.DragContext drag_context, int x, int y,
Gtk.SelectionData data, uint info, uint time)
{
//loop through list of URIs
foreach(string uri in data.get_uris ()){
string file = uri.replace("file://","").replace("file:/","");
file = Uri.unescape_string (file);
//add file to tree view
add_file (file);
}
Gtk.drag_finish (drag_context, true, false, time);
}
private void add_file(string file)
{
TreeIter iter;
ListStore store = (ListStore) tvFiles.model;
store.append (out iter);
store.set (iter, 0, file);
}
}
valac --pkg gtk+-3.0 "dragdrop.vala"Run the executable file:
./dragdropDrag files and directories from Nautilus (or any other file manager) and drop it on the window.
Image may be NSFW.
Clik here to view.

Code Walkthrough
The following code is added to the window constructor. It sets the current window as the drop target:Gtk.drag_dest_set (this, Gtk.DestDefaults.ALL, targets, Gdk.DragAction.COPY);this refers to the current window object which is the drop target.
targets is a struct of type Gtk.TargetEntry[]. It specifies the type of objects that can be dropped on the window.
private const Gtk.TargetEntry[] targets = {The mime-type text/uri-list specifies that the drop-target will accept only files and directories.
{"text/uri-list",0,0}
};
After setting the drop-target, we need to create a function which will handle the drag-drop event. The following code connects the function on_drag_data_received to the drag_data_received window event.
this.drag_data_received.connect(this.on_drag_data_received);The function for handling the event is given below:
private void on_drag_data_received (Gdk.DragContext drag_context, int x, int y,data.get_Uris() retrieves the list of URIs for the the files and directories that were dropped on the window. URIs are strings which contain the file path prefixed with file://. For example, the directory /usr/share/themes will have the URI file:///usr/share/themes. We can remove the prefix file:// to get the file path.
Gtk.SelectionData data, uint info, uint time)
{
//loop through list of URIs
foreach(string uri in data.get_uris ()){
string file = uri.replace("file://","").replace("file:/","");
file = Uri.unescape_string (file);
//add file to tree view
add_file (file);
}
Gtk.drag_finish (drag_context, true, false, time);
}
Once we get the file path we are adding it to the tree view by calling the function add_file().
private void add_file(string file)
{
TreeIter iter;
ListStore store = (ListStore) tvFiles.model;
store.append (out iter);
store.set (iter, 0, file);
}