[gtk/wip/otte/dnd: 6/8] dnd: Port the TreeModel machinery to GValue DND



commit c457e0813bb64623b9f97c970b69db0975d867b3
Author: Benjamin Otte <otte redhat com>
Date:   Tue Feb 18 01:41:42 2020 +0100

    dnd: Port the TreeModel machinery to GValue DND

 demos/icon-browser/iconstore.c       |  12 ++--
 docs/reference/gtk/gtk4-sections.txt |   4 +-
 gtk/gtkfilesystemmodel.c             |  15 ++--
 gtk/gtkiconview.c                    | 113 ++++++++++++-----------------
 gtk/gtkliststore.c                   |  41 ++++-------
 gtk/gtktreednd.c                     | 112 ++++++++++++++---------------
 gtk/gtktreednd.h                     |  38 ++++++----
 gtk/gtktreemodelfilter.c             |  19 +++--
 gtk/gtktreemodelsort.c               |  15 ++--
 gtk/gtktreestore.c                   |  45 +++++-------
 gtk/gtktreeview.c                    | 133 ++++++++++++++---------------------
 tests/testiconview.c                 |   6 +-
 tests/testkineticscrolling.c         |   7 +-
 tests/testtreecolumns.c              |  38 ++++------
 tests/testtreednd.c                  |  39 +++++-----
 tests/testtreeview.c                 |   6 +-
 16 files changed, 267 insertions(+), 376 deletions(-)
---
diff --git a/demos/icon-browser/iconstore.c b/demos/icon-browser/iconstore.c
index b43691ffa2..97d7018ffa 100644
--- a/demos/icon-browser/iconstore.c
+++ b/demos/icon-browser/iconstore.c
@@ -53,26 +53,26 @@ drag_data_delete (GtkTreeDragSource *drag_source,
   return FALSE;
 }
 
-static gboolean
+static GdkContentProvider *
 drag_data_get (GtkTreeDragSource *drag_source,
-               GtkTreePath       *path,
-               GtkSelectionData  *selection)
+               GtkTreePath       *path)
 {
+  GdkContentProvider *content;
   GtkTreeIter iter;
   gchar *text;
 
   if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), &iter, path))
-    return FALSE;
+    return NULL;
 
   gtk_tree_model_get (GTK_TREE_MODEL (drag_source), &iter,
                       ICON_STORE (drag_source)->text_column, &text,
                       -1);
 
-  gtk_selection_data_set_text (selection, text, -1);
+  content = gdk_content_provider_new_typed (G_TYPE_STRING, text);
 
   g_free (text);
 
-  return TRUE;
+  return content;
 }
 
 
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index a7b1be5e5e..f0b4e577d7 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -3271,7 +3271,8 @@ GtkTreeDragDest
 GtkTreeDragDestIface
 gtk_tree_drag_dest_drag_data_received
 gtk_tree_drag_dest_row_drop_possible
-gtk_tree_set_row_drag_data
+GTK_TYPE_TREE_ROW_DATA
+gtk_tree_create_row_drag_content
 gtk_tree_get_row_drag_data
 <SUBSECTION Standard>
 GTK_TYPE_TREE_DRAG_DEST
@@ -3283,6 +3284,7 @@ GTK_IS_TREE_DRAG_SOURCE
 GTK_TYPE_TREE_DRAG_SOURCE
 GTK_TREE_DRAG_SOURCE_GET_IFACE
 <SUBSECTION Private>
+gtk_tree_row_data_get_type
 gtk_tree_drag_source_get_type
 gtk_tree_drag_dest_get_type
 </SECTION>
diff --git a/gtk/gtkfilesystemmodel.c b/gtk/gtkfilesystemmodel.c
index bf49e0196b..8f382b8a3d 100644
--- a/gtk/gtkfilesystemmodel.c
+++ b/gtk/gtkfilesystemmodel.c
@@ -965,29 +965,22 @@ drag_source_row_draggable (GtkTreeDragSource *drag_source,
   return ITER_INDEX (&iter) != 0;
 }
 
-static gboolean
+static GdkContentProvider *
 drag_source_drag_data_get (GtkTreeDragSource *drag_source,
-                          GtkTreePath       *path,
-                          GtkSelectionData  *selection_data)
+                          GtkTreePath       *path)
 {
   GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (drag_source);
   FileModelNode *node;
   GtkTreeIter iter;
-  char *uris[2]; 
 
   if (!gtk_file_system_model_get_iter (GTK_TREE_MODEL (model), &iter, path))
-    return FALSE;
+    return NULL;
 
   node = get_node (model, ITER_INDEX (&iter));
   if (node->file == NULL)
     return FALSE;
 
-  uris[0] = g_file_get_uri (node->file);
-  uris[1] = NULL;
-  gtk_selection_data_set_uris (selection_data, uris);
-  g_free (uris[0]);
-
-  return TRUE;
+  return gdk_content_provider_new_typed (G_TYPE_FILE, node->file);
 }
 
 static void
diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c
index 10b86fa642..55cf780542 100644
--- a/gtk/gtkiconview.c
+++ b/gtk/gtkiconview.c
@@ -50,7 +50,6 @@
 #include "gtkdragsource.h"
 #include "gtkdragdest.h"
 #include "gtkdragicon.h"
-#include "gtkselectionprivate.h"
 #include "gtknative.h"
 
 #include "a11y/gtkiconviewaccessibleprivate.h"
@@ -285,8 +284,8 @@ static void                 update_pixbuf_cell                           (GtkIco
 /* Source side drag signals */
 static void     gtk_icon_view_dnd_finished_cb   (GdkDrag         *drag,
                                                  GtkWidget       *widget);
-static GBytes * gtk_icon_view_drag_data_get     (const char      *mime_type,
-                                                 gpointer         data);
+static GdkContentProvider * gtk_icon_view_drag_data_get                  (GtkIconView            *icon_view,
+                                                                          GtkTreePath            
*source_row);
 
 /* Target side drag signals */
 static void     gtk_icon_view_drag_leave         (GtkDropTarget    *dest,
@@ -5861,19 +5860,20 @@ set_destination (GtkIconView    *icon_view,
                 gint            x,
                 gint            y,
                 GdkDragAction  *suggested_action,
-                GdkAtom        *target)
+                GType          *target)
 {
   GtkWidget *widget;
   GtkTreePath *path = NULL;
   GtkIconViewDropPosition pos;
   GtkIconViewDropPosition old_pos;
   GtkTreePath *old_dest_path = NULL;
+  GdkContentFormats *formats;
   gboolean can_drop = FALSE;
 
   widget = GTK_WIDGET (icon_view);
 
   *suggested_action = 0;
-  *target = NULL;
+  *target = G_TYPE_INVALID;
 
   if (!icon_view->priv->dest_set)
     {
@@ -5890,8 +5890,9 @@ set_destination (GtkIconView    *icon_view,
       return FALSE; /* no longer a drop site */
     }
 
-  *target = gtk_drop_target_find_mimetype (dest);
-  if (*target == NULL)
+  formats = gtk_drop_target_get_formats (dest);
+  *target = gdk_content_formats_match_gtype (formats, formats);
+  if (*target == G_TYPE_INVALID)
     return FALSE;
 
   if (!gtk_icon_view_get_dest_item_at_pos (icon_view, x, y, &path, &pos)) 
@@ -6053,10 +6054,9 @@ gtk_icon_view_maybe_begin_drag (GtkIconView *icon_view,
 
   surface = gtk_native_get_surface (gtk_widget_get_native (GTK_WIDGET (icon_view)));
 
-  content = gdk_content_provider_new_with_formats (icon_view->priv->source_formats,
-                                                   gtk_icon_view_drag_data_get,
-                                                   icon_view,
-                                                   NULL);
+  content = gtk_icon_view_drag_data_get (icon_view, path);
+  if (content == NULL)
+    goto out;
 
   drag = gdk_drag_begin (surface,
                          device,
@@ -6090,16 +6090,12 @@ gtk_icon_view_maybe_begin_drag (GtkIconView *icon_view,
 }
 
 /* Source side drag signals */
-static GBytes *
-gtk_icon_view_drag_data_get (const char *mime_type,
-                             gpointer    data)
+static GdkContentProvider *
+gtk_icon_view_drag_data_get (GtkIconView *icon_view,
+                             GtkTreePath *source_row)
 {
-  GtkIconView *icon_view = data;
+  GdkContentProvider *content;
   GtkTreeModel *model;
-  GtkTreePath *source_row;
-  GtkSelectionData sdata = { 0, };
-
-  sdata.target = g_intern_string (mime_type);
 
   model = gtk_icon_view_get_model (icon_view);
 
@@ -6109,28 +6105,21 @@ gtk_icon_view_drag_data_get (const char *mime_type,
   if (!icon_view->priv->source_set)
     return NULL;
 
-  source_row = gtk_tree_row_reference_get_path (icon_view->priv->source_item);
-  if (source_row == NULL)
-    return NULL;
-
   /* We can implement the GTK_TREE_MODEL_ROW target generically for
    * any model; for DragSource models there are some other formats
    * we also support.
    */
 
-  if (GTK_IS_TREE_DRAG_SOURCE (model) &&
-      gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (model), source_row, &sdata))
-    goto done;
+  if (GTK_IS_TREE_DRAG_SOURCE (model))
+    content = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (model), source_row);
+  else
+    content = NULL;
 
   /* If drag_data_get does nothing, try providing row data. */
-  if (gtk_selection_data_get_target (&sdata) == g_intern_static_string ("GTK_TREE_MODEL_ROW"))
-    gtk_tree_set_row_drag_data (&sdata, model, source_row);
+  if (content == NULL)
+    content = gtk_tree_create_row_drag_content (model, source_row);
 
- done:
-  gtk_tree_path_free (source_row);
-
-  return g_bytes_new_take ((gpointer)gtk_selection_data_get_data (&sdata),
-                           gtk_selection_data_get_length (&sdata));
+  return content;
 }
 
 static void 
@@ -6189,7 +6178,7 @@ gtk_icon_view_drag_motion (GtkDropTarget *dest,
   GtkTreePath *path = NULL;
   GtkIconViewDropPosition pos;
   GdkDragAction suggested_action = 0;
-  GdkAtom target;
+  GType target;
   gboolean empty;
 
   if (!set_destination (icon_view, dest, x, y, &suggested_action, &target))
@@ -6216,13 +6205,13 @@ gtk_icon_view_drag_motion (GtkDropTarget *dest,
          g_source_set_name_by_id (icon_view->priv->scroll_timeout_id, "[gtk] drag_scroll_timeout");
        }
 
-      if (target == g_intern_static_string ("GTK_TREE_MODEL_ROW"))
+      if (target == GTK_TYPE_TREE_ROW_DATA)
         {
           /* Request data so we can use the source row when
            * determining whether to accept the drop
            */
           set_status_pending (drop, suggested_action);
-          gtk_drop_target_read_selection (dest, target, NULL, gtk_icon_view_drag_data_received, icon_view);
+          gdk_drop_read_value_async (drop, target, G_PRIORITY_DEFAULT, NULL, 
gtk_icon_view_drag_data_received, icon_view);
         }
       else
         {
@@ -6244,7 +6233,7 @@ gtk_icon_view_drag_drop (GtkDropTarget *dest,
 {
   GtkTreePath *path;
   GdkDragAction suggested_action = 0;
-  GdkAtom target = NULL;
+  GType target = G_TYPE_INVALID;
   GtkTreeModel *model;
   gboolean drop_append_mode;
 
@@ -6263,7 +6252,7 @@ gtk_icon_view_drag_drop (GtkDropTarget *dest,
   
   path = get_logical_destination (icon_view, &drop_append_mode);
 
-  if (target != NULL && path != NULL)
+  if (target != G_TYPE_INVALID && path != NULL)
     {
       /* in case a motion had requested drag data, change things so we
        * treat drag data receives as a drop.
@@ -6279,9 +6268,9 @@ gtk_icon_view_drag_drop (GtkDropTarget *dest,
   /* Unset this thing */
   gtk_icon_view_set_drag_dest_item (icon_view, NULL, GTK_ICON_VIEW_DROP_LEFT);
 
-  if (target != NULL)
+  if (target != G_TYPE_INVALID)
     {
-      gtk_drop_target_read_selection (dest, target, NULL, gtk_icon_view_drag_data_received, icon_view);
+      gdk_drop_read_value_async (drop, target, G_PRIORITY_DEFAULT, NULL, gtk_icon_view_drag_data_received, 
icon_view);
       return TRUE;
     }
   else
@@ -6319,27 +6308,26 @@ gtk_icon_view_drag_data_received (GObject *source,
                                   GAsyncResult *result,
                                   gpointer data)
 {
-  GtkDropTarget *dest = GTK_DROP_TARGET (source);
   GtkIconView *icon_view = data;
-  GdkDrop *drop = gtk_drop_target_get_drop (dest);
+  GdkDrop *drop = GDK_DROP (source);
   GtkTreePath *path;
   GtkTreeModel *model;
   GtkTreePath *dest_row;
   GdkDragAction suggested_action;
   gboolean drop_append_mode;
-  GtkSelectionData *selection_data;
+  const GValue *value;
 
-  selection_data = gtk_drop_target_read_selection_finish (dest, result, NULL);
-  if (!selection_data)
+  value = gdk_drop_read_value_finish (drop, result, NULL);
+  if (!value)
     return;
 
   model = gtk_icon_view_get_model (icon_view);
 
   if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_DEST, "drag-data-received"))
-    goto out;
+    return;
 
   if (!icon_view->priv->dest_set)
-    goto out;
+    return;
 
   suggested_action = get_status_pending (drop);
 
@@ -6359,7 +6347,7 @@ gtk_icon_view_drag_data_received (GObject *source,
         {
          if (!gtk_tree_drag_dest_row_drop_possible (GTK_TREE_DRAG_DEST (model),
                                                     path,
-                                                    selection_data))
+                                                    value))
            suggested_action = 0;
         }
 
@@ -6373,25 +6361,22 @@ gtk_icon_view_drag_data_received (GObject *source,
         gtk_icon_view_set_drag_dest_item (icon_view,
                                          NULL,
                                          GTK_ICON_VIEW_DROP_LEFT);
-      goto out;
+      return;
     }
   
 
   dest_row = get_dest_row (drop);
 
   if (dest_row == NULL)
-    goto out;
+    return;
 
-  if (gtk_selection_data_get_length (selection_data) >= 0)
-    {
-      suggested_action = gtk_icon_view_get_action (GTK_WIDGET (icon_view), drop);
+  suggested_action = gtk_icon_view_get_action (GTK_WIDGET (icon_view), drop);
 
-      if (suggested_action &&
-          !gtk_tree_drag_dest_drag_data_received (GTK_TREE_DRAG_DEST (model),
-                                                  dest_row,
-                                                  selection_data))
-        suggested_action = 0;
-    }
+  if (suggested_action &&
+      !gtk_tree_drag_dest_drag_data_received (GTK_TREE_DRAG_DEST (model),
+                                              dest_row,
+                                              value))
+    suggested_action = 0;
 
   gdk_drop_finish (drop, suggested_action);
 
@@ -6399,9 +6384,6 @@ gtk_icon_view_drag_data_received (GObject *source,
 
   /* drop dest_row */
   set_dest_row (drop, NULL, NULL, FALSE, FALSE);
-
-out:
-  gtk_selection_data_free (selection_data);
 }
 
 /* Drag-and-Drop support */
@@ -6736,11 +6718,6 @@ gtk_icon_view_get_reorderable (GtkIconView *icon_view)
   return icon_view->priv->reorderable;
 }
 
-static const char *item_formats[] = {
-  "GTK_TREE_MODEL_ROW" 
-};
-
-
 /**
  * gtk_icon_view_set_reorderable:
  * @icon_view: A #GtkIconView.
@@ -6772,7 +6749,7 @@ gtk_icon_view_set_reorderable (GtkIconView *icon_view,
 
   if (reorderable)
     {
-      GdkContentFormats *formats = gdk_content_formats_new (item_formats, G_N_ELEMENTS (item_formats));
+      GdkContentFormats *formats = gdk_content_formats_new_for_gtype (GTK_TYPE_TREE_ROW_DATA);
       gtk_icon_view_enable_model_drag_source (icon_view,
                                              GDK_BUTTON1_MASK,
                                              formats,
diff --git a/gtk/gtkliststore.c b/gtk/gtkliststore.c
index 4e7ff1164d..8b582fd526 100644
--- a/gtk/gtkliststore.c
+++ b/gtk/gtkliststore.c
@@ -248,15 +248,15 @@ static gboolean real_gtk_list_store_row_draggable (GtkTreeDragSource *drag_sourc
                                                    GtkTreePath       *path);
 static gboolean gtk_list_store_drag_data_delete   (GtkTreeDragSource *drag_source,
                                                    GtkTreePath       *path);
-static gboolean gtk_list_store_drag_data_get      (GtkTreeDragSource *drag_source,
-                                                   GtkTreePath       *path,
-                                                   GtkSelectionData  *selection_data);
+static GdkContentProvider *
+                gtk_list_store_drag_data_get      (GtkTreeDragSource *drag_source,
+                                                   GtkTreePath       *path);
 static gboolean gtk_list_store_drag_data_received (GtkTreeDragDest   *drag_dest,
                                                    GtkTreePath       *dest,
-                                                   GtkSelectionData  *selection_data);
+                                                   const GValue      *value);
 static gboolean gtk_list_store_row_drop_possible  (GtkTreeDragDest   *drag_dest,
                                                    GtkTreePath       *dest_path,
-                                                  GtkSelectionData  *selection_data);
+                                                  const GValue      *value);
 
 
 /* sortable */
@@ -1476,35 +1476,22 @@ gtk_list_store_drag_data_delete (GtkTreeDragSource *drag_source,
   return FALSE;
 }
 
-static gboolean
+static GdkContentProvider *
 gtk_list_store_drag_data_get (GtkTreeDragSource *drag_source,
-                              GtkTreePath       *path,
-                              GtkSelectionData  *selection_data)
+                              GtkTreePath       *path)
 {
   /* Note that we don't need to handle the GTK_TREE_MODEL_ROW
    * target, because the default handler does it for us, but
    * we do anyway for the convenience of someone maybe overriding the
    * default handler.
    */
-
-  if (gtk_tree_set_row_drag_data (selection_data,
-                                 GTK_TREE_MODEL (drag_source),
-                                 path))
-    {
-      return TRUE;
-    }
-  else
-    {
-      /* FIXME handle text targets at least. */
-    }
-
-  return FALSE;
+  return gtk_tree_create_row_drag_content (GTK_TREE_MODEL (drag_source), path);
 }
 
 static gboolean
-gtk_list_store_drag_data_received (GtkTreeDragDest   *drag_dest,
-                                   GtkTreePath       *dest,
-                                   GtkSelectionData  *selection_data)
+gtk_list_store_drag_data_received (GtkTreeDragDest *drag_dest,
+                                   GtkTreePath     *dest,
+                                   const GValue    *value)
 {
   GtkTreeModel *tree_model = GTK_TREE_MODEL (drag_dest);
   GtkListStore *list_store = GTK_LIST_STORE (tree_model);
@@ -1513,7 +1500,7 @@ gtk_list_store_drag_data_received (GtkTreeDragDest   *drag_dest,
   GtkTreePath *src_path = NULL;
   gboolean retval = FALSE;
 
-  if (gtk_tree_get_row_drag_data (selection_data,
+  if (gtk_tree_get_row_drag_data (value,
                                  &src_model,
                                  &src_path) &&
       src_model == tree_model)
@@ -1611,7 +1598,7 @@ gtk_list_store_drag_data_received (GtkTreeDragDest   *drag_dest,
 static gboolean
 gtk_list_store_row_drop_possible (GtkTreeDragDest  *drag_dest,
                                   GtkTreePath      *dest_path,
-                                 GtkSelectionData *selection_data)
+                                  const GValue     *value)
 {
   gint *indices;
   GtkTreeModel *src_model = NULL;
@@ -1622,7 +1609,7 @@ gtk_list_store_row_drop_possible (GtkTreeDragDest  *drag_dest,
   if (GTK_LIST_STORE_IS_SORTED (drag_dest))
     return FALSE;
 
-  if (!gtk_tree_get_row_drag_data (selection_data,
+  if (!gtk_tree_get_row_drag_data (value,
                                   &src_model,
                                   &src_path))
     goto out;
diff --git a/gtk/gtktreednd.c b/gtk/gtktreednd.c
index d0b2ae115c..20ebbfb613 100644
--- a/gtk/gtktreednd.c
+++ b/gtk/gtktreednd.c
@@ -43,7 +43,6 @@
  * #GtkTreeDragSource and #GtkTreeDragDest interfaces.
  */
 
-
 GType
 gtk_tree_drag_source_get_type (void)
 {
@@ -157,38 +156,34 @@ gtk_tree_drag_source_drag_data_delete (GtkTreeDragSource *drag_source,
  * gtk_tree_drag_source_drag_data_get:
  * @drag_source: a #GtkTreeDragSource
  * @path: row that was dragged
- * @selection_data: a #GtkSelectionData to fill with data
- *                  from the dragged row
  * 
- * Asks the #GtkTreeDragSource to fill in @selection_data with a
- * representation of the row at @path. @selection_data->target gives
- * the required type of the data.  Should robustly handle a @path no
+ * Asks the #GtkTreeDragSource to return a #GdkContentProvider representing
+ * the row at @path. Should robustly handle a @path no
  * longer found in the model!
  * 
- * Returns: %TRUE if data of the required type was provided 
+ * Returns: (nullable) (transfer full): a #GdkContentProvider for the
+ *    given @path or %NULL if none exists
  **/
-gboolean
-gtk_tree_drag_source_drag_data_get    (GtkTreeDragSource *drag_source,
-                                       GtkTreePath       *path,
-                                       GtkSelectionData  *selection_data)
+GdkContentProvider *
+gtk_tree_drag_source_drag_data_get (GtkTreeDragSource *drag_source,
+                                    GtkTreePath       *path)
 {
   GtkTreeDragSourceIface *iface = GTK_TREE_DRAG_SOURCE_GET_IFACE (drag_source);
 
   g_return_val_if_fail (iface->drag_data_get != NULL, FALSE);
   g_return_val_if_fail (path != NULL, FALSE);
-  g_return_val_if_fail (selection_data != NULL, FALSE);
 
-  return (* iface->drag_data_get) (drag_source, path, selection_data);
+  return (* iface->drag_data_get) (drag_source, path);
 }
 
 /**
  * gtk_tree_drag_dest_drag_data_received:
  * @drag_dest: a #GtkTreeDragDest
  * @dest: row to drop in front of
- * @selection_data: data to drop
+ * @value: data to drop
  * 
  * Asks the #GtkTreeDragDest to insert a row before the path @dest,
- * deriving the contents of the row from @selection_data. If @dest is
+ * deriving the contents of the row from @value. If @dest is
  * outside the tree so that inserting before it is impossible, %FALSE
  * will be returned. Also, %FALSE may be returned if the new row is
  * not created for some model-specific reason.  Should robustly handle
@@ -199,15 +194,15 @@ gtk_tree_drag_source_drag_data_get    (GtkTreeDragSource *drag_source,
 gboolean
 gtk_tree_drag_dest_drag_data_received (GtkTreeDragDest  *drag_dest,
                                        GtkTreePath      *dest,
-                                       GtkSelectionData *selection_data)
+                                       const GValue     *value)
 {
   GtkTreeDragDestIface *iface = GTK_TREE_DRAG_DEST_GET_IFACE (drag_dest);
 
   g_return_val_if_fail (iface->drag_data_received != NULL, FALSE);
   g_return_val_if_fail (dest != NULL, FALSE);
-  g_return_val_if_fail (selection_data != NULL, FALSE);
+  g_return_val_if_fail (value != NULL, FALSE);
 
-  return (* iface->drag_data_received) (drag_dest, dest, selection_data);
+  return (* iface->drag_data_received) (drag_dest, dest, value);
 }
 
 
@@ -215,11 +210,11 @@ gtk_tree_drag_dest_drag_data_received (GtkTreeDragDest  *drag_dest,
  * gtk_tree_drag_dest_row_drop_possible:
  * @drag_dest: a #GtkTreeDragDest
  * @dest_path: destination row
- * @selection_data: the data being dragged
+ * @value: the data being dropped
  * 
  * Determines whether a drop is possible before the given @dest_path,
  * at the same depth as @dest_path. i.e., can we drop the data in
- * @selection_data at that location. @dest_path does not have to
+ * @value at that location. @dest_path does not have to
  * exist; the return value will almost certainly be %FALSE if the
  * parent of @dest_path doesn’t exist, though.
  * 
@@ -228,15 +223,15 @@ gtk_tree_drag_dest_drag_data_received (GtkTreeDragDest  *drag_dest,
 gboolean
 gtk_tree_drag_dest_row_drop_possible (GtkTreeDragDest   *drag_dest,
                                       GtkTreePath       *dest_path,
-                                     GtkSelectionData  *selection_data)
+                                     const GValue      *value)
 {
   GtkTreeDragDestIface *iface = GTK_TREE_DRAG_DEST_GET_IFACE (drag_dest);
 
   g_return_val_if_fail (iface->row_drop_possible != NULL, FALSE);
-  g_return_val_if_fail (selection_data != NULL, FALSE);
   g_return_val_if_fail (dest_path != NULL, FALSE);
+  g_return_val_if_fail (value != NULL, FALSE);
 
-  return (* iface->row_drop_possible) (drag_dest, dest_path, selection_data);
+  return (* iface->row_drop_possible) (drag_dest, dest_path, value);
 }
 
 typedef struct _TreeRowData TreeRowData;
@@ -247,34 +242,39 @@ struct _TreeRowData
   gchar path[4];
 };
 
+static TreeRowData *
+gtk_tree_row_data_copy (TreeRowData *src)
+{
+  return g_memdup (src, sizeof (TreeRowData) + strlen (src->path) + 1 -
+    (sizeof (TreeRowData) - G_STRUCT_OFFSET (TreeRowData, path)));
+}
+
+G_DEFINE_BOXED_TYPE (TreeRowData, gtk_tree_row_data,
+                     gtk_tree_row_data_copy,
+                     g_free)
+
 /**
- * gtk_tree_set_row_drag_data:
- * @selection_data: some #GtkSelectionData
+ * gtk_tree_create_row_drag_content:
  * @tree_model: a #GtkTreeModel
  * @path: a row in @tree_model
  * 
- * Sets selection data of target type %GTK_TREE_MODEL_ROW. Normally used
- * in a drag_data_get handler.
+ * Creates a content provider for dragging @path from @tree_model.
  * 
- * Returns: %TRUE if the #GtkSelectionData had the proper target type to allow us to set a tree row
+ * Returns: a new #GdkContentProvider
  **/
-gboolean
-gtk_tree_set_row_drag_data (GtkSelectionData *selection_data,
-                           GtkTreeModel     *tree_model,
-                           GtkTreePath      *path)
+GdkContentProvider *
+gtk_tree_create_row_drag_content (GtkTreeModel *tree_model,
+                                 GtkTreePath  *path)
 {
+  GdkContentProvider *content;
   TreeRowData *trd;
   gchar *path_str;
   gint len;
   gint struct_size;
   
-  g_return_val_if_fail (selection_data != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
   g_return_val_if_fail (path != NULL, FALSE);
 
-  if (gtk_selection_data_get_target (selection_data) != g_intern_static_string ("GTK_TREE_MODEL_ROW"))
-    return FALSE;
-  
   path_str = gtk_tree_path_to_string (path);
 
   len = strlen (path_str);
@@ -291,44 +291,35 @@ gtk_tree_set_row_drag_data (GtkSelectionData *selection_data,
   
   trd->model = tree_model;
   
-  gtk_selection_data_set (selection_data,
-                          g_intern_static_string ("GTK_TREE_MODEL_ROW"),
-                          8, /* bytes */
-                          (void*)trd,
-                          struct_size);
+  content = gdk_content_provider_new_typed (GTK_TYPE_TREE_ROW_DATA, trd);
 
   g_free (trd);
   
-  return TRUE;
+  return content;
 }
 
 /**
  * gtk_tree_get_row_drag_data:
- * @selection_data: a #GtkSelectionData
+ * @value: a #GValue
  * @tree_model: (nullable) (optional) (transfer none) (out): a #GtkTreeModel
  * @path: (nullable) (optional) (out): row in @tree_model
  * 
- * Obtains a @tree_model and @path from selection data of target type
- * %GTK_TREE_MODEL_ROW. Normally called from a drag_data_received handler.
- * This function can only be used if @selection_data originates from the same
- * process that’s calling this function, because a pointer to the tree model
- * is being passed around. If you aren’t in the same process, then you'll
- * get memory corruption. In the #GtkTreeDragDest drag_data_received handler,
- * you can assume that selection data of type %GTK_TREE_MODEL_ROW is
- * in from the current process. The returned path must be freed with
- * gtk_tree_path_free().
+ * Obtains a @tree_model and @path from value of target type
+ * %GTK_TYPE_TREE_ROW_DATA.
+ *
+ * The returned path must be freed with gtk_tree_path_free().
  * 
- * Returns: %TRUE if @selection_data had target type %GTK_TREE_MODEL_ROW and
+ * Returns: %TRUE if @selection_data had target type %GTK_TYPE_TREE_ROW_DATA
  *  is otherwise valid
  **/
 gboolean
-gtk_tree_get_row_drag_data (GtkSelectionData  *selection_data,
-                           GtkTreeModel     **tree_model,
-                           GtkTreePath      **path)
+gtk_tree_get_row_drag_data (const GValue  *value,
+                           GtkTreeModel **tree_model,
+                           GtkTreePath  **path)
 {
   TreeRowData *trd;
   
-  g_return_val_if_fail (selection_data != NULL, FALSE);  
+  g_return_val_if_fail (value != NULL, FALSE);  
 
   if (tree_model)
     *tree_model = NULL;
@@ -336,14 +327,13 @@ gtk_tree_get_row_drag_data (GtkSelectionData  *selection_data,
   if (path)
     *path = NULL;
 
-  if (gtk_selection_data_get_target (selection_data) != g_intern_static_string ("GTK_TREE_MODEL_ROW"))
+  if (!G_VALUE_HOLDS (value, GTK_TYPE_TREE_ROW_DATA))
     return FALSE;
 
-  if (gtk_selection_data_get_length (selection_data) < 0)
+  trd = g_value_get_boxed (value);
+  if (trd == NULL)
     return FALSE;
 
-  trd = (void*) gtk_selection_data_get_data (selection_data);
-
   if (tree_model)
     *tree_model = trd->model;
 
diff --git a/gtk/gtktreednd.h b/gtk/gtktreednd.h
index 46d907e988..d63b35fa61 100644
--- a/gtk/gtktreednd.h
+++ b/gtk/gtktreednd.h
@@ -22,11 +22,22 @@
 #error "Only <gtk/gtk.h> can be included directly."
 #endif
 
-#include <gtk/gtkselection.h>
 #include <gtk/gtktreemodel.h>
 
 G_BEGIN_DECLS
 
+/**
+ * GTK_TYPE_TREE_ROW_DATA:
+ * Magic #GType to use when dragging rows in a #GtkTreeModel.
+ *
+ * Data in this format will be provided by gtk_tree_create_row_drag_content()
+ * and can be consumed via gtk_tree_get_row_drag_data().
+ */
+#define GTK_TYPE_TREE_ROW_DATA (gtk_tree_row_data_get_type ())
+GDK_AVAILABLE_IN_ALL
+GType             gtk_tree_row_data_get_type (void) G_GNUC_CONST;
+
+
 #define GTK_TYPE_TREE_DRAG_SOURCE            (gtk_tree_drag_source_get_type ())
 #define GTK_TREE_DRAG_SOURCE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_DRAG_SOURCE, 
GtkTreeDragSource))
 #define GTK_IS_TREE_DRAG_SOURCE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TREE_DRAG_SOURCE))
@@ -56,9 +67,8 @@ struct _GtkTreeDragSourceIface
   gboolean     (* row_draggable)        (GtkTreeDragSource   *drag_source,
                                          GtkTreePath         *path);
 
-  gboolean     (* drag_data_get)        (GtkTreeDragSource   *drag_source,
-                                         GtkTreePath         *path,
-                                         GtkSelectionData    *selection_data);
+  GdkContentProvider * (* drag_data_get)(GtkTreeDragSource   *drag_source,
+                                         GtkTreePath         *path);
 
   gboolean     (* drag_data_delete)     (GtkTreeDragSource *drag_source,
                                          GtkTreePath       *path);
@@ -81,9 +91,9 @@ gboolean gtk_tree_drag_source_drag_data_delete (GtkTreeDragSource *drag_source,
  * the row denoted by path, returns TRUE if it does anything
  */
 GDK_AVAILABLE_IN_ALL
-gboolean gtk_tree_drag_source_drag_data_get    (GtkTreeDragSource *drag_source,
-                                                GtkTreePath       *path,
-                                                GtkSelectionData  *selection_data);
+GdkContentProvider *
+         gtk_tree_drag_source_drag_data_get    (GtkTreeDragSource *drag_source,
+                                                GtkTreePath       *path);
 
 #define GTK_TYPE_TREE_DRAG_DEST            (gtk_tree_drag_dest_get_type ())
 #define GTK_TREE_DRAG_DEST(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_DRAG_DEST, 
GtkTreeDragDest))
@@ -112,11 +122,11 @@ struct _GtkTreeDragDestIface
 
   gboolean     (* drag_data_received) (GtkTreeDragDest   *drag_dest,
                                        GtkTreePath       *dest,
-                                       GtkSelectionData  *selection_data);
+                                       const GValue      *value);
 
   gboolean     (* row_drop_possible)  (GtkTreeDragDest   *drag_dest,
                                        GtkTreePath       *dest_path,
-                                      GtkSelectionData  *selection_data);
+                                       const GValue      *value);
 };
 
 GDK_AVAILABLE_IN_ALL
@@ -128,25 +138,25 @@ GType           gtk_tree_drag_dest_get_type   (void) G_GNUC_CONST;
 GDK_AVAILABLE_IN_ALL
 gboolean gtk_tree_drag_dest_drag_data_received (GtkTreeDragDest   *drag_dest,
                                                GtkTreePath       *dest,
-                                               GtkSelectionData  *selection_data);
+                                               const GValue      *value);
 
 
 /* Returns TRUE if we can drop before path; path may not exist. */
 GDK_AVAILABLE_IN_ALL
 gboolean gtk_tree_drag_dest_row_drop_possible  (GtkTreeDragDest   *drag_dest,
                                                GtkTreePath       *dest_path,
-                                               GtkSelectionData  *selection_data);
+                                               const GValue      *value);
 
 
 /* The selection data would normally have target type GTK_TREE_MODEL_ROW in this
  * case. If the target is wrong these functions return FALSE.
  */
 GDK_AVAILABLE_IN_ALL
-gboolean gtk_tree_set_row_drag_data            (GtkSelectionData  *selection_data,
-                                               GtkTreeModel      *tree_model,
+GdkContentProvider * 
+         gtk_tree_create_row_drag_content      (GtkTreeModel      *tree_model,
                                                GtkTreePath       *path);
 GDK_AVAILABLE_IN_ALL
-gboolean gtk_tree_get_row_drag_data            (GtkSelectionData  *selection_data,
+gboolean gtk_tree_get_row_drag_data            (const GValue      *value,
                                                GtkTreeModel     **tree_model,
                                                GtkTreePath      **path);
 
diff --git a/gtk/gtktreemodelfilter.c b/gtk/gtktreemodelfilter.c
index a371caedbe..86d575f8cf 100644
--- a/gtk/gtktreemodelfilter.c
+++ b/gtk/gtktreemodelfilter.c
@@ -403,9 +403,9 @@ static void         gtk_tree_model_filter_unref_node                      (GtkTr
 /* TreeDragSource interface */
 static gboolean    gtk_tree_model_filter_row_draggable                    (GtkTreeDragSource      
*drag_source,
                                                                            GtkTreePath            *path);
-static gboolean    gtk_tree_model_filter_drag_data_get                    (GtkTreeDragSource      
*drag_source,
-                                                                           GtkTreePath            *path,
-                                                                           GtkSelectionData       
*selection_data);
+static GdkContentProvider *
+                   gtk_tree_model_filter_drag_data_get                    (GtkTreeDragSource      
*drag_source,
+                                                                           GtkTreePath            *path);
 static gboolean    gtk_tree_model_filter_drag_data_delete                 (GtkTreeDragSource      
*drag_source,
                                                                            GtkTreePath            *path);
 
@@ -3589,20 +3589,19 @@ gtk_tree_model_filter_row_draggable (GtkTreeDragSource *drag_source,
   return draggable;
 }
 
-static gboolean
+static GdkContentProvider *
 gtk_tree_model_filter_drag_data_get (GtkTreeDragSource *drag_source,
-                                     GtkTreePath       *path,
-                                     GtkSelectionData  *selection_data)
+                                     GtkTreePath       *path)
 {
   GtkTreeModelFilter *tree_model_filter = (GtkTreeModelFilter *)drag_source;
   GtkTreePath *child_path;
-  gboolean gotten;
+  GdkContentProvider *gotten;
 
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (drag_source), FALSE);
-  g_return_val_if_fail (path != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (drag_source), NULL);
+  g_return_val_if_fail (path != NULL, NULL);
 
   child_path = gtk_tree_model_filter_convert_path_to_child_path (tree_model_filter, path);
-  gotten = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (tree_model_filter->priv->child_model), 
child_path, selection_data);
+  gotten = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (tree_model_filter->priv->child_model), 
child_path);
   gtk_tree_path_free (child_path);
 
   return gotten;
diff --git a/gtk/gtktreemodelsort.c b/gtk/gtktreemodelsort.c
index 75476bad4b..5f793b547d 100644
--- a/gtk/gtktreemodelsort.c
+++ b/gtk/gtktreemodelsort.c
@@ -383,9 +383,9 @@ static void         gtk_tree_model_sort_unref_node         (GtkTreeModel
 /* TreeDragSource interface */
 static gboolean     gtk_tree_model_sort_row_draggable         (GtkTreeDragSource      *drag_source,
                                                                GtkTreePath            *path);
-static gboolean     gtk_tree_model_sort_drag_data_get         (GtkTreeDragSource      *drag_source,
-                                                               GtkTreePath            *path,
-                                                              GtkSelectionData       *selection_data);
+static GdkContentProvider *
+                    gtk_tree_model_sort_drag_data_get         (GtkTreeDragSource      *drag_source,
+                                                               GtkTreePath            *path);
 static gboolean     gtk_tree_model_sort_drag_data_delete      (GtkTreeDragSource      *drag_source,
                                                                GtkTreePath            *path);
 
@@ -1780,17 +1780,16 @@ gtk_tree_model_sort_row_draggable (GtkTreeDragSource *drag_source,
   return draggable;
 }
 
-static gboolean
+static GdkContentProvider *
 gtk_tree_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
-                                   GtkTreePath       *path,
-                                   GtkSelectionData  *selection_data)
+                                   GtkTreePath       *path)
 {
   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
   GtkTreePath *child_path;
-  gboolean gotten;
+  GdkContentProvider *gotten;
 
   child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
-  gotten = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), 
child_path, selection_data);
+  gotten = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), 
child_path);
   gtk_tree_path_free (child_path);
 
   return gotten;
diff --git a/gtk/gtktreestore.c b/gtk/gtktreestore.c
index 18f352db81..df64028a3d 100644
--- a/gtk/gtktreestore.c
+++ b/gtk/gtktreestore.c
@@ -135,15 +135,15 @@ static gboolean real_gtk_tree_store_row_draggable   (GtkTreeDragSource *drag_sou
                                                   GtkTreePath       *path);
 static gboolean gtk_tree_store_drag_data_delete   (GtkTreeDragSource *drag_source,
                                                   GtkTreePath       *path);
-static gboolean gtk_tree_store_drag_data_get      (GtkTreeDragSource *drag_source,
-                                                  GtkTreePath       *path,
-                                                  GtkSelectionData  *selection_data);
+static GdkContentProvider *
+                gtk_tree_store_drag_data_get      (GtkTreeDragSource *drag_source,
+                                                  GtkTreePath       *path);
 static gboolean gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
                                                   GtkTreePath       *dest,
-                                                  GtkSelectionData  *selection_data);
+                                                  const GValue      *value);
 static gboolean gtk_tree_store_row_drop_possible  (GtkTreeDragDest   *drag_dest,
                                                   GtkTreePath       *dest_path,
-                                                  GtkSelectionData  *selection_data);
+                                                  const GValue      *value);
 
 /* Sortable Interfaces */
 
@@ -1956,29 +1956,16 @@ gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
     }
 }
 
-static gboolean
+static GdkContentProvider *
 gtk_tree_store_drag_data_get (GtkTreeDragSource *drag_source,
-                              GtkTreePath       *path,
-                              GtkSelectionData  *selection_data)
+                              GtkTreePath       *path)
 {
   /* Note that we don't need to handle the GTK_TREE_MODEL_ROW
    * target, because the default handler does it for us, but
    * we do anyway for the convenience of someone maybe overriding the
    * default handler.
    */
-
-  if (gtk_tree_set_row_drag_data (selection_data,
-                                 GTK_TREE_MODEL (drag_source),
-                                 path))
-    {
-      return TRUE;
-    }
-  else
-    {
-      /* FIXME handle text targets at least. */
-    }
-
-  return FALSE;
+  return gtk_tree_create_row_drag_content (GTK_TREE_MODEL (drag_source), path);
 }
 
 static void
@@ -2052,9 +2039,9 @@ recursive_node_copy (GtkTreeStore *tree_store,
 }
 
 static gboolean
-gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
-                                   GtkTreePath       *dest,
-                                   GtkSelectionData  *selection_data)
+gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest,
+                                   GtkTreePath     *dest,
+                                   const GValue    *value)
 {
   GtkTreeModel *tree_model;
   GtkTreeStore *tree_store;
@@ -2067,7 +2054,7 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
 
   validate_tree (tree_store);
 
-  if (gtk_tree_get_row_drag_data (selection_data,
+  if (gtk_tree_get_row_drag_data (value,
                                  &src_model,
                                  &src_path) &&
       src_model == tree_model)
@@ -2160,9 +2147,9 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
 }
 
 static gboolean
-gtk_tree_store_row_drop_possible (GtkTreeDragDest  *drag_dest,
-                                  GtkTreePath      *dest_path,
-                                 GtkSelectionData *selection_data)
+gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest,
+                                  GtkTreePath     *dest_path,
+                                 const GValue    *value)
 {
   GtkTreeModel *src_model = NULL;
   GtkTreePath *src_path = NULL;
@@ -2173,7 +2160,7 @@ gtk_tree_store_row_drop_possible (GtkTreeDragDest  *drag_dest,
   if (GTK_TREE_STORE_IS_SORTED (drag_dest))
     return FALSE;
 
-  if (!gtk_tree_get_row_drag_data (selection_data,
+  if (!gtk_tree_get_row_drag_data (value,
                                   &src_model,
                                   &src_path))
     goto out;
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 8ce1a0ef14..1a894ad3b2 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -688,8 +688,8 @@ static void     gtk_tree_view_forall               (GtkContainer     *container,
 /* Source side drag signals */
 static void gtk_tree_view_dnd_finished_cb  (GdkDrag          *drag,
                                             GtkWidget        *widget);
-static GBytes *gtk_tree_view_drag_data_get (const char *mimetype,
-                                            gpointer    data);
+static GdkContentProvider * gtk_tree_view_drag_data_get   (GtkTreeView           *tree_view,
+                                                           GtkTreePath           *source_row);
 
 /* Target side drag signals */
 static void     gtk_tree_view_drag_leave         (GtkDropTarget    *dest,
@@ -6877,7 +6877,7 @@ set_destination_row (GtkTreeView    *tree_view,
                      gint            x,
                      gint            y,
                      GdkDragAction  *suggested_action,
-                     GdkAtom        *target)
+                     GType          *target)
 {
   GtkTreePath *path = NULL;
   GtkTreeViewDropPosition pos;
@@ -6886,9 +6886,10 @@ set_destination_row (GtkTreeView    *tree_view,
   GtkWidget *widget;
   GtkTreePath *old_dest_path = NULL;
   gboolean can_drop = FALSE;
+  GdkContentFormats *formats;
 
   *suggested_action = 0;
-  *target = NULL;
+  *target = G_TYPE_INVALID;
 
   widget = GTK_WIDGET (tree_view);
 
@@ -6910,8 +6911,9 @@ set_destination_row (GtkTreeView    *tree_view,
       return FALSE; /* no longer a drop site */
     }
 
-  *target = gtk_drop_target_find_mimetype (dest);
-  if (*target == NULL)
+  formats = gtk_drop_target_get_formats (dest);
+  *target = gdk_content_formats_match_gtype (formats, formats);
+  if (*target == G_TYPE_INVALID)
     return FALSE;
 
   if (!gtk_tree_view_get_dest_row_at_pos (tree_view,
@@ -7101,21 +7103,22 @@ gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view)
   if (!(GDK_BUTTON1_MASK << (button - 1) & di->start_button_mask))
     goto out;
 
-  retval = TRUE;
-
   /* Now we can begin the drag */
   gtk_gesture_set_state (GTK_GESTURE (tree_view->drag_gesture),
                          GTK_EVENT_SEQUENCE_CLAIMED);
 
   surface = gtk_native_get_surface (gtk_widget_get_native (GTK_WIDGET (tree_view)));
   device = gtk_gesture_get_device (GTK_GESTURE (tree_view->drag_gesture)),
-  content = gdk_content_provider_new_with_formats (di->source_formats,
-                                                   gtk_tree_view_drag_data_get,
-                                                   tree_view,
-                                                   NULL);
+  content = gtk_tree_view_drag_data_get (tree_view, path);
+  if (content == NULL)
+    goto out;
+
+  retval = TRUE;
 
   drag = gdk_drag_begin (surface, device, content, di->source_actions, start_x, start_y);
 
+  g_object_unref (content);
+
   g_signal_connect (drag, "dnd-finished", G_CALLBACK (gtk_tree_view_dnd_finished_cb), tree_view);
 
   icon = gtk_tree_view_create_row_drag_icon (tree_view, path);
@@ -7174,55 +7177,33 @@ gtk_tree_view_dnd_finished_cb (GdkDrag   *drag,
 }
 
 /* Default signal implementations for the drag signals */
-static GBytes *
-gtk_tree_view_drag_data_get (const char *mime_type,
-                             gpointer    data)
+static GdkContentProvider *
+gtk_tree_view_drag_data_get (GtkTreeView *tree_view,
+                             GtkTreePath *source_row)
 {
-  GtkTreeView *tree_view = data;
   GtkTreeModel *model;
-  TreeViewDragInfo *di;
-  GtkTreePath *source_row;
-  GtkSelectionData sdata = { 0, };
-
-  sdata.target = g_intern_string (mime_type);
+  GdkContentProvider *content;
 
   model = gtk_tree_view_get_model (tree_view);
 
   if (model == NULL)
     return NULL;
 
-  di = get_info (tree_view);
-
-  if (di == NULL || di->source_item == NULL)
-    return NULL;
-
-  source_row = gtk_tree_row_reference_get_path (di->source_item);
-
-  if (source_row == NULL)
-    return NULL;
-
   /* We can implement the GTK_TREE_MODEL_ROW target generically for
    * any model; for DragSource models there are some other targets
    * we also support.
    */
 
-  if (GTK_IS_TREE_DRAG_SOURCE (model) &&
-      gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (model),
-                                          source_row,
-                                          &sdata))
-    goto done;
+  if (GTK_IS_TREE_DRAG_SOURCE (model))
+    content = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (model), source_row);
+  else
+    content = NULL;
 
   /* If drag_data_get does nothing, try providing row data. */
-  if (mime_type == g_intern_static_string ("GTK_TREE_MODEL_ROW"))
-    {
-      gtk_tree_set_row_drag_data (&sdata, model, source_row);
-    }
-
- done:
-  gtk_tree_path_free (source_row);
+  if (!content)
+    content = gtk_tree_create_row_drag_content (model, source_row);
 
-  return g_bytes_new_take ((gpointer)gtk_selection_data_get_data (&sdata),
-                            gtk_selection_data_get_length (&sdata));
+  return content;
 }
 
 static void
@@ -7254,7 +7235,7 @@ gtk_tree_view_drag_motion (GtkDropTarget *dest,
   GtkTreePath *path = NULL;
   GtkTreeViewDropPosition pos;
   GdkDragAction suggested_action = 0;
-  GdkAtom target;
+  GType target;
 
   if (!set_destination_row (tree_view, dest, x, y, &suggested_action, &target))
     {
@@ -7290,13 +7271,13 @@ gtk_tree_view_drag_motion (GtkDropTarget *dest,
          add_scroll_timeout (tree_view);
        }
 
-      if (target == g_intern_static_string ("GTK_TREE_MODEL_ROW"))
+      if (target == GTK_TYPE_TREE_ROW_DATA)
         {
           /* Request data so we can use the source row when
            * determining whether to accept the drop
            */
           set_status_pending (drop, suggested_action);
-          gtk_drop_target_read_selection (dest, target, NULL, gtk_tree_view_drag_data_received, tree_view);
+          gdk_drop_read_value_async (drop, GTK_TYPE_TREE_ROW_DATA, G_PRIORITY_DEFAULT, NULL, 
gtk_tree_view_drag_data_received, tree_view);
         }
       else
         {
@@ -7319,7 +7300,7 @@ gtk_tree_view_drag_drop (GtkDropTarget *dest,
 {
   GtkTreePath *path;
   GdkDragAction suggested_action = 0;
-  GdkAtom target = NULL;
+  GType target = G_TYPE_INVALID;
   TreeViewDragInfo *di;
   GtkTreeModel *model;
   gboolean path_down_mode;
@@ -7343,7 +7324,7 @@ gtk_tree_view_drag_drop (GtkDropTarget *dest,
 
   path = get_logical_dest_row (tree_view, &path_down_mode, &drop_append_mode);
 
-  if (target != NULL && path != NULL)
+  if (target != G_TYPE_INVALID && path != NULL)
     {
       /* in case a motion had requested drag data, change things so we
        * treat drag data receives as a drop.
@@ -7362,9 +7343,9 @@ gtk_tree_view_drag_drop (GtkDropTarget *dest,
                                    NULL,
                                    GTK_TREE_VIEW_DROP_BEFORE);
 
-  if (target != NULL)
+  if (target != G_TYPE_INVALID)
     {
-      gtk_drop_target_read_selection (dest, target, NULL, gtk_tree_view_drag_data_received, tree_view);
+      gdk_drop_read_value_async (drop, GTK_TYPE_TREE_ROW_DATA, G_PRIORITY_DEFAULT, NULL, 
gtk_tree_view_drag_data_received, tree_view);
       return TRUE;
     }
   else
@@ -7402,9 +7383,8 @@ gtk_tree_view_drag_data_received (GObject      *source,
                                   GAsyncResult *result,
                                   gpointer      data)
 {
-  GtkDropTarget *dest = GTK_DROP_TARGET (source);
   GtkTreeView *tree_view = GTK_TREE_VIEW (data);
-  GdkDrop *drop = gtk_drop_target_get_drop (dest);
+  GdkDrop *drop = GDK_DROP (source);
   GtkTreePath *path;
   TreeViewDragInfo *di;
   GtkTreeModel *model;
@@ -7412,9 +7392,13 @@ gtk_tree_view_drag_data_received (GObject      *source,
   GdkDragAction suggested_action;
   gboolean path_down_mode;
   gboolean drop_append_mode;
-  GtkSelectionData *selection_data;
+  const GValue *value;
+
+  suggested_action = 0;
 
-  selection_data = gtk_drop_target_read_selection_finish (dest, result, NULL);
+  value = gdk_drop_read_value_finish (drop, result, NULL);
+  if (value == NULL)
+    return;
 
   model = gtk_tree_view_get_model (tree_view);
 
@@ -7447,7 +7431,7 @@ gtk_tree_view_drag_data_received (GObject      *source,
         {
          if (!gtk_tree_drag_dest_row_drop_possible (GTK_TREE_DRAG_DEST (model),
                                                     path,
-                                                    selection_data))
+                                                    value))
             {
               if (path_down_mode)
                 {
@@ -7456,7 +7440,7 @@ gtk_tree_view_drag_data_received (GObject      *source,
 
                   if (!gtk_tree_drag_dest_row_drop_possible (GTK_TREE_DRAG_DEST (model),
                                                              path,
-                                                             selection_data))
+                                                             value))
                     suggested_action = 0;
                 }
               else
@@ -7483,27 +7467,21 @@ gtk_tree_view_drag_data_received (GObject      *source,
   if (dest_row == NULL)
     return;
 
-  if (gtk_selection_data_get_length (selection_data) >= 0)
+  if (path_down_mode)
     {
-      if (path_down_mode)
-        {
-          gtk_tree_path_down (dest_row);
-          if (!gtk_tree_drag_dest_row_drop_possible (GTK_TREE_DRAG_DEST (model),
-                                                     dest_row, selection_data))
-            gtk_tree_path_up (dest_row);
-        }
+      gtk_tree_path_down (dest_row);
+      if (!gtk_tree_drag_dest_row_drop_possible (GTK_TREE_DRAG_DEST (model),
+                                                 dest_row, value))
+        gtk_tree_path_up (dest_row);
     }
 
-  if (gtk_selection_data_get_length (selection_data) >= 0)
-    {
-      suggested_action = gtk_tree_view_get_action (GTK_WIDGET (tree_view), drop);
+  suggested_action = gtk_tree_view_get_action (GTK_WIDGET (tree_view), drop);
 
-      if (suggested_action &&
-          !gtk_tree_drag_dest_drag_data_received (GTK_TREE_DRAG_DEST (model),
-                                                  dest_row,
-                                                  selection_data))
-        suggested_action = 0;
-    }
+  if (suggested_action &&
+      !gtk_tree_drag_dest_drag_data_received (GTK_TREE_DRAG_DEST (model),
+                                              dest_row,
+                                              value))
+    suggested_action = 0;
 
   gdk_drop_finish (drop, suggested_action);
 
@@ -11883,12 +11861,9 @@ gtk_tree_view_set_reorderable (GtkTreeView *tree_view,
 
   if (reorderable)
     {
-      const char *row_targets[] = {
-        "GTK_TREE_MODEL_ROW"
-      };
       GdkContentFormats *formats;
 
-      formats = gdk_content_formats_new (row_targets, G_N_ELEMENTS (row_targets));
+      formats = gdk_content_formats_new_for_gtype (GTK_TYPE_TREE_ROW_DATA);
 
       gtk_tree_view_enable_model_drag_source (tree_view,
                                              GDK_BUTTON1_MASK,
diff --git a/tests/testiconview.c b/tests/testiconview.c
index bd5eeae3cb..9b87c41a38 100644
--- a/tests/testiconview.c
+++ b/tests/testiconview.c
@@ -389,10 +389,6 @@ popup_menu_handler (GtkWidget *widget)
   return TRUE;
 }
 
-static const char *item_targets[] = {
-  "GTK_TREE_MODEL_ROW"
-};
-       
 gint
 main (gint argc, gchar **argv)
 {
@@ -506,7 +502,7 @@ main (gint argc, gchar **argv)
 #endif
   /* Allow DND between the icon view and the tree view */
   
-  targets = gdk_content_formats_new (item_targets, G_N_ELEMENTS (item_targets));
+  targets = gdk_content_formats_new_for_gtype (GTK_TYPE_TREE_ROW_DATA);
   gtk_icon_view_enable_model_drag_source (GTK_ICON_VIEW (icon_list),
                                          GDK_BUTTON1_MASK,
                                           targets,
diff --git a/tests/testkineticscrolling.c b/tests/testkineticscrolling.c
index eaac76cbe0..ca9f2581e4 100644
--- a/tests/testkineticscrolling.c
+++ b/tests/testkineticscrolling.c
@@ -1,10 +1,5 @@
 #include <gtk/gtk.h>
 
-static const char *row_targets[] =
-{
-  "GTK_TREE_MODEL_ROW"
-};
-
 static void
 on_button_clicked (GtkWidget *widget, gpointer data)
 {
@@ -83,7 +78,7 @@ kinetic_scrolling (void)
   gtk_widget_show (swindow);
 
   treeview = gtk_tree_view_new ();
-  targets = gdk_content_formats_new (row_targets, G_N_ELEMENTS (row_targets));
+  targets = gdk_content_formats_new_for_gtype (GTK_TYPE_TREE_ROW_DATA);
   gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (treeview),
                                           GDK_BUTTON1_MASK,
                                           targets,
diff --git a/tests/testtreecolumns.c b/tests/testtreecolumns.c
index c71f2c912a..6ad42964a5 100644
--- a/tests/testtreecolumns.c
+++ b/tests/testtreecolumns.c
@@ -268,17 +268,11 @@ view_column_model_tree_model_init (GtkTreeModelIface *iface)
   iface->iter_parent = view_column_model_iter_parent;
 }
 
-static gboolean
-view_column_model_drag_data_get (GtkTreeDragSource   *drag_source,
-                                GtkTreePath         *path,
-                                GtkSelectionData    *selection_data)
-{
-  if (gtk_tree_set_row_drag_data (selection_data,
-                                 GTK_TREE_MODEL (drag_source),
-                                 path))
-    return TRUE;
-  else
-    return FALSE;
+static GdkContentProvider *
+view_column_model_drag_data_get (GtkTreeDragSource *drag_source,
+                                GtkTreePath       *path)
+{
+  return gtk_tree_create_row_drag_content (GTK_TREE_MODEL (drag_source), path);
 }
 
 static gboolean
@@ -291,13 +285,13 @@ view_column_model_drag_data_delete (GtkTreeDragSource *drag_source,
 }
 
 static gboolean
-view_column_model_row_drop_possible (GtkTreeDragDest   *drag_dest,
-                                    GtkTreePath       *dest_path,
-                                    GtkSelectionData  *selection_data)
+view_column_model_row_drop_possible (GtkTreeDragDest *drag_dest,
+                                    GtkTreePath     *dest_path,
+                                    const GValue    *value)
 {
   GtkTreeModel *src_model;
   
-  if (gtk_tree_get_row_drag_data (selection_data,
+  if (gtk_tree_get_row_drag_data (value,
                                  &src_model,
                                  NULL))
     {
@@ -311,15 +305,15 @@ view_column_model_row_drop_possible (GtkTreeDragDest   *drag_dest,
 }
 
 static gboolean
-view_column_model_drag_data_received (GtkTreeDragDest   *drag_dest,
-                                     GtkTreePath       *dest,
-                                     GtkSelectionData  *selection_data)
+view_column_model_drag_data_received (GtkTreeDragDest *drag_dest,
+                                     GtkTreePath     *dest,
+                                     const GValue    *value)
 {
   GtkTreeModel *src_model;
   GtkTreePath *src_path = NULL;
   gboolean retval = FALSE;
   
-  if (gtk_tree_get_row_drag_data (selection_data,
+  if (gtk_tree_get_row_drag_data (value,
                                  &src_model,
                                  &src_path))
     {
@@ -703,10 +697,6 @@ selection_changed (GtkTreeSelection *selection, GtkWidget *button)
     gtk_widget_set_sensitive (button, FALSE);
 }
 
-static const char *row_targets[] = {
-  "GTK_TREE_MODEL_ROW"
-};
-
 static void
 quit_cb (GtkWidget *widget,
          gpointer   data)
@@ -874,7 +864,7 @@ main (int argc, char *argv[])
 
 
   /* Drag and Drop */
-  targets = gdk_content_formats_new (row_targets, G_N_ELEMENTS (row_targets));
+  targets = gdk_content_formats_new_for_gtype (GTK_TYPE_TREE_ROW_DATA);
   gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (left_tree_view),
                                          GDK_BUTTON1_MASK,
                                           targets,
diff --git a/tests/testtreednd.c b/tests/testtreednd.c
index 16efa7e302..c087527ce3 100644
--- a/tests/testtreednd.c
+++ b/tests/testtreednd.c
@@ -22,20 +22,20 @@ my_model_init (MyModel *object)
   gtk_list_store_set_column_types (GTK_LIST_STORE (object), G_N_ELEMENTS (types), types);
 }
 
-static gboolean
+static GdkContentProvider *
 my_model_drag_data_get (GtkTreeDragSource *source,
-                        GtkTreePath       *path,
-                        GtkSelectionData  *data)
+                        GtkTreePath       *path)
 {
+  GdkContentProvider *content;
   GtkTreeIter iter;
   gchar *text;
 
   gtk_tree_model_get_iter (GTK_TREE_MODEL (source), &iter, path);
   gtk_tree_model_get (GTK_TREE_MODEL (source), &iter, 0, &text, -1);
-  gtk_selection_data_set_text (data, text, -1);
+  content = gdk_content_provider_new_typed (G_TYPE_STRING, text);
   g_free (text);
 
-  return TRUE;
+  return content;
 }
 
 static void
@@ -63,10 +63,6 @@ get_model (void)
   return GTK_TREE_MODEL (model);
 }
 
-static const char *entries[] = {
-  "text/plain"
-};
-
 static GtkWidget *
 get_dragsource (void)
 {
@@ -81,7 +77,7 @@ get_dragsource (void)
   gtk_tree_view_append_column (tv, column);
 
   gtk_tree_view_set_model (tv, get_model ());
-  targets = gdk_content_formats_new (entries, G_N_ELEMENTS (entries));
+  targets = gdk_content_formats_new_for_gtype (G_TYPE_STRING);
   gtk_tree_view_enable_model_drag_source (tv, GDK_BUTTON1_MASK, targets, GDK_ACTION_COPY);
   gdk_content_formats_unref (targets);
 
@@ -93,18 +89,15 @@ got_text (GObject      *source,
           GAsyncResult *result,
           gpointer      data)
 {
-  GtkDropTarget *dest = GTK_DROP_TARGET (source);
-  GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
-  gchar *text;
-  GtkSelectionData *selda;
+  GdkDrop *drop = GDK_DROP (source);
+  GtkWidget *widget = data;
+  const GValue *value;
 
-  selda = gtk_drop_target_read_selection_finish (dest, result, NULL);
+  value = gdk_drop_read_value_finish (drop, result, NULL);
+  if (value == NULL)
+    return;
   
-  text = (gchar*) gtk_selection_data_get_text (selda);
-  gtk_label_set_label (GTK_LABEL (widget), text);
-  g_free (text);
-
-  gtk_selection_data_free (selda);
+  gtk_label_set_label (GTK_LABEL (widget), g_value_get_string (value));
 }
 
 static void
@@ -114,7 +107,9 @@ drag_drop (GtkDropTarget *dest,
            int            y,
            gpointer       dada)
 {
-  gtk_drop_target_read_selection (dest, "text/plain",  NULL, got_text, dada);
+  GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
+
+  gdk_drop_read_value_async (drop, G_TYPE_STRING, G_PRIORITY_DEFAULT, NULL, got_text, widget);
 }
 
 static GtkWidget *
@@ -124,7 +119,7 @@ get_droptarget (void)
   GtkDropTarget *dest;
 
   label = gtk_label_new ("Drop here");
-  dest = gtk_drop_target_new (gdk_content_formats_new (entries, G_N_ELEMENTS (entries)), GDK_ACTION_COPY);
+  dest = gtk_drop_target_new (gdk_content_formats_new_for_gtype (G_TYPE_STRING), GDK_ACTION_COPY);
   g_signal_connect (dest, "drag-drop", G_CALLBACK (drag_drop), NULL);
   gtk_widget_add_controller (label, GTK_EVENT_CONTROLLER (dest));
 
diff --git a/tests/testtreeview.c b/tests/testtreeview.c
index ffa06867e2..8df5ca4925 100644
--- a/tests/testtreeview.c
+++ b/tests/testtreeview.c
@@ -641,10 +641,6 @@ on_row_activated (GtkTreeView       *tree_view,
   g_print ("Row activated\n");
 }
 
-static const char *row_targets[] = {
-  "GTK_TREE_MODEL_ROW"
-};
-
 static void
 quit_cb (GtkWidget *widget,
          gpointer   data)
@@ -709,7 +705,7 @@ main (int    argc,
   tv = gtk_tree_view_new_with_model (models[0]);
   g_signal_connect (tv, "row-activated", G_CALLBACK (on_row_activated), NULL);
 
-  targets = gdk_content_formats_new (row_targets, G_N_ELEMENTS (row_targets));
+  targets = gdk_content_formats_new_for_gtype (GTK_TYPE_TREE_ROW_DATA);
   gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (tv),
                                          GDK_BUTTON1_MASK,
                                           targets,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]