[Previous] [Contents] [Next]

20. Drag-and-drop (DND)

GTK+ has a high level set of functions for doing inter-process communication via the drag-and-drop system. GTK+ can perform drag-and-drop on top of the low level Xdnd and Motif drag-and-drop protocols.

20.1 Overview

An application capable of GTK+ drag-and-drop first defines and sets up the GTK+ widget(s) for drag-and-drop. Each widget can be a source and/or destination for drag-and-drop. Note that these GTK+ widgets must have an associated X Window, check using GTK_WIDGET_NO_WINDOW(widget)).

Source widgets can send out drag data, thus allowing the user to drag things off of them, while destination widgets can receive drag data. Drag-and-drop destinations can limit who they accept drag data from, e.g. the same application or any application (including itself).

Sending and receiving drop data makes use of GTK+ signals. Dropping an item to a destination widget requires both a data request (for the source widget) and data received signal handler (for the target widget). Additional signal handers can be connected if you want to know when a drag begins (at the very instant it starts), to when a drop is made, and when the entire drag-and-drop procedure has ended (successfully or not).

Your application will need to provide data for source widgets when requested, that involves having a drag data request signal handler. For destination widgets they will need a drop data received signal handler.

So a typical drag-and-drop cycle would look as follows:

  1. Drag begins.
  2. Drag data request (when a drop occurs).
  3. Drop data received (may be on same or different application).
  4. Drag data delete (if the drag was a move).
  5. Drag-and-drop procedure done.

There are a few minor steps that go in between here and there, but we will get into detail about that later.


20.2 Properties

Drag data has the following properties:

Drag actions are quite obvious, they specify if the widget can drag with the specified action(s), e.g. GDK_ACTION_COPY and/or GDK_ACTION_MOVE. A GDK_ACTION_COPY would be a typical drag-and-drop without the source data being deleted while GDK_ACTION_MOVE would be just like GDK_ACTION_COPY but the source data will be 'suggested' to be deleted after the received signal handler is called. There are additional drag actions including GDK_ACTION_LINK which you may want to look into when you get to more advanced levels of drag-and-drop.

The client specified arbitrary drag-and-drop type is much more flexible, because your application will be defining and checking for that specifically. You will need to set up your destination widgets to receive certain drag-and-drop types by specifying a name and/or number. It would be more reliable to use a name since another application may just happen to use the same number for an entirely different meaning.

Sent and received data format types (selection target) come into play only in your request and received data handler functions. The term selection target is somewhat misleading. It is a term adapted from GTK+ selection (cut/copy and paste). What selection target actually means is the data's format type (i.e. GdkAtom, integer, or string) that being sent or received. Your request data handler function needs to specify the type (selection target) of data that it sends out and your received data handler needs to handle the type (selection target) of data received.


20.3 Functions

20.3.1 Setting up the source widget

The procedure gtk_drag_source_set() specifies a set of target types for a drag operation on a widget.

procedure gtk_drag_source_set (widget : PGtkWidget;
                               start_button_mask: GdkModifierType;
                               targets : PGtkTargetEntry;
                               n_targets : gint;
                               actions : GdkDragAction);

The parameters signify the following:

The targets parameter is an array of the following structure:

type
   TGtkTargetEntry = record
                        target : pgchart;
                        flags : guint;
                        info : guint;
                     end;

The fields specify a string representing the drag type, optional flags and application assigned integer identifier.

If a widget is no longer required to act as a source for drag-and-drop operations, the procedure gtk_drag_source_unset() can be used to remove a set of drag-and-drop target types.

procedure gtk_drag_source_unset (widget : PGtkWidget);

20.3.2 Signals on the source widget

The source widget is sent the following signals during a drag-and-drop operation.

Table 1. Source widget signals

drag_begin
procedure (*drag_begin)(widget : PGtkWidget; dc : PGdkDragContext, data : gpointer)
drag_motion
function (*drag_motion)(widget : PGtkWidget; dc : PGdkDragContext; x : gint; y : gint;
                        t : guint; data : gpointer) : gboolean
drag_data_get
procedure (*drag_data_get)(widget : PGtkWidget; dc : PGdkDragContext;
                           selection_data : PGtkSelectionData; info : guint;
                           t : guint; data : gpointer)
drag_data_delete
procedure (*drag_data_delete)(widget : PGtkWidget; dc : PGdkDragContext; data : gpointer)
drag_drop
function (*drag_drop)(widget : PGtkWidget; dc : PGdkDragContext; x : gint; y : gint;
                      t : guint; data : gpointer) : gboolean
drag_end
procedure (*drag_end)(widget : PGtkWidget; dc : PGdkDragContext; data : gpointer)

20.3.3 Setting up a destination widget

gtk_drag_dest_set() specifies that this widget can receive drops and specifies what types of drops it can receive.

gtk_drag_dest_unset() specifies that the widget can no longer receive drops.

procedure gtk_drag_dest_set (widget : PGtkWidget;
                             flags : GtkDestDefaults;
                             targets : PGtkTargetEntry;
                             n_targets : gint;
                             actions : GdkDragAction);

procedure gtk_drag_dest_unset (widget : PGtkWidget);

20.3.4 Signals on the destination widget

The destination widget is sent the following signals during a drag-and-drop operation.

Table 2. Destination widget signals

drag_data_received
procedure (*drag_data_received)(widget : PGtkWidget; dc : PGdkDragContext;
                                x : gint; y : gint; selection_data : PGtkSelectionData;
                                info : guint; t : guint; data : gpointer)

[Previous] [Contents] [Next]