While drag and drop belongs into GTK+ itself, I thought it would be better to
cover it after some parts of GNOME were discussed.
A D V E R T I S E M E N T
You have already seen one drop handler back when we were discussing the
mime types. Basically, to accept drops, you have to decide which mime type
of data you want to be able to receive. You have already seen one for "text/uri-list".
Basically your handler will only receive data of those mime types that you
specify, so you only need to know how to decode those.
To specify the mime types you want to receive, you create an array of
GtkTargetEntry structures, where the first element
is a string of mime type, the second is an integer flag and the third is an
integer info. You can leave the flags at 0. The info field can be used if
you have several entries you are accepting, as the info integer will be
passed to your drop handler, so you can create a switch statement to handle
the different types of data. If you have only one type, just leave this at
After this you need to set up the widget for dragging. You do this by
calling the gtk_drag_dest_set function. The first
argument is the widget you want to set up, the second is a flags argument
for setting up which types of default drag behavior to use, you can leave
this at GTK_DEST_DEFAULT_ALL. The next argument is
the array of GtkTargetEntry structures, the next
argument is the number of items in that array. The last argument is the type
of action that you accept. The types can be any of the following ORed
GDK_ACTION_PRIVATE and GDK_ACTION_ASK. The most
useful are GDK_ACTION_COPY and
GDK_ACTION_MOVE. If you are for example passing around strings or other
data, you will most likely use GDK_ACTION_COPY only.
Then you need to set up and bind the drop handler. The drop handler
should have the following prototype:
Now let's look at the source side of DND. You set up the
GtkTargetEntry array, in the same manner as above.
Then instead of the flags argument you substitute a
mask for the start mouse button of the drag. This could be
GDK_BUTTON1_MASK | GDK_BUTTON3_MASK for 1st and 3rd
mouse buttons. Then you need to bind the drag_data_get
signal that will send the data for the drag on it's way, and
drag_data_delete if the action is
GDK_ACTION_MOVE, to delete the data since the move
was successful. Here's a simple example that will work with the above code
snippet for drop: