dragsource: Reshuffle api a bit
authorMatthias Clasen <mclasen@redhat.com>
Mon, 6 Jan 2020 19:46:14 +0000 (14:46 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Wed, 8 Jan 2020 23:48:21 +0000 (18:48 -0500)
Remove arguments from the constructor.

For actions, we now default to COPY, which is the most common one
that we should enable by default (MOVE requires handling deletion
on the the source side, and ASK only makes sense if we have
multiple actions).

For the content provider, we add a new ::prepare signal where
it should be provided just-in-time.

21 files changed:
demos/gtk-demo/clipboard.c
demos/icon-browser/iconbrowserwin.c
gtk/gtkcalendar.c
gtk/gtkcolorbutton.c
gtk/gtkcolorswatch.c
gtk/gtkdragsource.c
gtk/gtkdragsource.h
gtk/gtkentry.c
gtk/gtkiconview.c
gtk/gtklabel.c
gtk/gtklinkbutton.c
gtk/gtknotebook.c
gtk/gtkpathbar.c
gtk/gtkplacessidebar.c
gtk/gtktext.c
gtk/gtktextview.c
gtk/gtktreeview.c
tests/testdnd.c
tests/testdnd2.c
tests/testlist3.c
tests/testtoolbar.c

index 51f5507c266a7dc2e74cf5df4d340acb02c3fcaa..3da096060ecfee33c9824c9186479aa0ee38152a 100644 (file)
@@ -143,6 +143,19 @@ get_texture (GValue   *value,
     g_value_set_object (value, paintable);
 }
 
+static void
+prepare_drag (GtkDragSource *source,
+              double         x,
+              double         y,
+              GtkWidget     *image)
+{
+  GdkContentProvider *content;
+
+  content = gdk_content_provider_new_with_callback (GDK_TYPE_TEXTURE, get_texture, image);
+  gtk_drag_source_set_content (source, content);
+  g_object_unref (content);
+}
+
 static void
 got_texture (GObject *source,
              GAsyncResult *result,
@@ -265,7 +278,6 @@ do_clipboard (GtkWidget *do_widget)
         { "paste", paste_image, NULL, NULL, NULL },
       };
       GActionGroup *actions;
-      GdkContentProvider *content = NULL;
       GtkDragSource *source;
       GtkDropTarget *dest;
       GdkContentFormats *formats;
@@ -331,10 +343,9 @@ do_clipboard (GtkWidget *do_widget)
       gtk_container_add (GTK_CONTAINER (hbox), image);
 
       /* make image a drag source */
-      content = gdk_content_provider_new_with_callback (GDK_TYPE_TEXTURE, get_texture, image);
-      source = gtk_drag_source_new (content, GDK_ACTION_COPY);
-      g_object_unref (content);
+      source = gtk_drag_source_new ();
       gtk_drag_source_attach (source, image, GDK_BUTTON1_MASK);
+      g_signal_connect (source, "prepare", G_CALLBACK (prepare_drag), NULL);
       g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
 
       /* accept drops on image */
@@ -364,9 +375,8 @@ do_clipboard (GtkWidget *do_widget)
       gtk_container_add (GTK_CONTAINER (hbox), image);
 
       /* make image a drag source */
-      content = gdk_content_provider_new_with_callback (GDK_TYPE_TEXTURE, get_texture, image);
-      source = gtk_drag_source_new (content, GDK_ACTION_COPY);
-      g_object_unref (content);
+      source = gtk_drag_source_new ();
+      g_signal_connect (source, "prepare", G_CALLBACK (prepare_drag), NULL);
       g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
       gtk_drag_source_attach (source, image, GDK_BUTTON1_MASK);
 
index e560bc612ef0deb9254186bad8b8e9c65a986735..84ccb2725983cfd6e5438ef348717e111cf4e2d5 100644 (file)
@@ -423,8 +423,9 @@ setup_image_dnd (GtkWidget *image)
   GdkContentProvider *content;
   GtkDragSource *source;
 
+  source = gtk_drag_source_new ();
   content = gdk_content_provider_new_with_callback (GDK_TYPE_TEXTURE, get_texture, image);
-  source = gtk_drag_source_new (content, GDK_ACTION_COPY);
+  gtk_drag_source_set_content (source, content);
   g_object_unref (content);
   g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
   gtk_drag_source_attach (source, image, GDK_BUTTON1_MASK);
@@ -436,8 +437,9 @@ setup_scalable_image_dnd (GtkWidget *image)
   GdkContentProvider *content;
   GtkDragSource *source;
 
+  source = gtk_drag_source_new ();
   content = gdk_content_provider_new_with_callback (G_TYPE_FILE, get_file, image);
-  source = gtk_drag_source_new (content, GDK_ACTION_COPY);
+  gtk_drag_source_set_content (source, content);
   g_object_unref (content);
 
   g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
index 7e3b8b49d8dfbd150abaf6b896868acfe880b0f8..9892f99e22eb7c9d6ce25ebbf1b2edcfb6021e60 100644 (file)
@@ -2709,8 +2709,9 @@ gtk_calendar_drag_update (GtkGestureDrag *gesture,
 
   gtk_gesture_drag_get_start_point (gesture, &start_x, &start_y);
 
+  source = gtk_drag_source_new ();
   content = get_calendar_content (calendar);
-  source = gtk_drag_source_new (content, GDK_ACTION_COPY);
+  gtk_drag_source_set_content (source, content);
   g_object_unref (content);
   device = gtk_gesture_get_device (GTK_GESTURE (gesture));
   gtk_drag_source_drag_begin (source, widget, device, start_x, start_y);
index 00fcf02b68b969f56cc75146672047d53969a3ec..a951958c484a45a75f57df217de4ce9f420d4113 100644 (file)
@@ -333,8 +333,9 @@ gtk_color_button_init (GtkColorButton *button)
   gtk_widget_add_controller (GTK_WIDGET (button), GTK_EVENT_CONTROLLER (dest));
   gdk_content_formats_unref (targets);
 
+  source = gtk_drag_source_new ();
   content = gdk_content_provider_new_with_callback (GDK_TYPE_RGBA, get_rgba_value, button);
-  source = gtk_drag_source_new (content, GDK_ACTION_COPY);
+  gtk_drag_source_set_content (source, content);
   g_object_unref (content);
   g_signal_connect (source, "drag-begin", G_CALLBACK (gtk_color_button_drag_begin), button);
 
index 9bdcca3e83f39974654906af15ac5ef73c1cf96d..d693709669f23e809c81b153be0ae7834244ba04 100644 (file)
@@ -601,8 +601,9 @@ gtk_color_swatch_set_rgba (GtkColorSwatch *swatch,
       GdkContentProvider *content;
       GtkDragSource *source;
 
+      source = gtk_drag_source_new ();
       content = gdk_content_provider_new_with_callback (GDK_TYPE_RGBA, get_rgba_value, swatch);
-      source = gtk_drag_source_new (content, GDK_ACTION_COPY);
+      gtk_drag_source_set_content (source, content);
       g_object_unref (content);
       g_signal_connect (source, "drag-begin", G_CALLBACK (gtk_color_swatch_drag_begin), swatch);
 
index 6fa40897f41e301cfba7bad533cbbec2baf63edb..68a0a344df4ab64ea45f1d6415d343171e86dcc3 100644 (file)
@@ -107,6 +107,7 @@ enum {
 static GParamSpec *properties[NUM_PROPERTIES];
 
 enum {
+  PREPARE,
   DRAG_BEGIN,
   DRAG_END,
   DRAG_FAILED,
@@ -115,11 +116,21 @@ enum {
 
 static guint signals[NUM_SIGNALS];
 
+static void gtk_drag_source_dnd_finished_cb   (GdkDrag             *drag,
+                                               GtkDragSource       *source);
+static void gtk_drag_source_drop_performed_cb (GdkDrag             *drag,
+                                               GtkDragSource       *source);
+static void gtk_drag_source_cancel_cb         (GdkDrag             *drag,
+                                               GdkDragCancelReason  reason,
+                                               GtkDragSource       *source);
+
+
 G_DEFINE_TYPE (GtkDragSource, gtk_drag_source, G_TYPE_OBJECT);
 
 static void
 gtk_drag_source_init (GtkDragSource *source)
 {
+  source->actions = GDK_ACTION_COPY;
 }
 
 static void
@@ -216,11 +227,21 @@ gtk_drag_source_class_init (GtkDragSourceClass *class)
        g_param_spec_flags ("actions",
                            P_("Actions"),
                            P_("Supported actions"),
-                           GDK_TYPE_DRAG_ACTION, 0,
+                           GDK_TYPE_DRAG_ACTION, GDK_ACTION_COPY,
                            G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
 
   g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
 
+  signals[PREPARE] =
+      g_signal_new (I_("prepare"),
+                    G_TYPE_FROM_CLASS (class),
+                    G_SIGNAL_RUN_LAST,
+                    0,
+                    NULL, NULL,
+                    NULL,
+                    G_TYPE_NONE, 2,
+                    G_TYPE_DOUBLE, G_TYPE_DOUBLE);
+
   /**
    * GtkDragSource::drag-begin:
    * @source: the #GtkDragSource
@@ -287,14 +308,6 @@ gtk_drag_source_class_init (GtkDragSourceClass *class)
                     GDK_TYPE_DRAG_CANCEL_REASON);
 }
 
-static void gtk_drag_source_dnd_finished_cb   (GdkDrag             *drag,
-                                               GtkDragSource       *source);
-static void gtk_drag_source_drop_performed_cb (GdkDrag             *drag,
-                                               GtkDragSource       *source);
-static void gtk_drag_source_cancel_cb         (GdkDrag             *drag,
-                                               GdkDragCancelReason  reason,
-                                               GtkDragSource       *source);
-
 static void
 drag_end (GtkDragSource *source,
           gboolean       success)
@@ -390,7 +403,13 @@ gtk_drag_source_drag_begin (GtkDragSource *source,
   dx = round (px) - x;
   dy = round (py) - y;
 
+  g_signal_emit (source, signals[PREPARE], 0, x, y);
+
+  if (source->content == NULL || source->actions == 0)
+    return;
+
   source->drag = gdk_drag_begin (surface, device, source->content, source->actions, dx, dy);
+
   if (source->drag == NULL)
     {
       g_print ("no drag :(\n");
@@ -439,21 +458,15 @@ gtk_drag_source_drag_begin (GtkDragSource *source,
 
 /**
  * gtk_drag_source_new:
- * @content: (nullable): the #GdkContentProvider to use, or %NULL
- * @actions: the actions to offer
  *
  * Creates a new #GtkDragSource object.
  *
  * Returns: the new #GtkDragSource
  */
 GtkDragSource *
-gtk_drag_source_new (GdkContentProvider *content,
-                     GdkDragAction       actions)
+gtk_drag_source_new (void)
 {
-  return g_object_new (GTK_TYPE_DRAG_SOURCE,
-                       "content", content,
-                       "actions", actions,
-                       NULL);
+  return g_object_new (GTK_TYPE_DRAG_SOURCE, NULL);
 }
 
 /**
index 8a7a8d0ec5fb8aca25d0e48e680326b4268ec4b9..bf8785beaa6a6d940056040d4f9f64a0f19730ab 100644 (file)
@@ -51,8 +51,7 @@ GDK_AVAILABLE_IN_ALL
 GType              gtk_drag_source_get_type  (void) G_GNUC_CONST;
 
 GDK_AVAILABLE_IN_ALL
-GtkDragSource      *gtk_drag_source_new        (GdkContentProvider *content,
-                                                GdkDragAction       actions);
+GtkDragSource      *gtk_drag_source_new        (void);
 
 GDK_AVAILABLE_IN_ALL
 void                gtk_drag_source_set_content (GtkDragSource     *source,
index 1b249b2fb6e136a2df8d7dec433a06e9bc47300c..4ec8a0f3758a99e2a8edd0970f63bbdb64c40cb4 100644 (file)
@@ -1469,7 +1469,9 @@ icon_drag_update_cb (GtkGestureDrag *gesture,
       GdkDevice *device;
 
       icon_info->in_drag = TRUE;
-      source = gtk_drag_source_new (icon_info->content, icon_info->actions);
+      source = gtk_drag_source_new ();
+      gtk_drag_source_set_content (source, icon_info->content);
+      gtk_drag_source_set_actions (source, icon_info->actions);
       paintable = gtk_widget_paintable_new (icon_info->widget);
       gtk_drag_source_set_icon (source, paintable, -2, -2);
       g_object_unref (paintable);
index caa589b5193a00ff8d90999da2830b790e16896f..49157c1da37ab37b3f7bc6ba36f53ac696df9a72 100644 (file)
@@ -6465,8 +6465,10 @@ gtk_icon_view_enable_model_drag_source (GtkIconView              *icon_view,
 
   g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), NULL);
 
+  icon_view->priv->source = gtk_drag_source_new ();
   content = gdk_content_provider_new_with_formats (formats, gtk_icon_view_drag_data_get, icon_view);
-  icon_view->priv->source = gtk_drag_source_new (content, actions);
+  gtk_drag_source_set_content (icon_view->priv->source, content);
+  gtk_drag_source_set_actions (icon_view->priv->source, actions);
   g_object_unref (content);
 
   g_signal_connect (icon_view->priv->source, "drag-begin",
index e29a164897c064007bbe80865318f8c77705f722..6b56dfcfdc92daccb706253328434853a2574009 100644 (file)
@@ -4720,7 +4720,8 @@ gtk_label_drag_gesture_update (GtkGestureDrag *gesture,
           GdkPaintable *paintable;
           GdkDevice *device;
 
-          source = gtk_drag_source_new (info->provider, GDK_ACTION_COPY);
+          source = gtk_drag_source_new ();
+          gtk_drag_source_set_content (source, info->provider);
           paintable = get_selection_paintable (label);
           gtk_drag_source_set_icon (source, paintable, 9, 0);
           g_clear_object (&paintable); 
index 3ae32f21ceb8be8b49827e32e87d90042ce414df..5c113516c6febbad6722e822f5b9a4f616384921 100644 (file)
@@ -332,9 +332,10 @@ gtk_link_button_init (GtkLinkButton *link_button)
   g_signal_connect (link_button, "query-tooltip",
                     G_CALLBACK (gtk_link_button_query_tooltip_cb), NULL);
 
+  source = gtk_drag_source_new ();
   content = g_object_new (GTK_TYPE_LINK_CONTENT, NULL);
   GTK_LINK_CONTENT (content)->link = link_button;
-  source = gtk_drag_source_new (content, GDK_ACTION_COPY);
+  gtk_drag_source_set_content (source, content);
   g_object_unref (content);
   gtk_drag_source_attach (source, GTK_WIDGET (link_button), GDK_BUTTON1_MASK);
 
index 37e087ba5bb88c06bdccbbff8a5d4a6cf1e7087e..e7bfdb0dc27ee63bed323f701cc0bc99c04f669a 100644 (file)
@@ -2877,9 +2877,11 @@ gtk_notebook_motion (GtkEventController *controller,
 
       priv->detached_tab = priv->cur_page;
 
+      source = gtk_drag_source_new ();
       content = gdk_content_provider_new_with_formats (priv->source_targets, gtk_notebook_drag_data_get, widget);
-      source = gtk_drag_source_new (content, GDK_ACTION_MOVE);
+      gtk_drag_source_set_content (source, content);
       g_object_unref (content);
+      gtk_drag_source_set_actions (source, GDK_ACTION_MOVE);
 
       g_signal_connect (source, "drag-begin", G_CALLBACK (gtk_notebook_drag_begin), notebook);
       g_signal_connect (source, "drag-end", G_CALLBACK (gtk_notebook_drag_end), notebook);
index 8c094cb9460f9d3ae0fae663f766bdd5e94d19a2..248ff308aee6ec879f59bacb21a13563c10880c6 100644 (file)
@@ -1366,10 +1366,11 @@ make_directory_button (GtkPathBar  *path_bar,
 
   g_value_init (&value, G_TYPE_FILE);
   g_value_set_object (&value, button_data->file);
+  source = gtk_drag_source_new ();
   content = gdk_content_provider_new_for_value (&value);
-  source = gtk_drag_source_new (content, GDK_ACTION_COPY);
-  gtk_drag_source_attach (source, button_data->button, GDK_BUTTON1_MASK);
+  gtk_drag_source_set_content (source, content);
   g_object_unref (content);
+  gtk_drag_source_attach (source, button_data->button, GDK_BUTTON1_MASK);
   g_value_unset (&value);
 
   return button_data;
index 5fcb8f6f57f2428c647bfbea2189246b5f16f2b3..8cec14201a374720730d7a2e0ff868daa02d1ac8 100644 (file)
@@ -3793,11 +3793,13 @@ on_row_dragged (GtkGestureDrag *gesture,
 
       sidebar->dragging_over = TRUE;
 
+      source = gtk_drag_source_new ();
       content = gdk_content_provider_new_with_formats (sidebar->source_targets,
                                                        drag_data_get_callback,
                                                        sidebar);
-      source = gtk_drag_source_new (content, GDK_ACTION_MOVE);
+      gtk_drag_source_set_content (source, content);
       g_object_unref (content);
+      gtk_drag_source_set_actions (source, GDK_ACTION_MOVE);
       g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin_callback), sidebar);
       g_signal_connect (source, "drag-end", G_CALLBACK (drag_end_callback), sidebar);
  
index f8959ce16dbd561cb21f3a09e2560734ae374889..2bbf9263a84eb8366ad348aa54fa9f9ddf74087f 100644 (file)
@@ -2846,9 +2846,10 @@ gtk_text_drag_gesture_update (GtkGestureDrag *gesture,
 
           paintable = gtk_text_util_create_drag_icon (widget, text, -1);
 
-          source = gtk_drag_source_new (priv->selection_content,
-                                        priv->editable ? GDK_ACTION_COPY | GDK_ACTION_MOVE
-                                                       : GDK_ACTION_COPY);
+          source = gtk_drag_source_new ();
+          gtk_drag_source_set_content (source, priv->selection_content);
+          if (priv->editable)
+            gtk_drag_source_set_actions (source, GDK_ACTION_COPY|GDK_ACTION_MOVE);
           gtk_drag_source_set_icon (source,
                                     paintable,
                                     priv->drag_start_x - ranges[0],
index 99f830f7474ca6c26a35a2fc40f261d74f577fe0..c261e32a62f7c2e694d41d23616555cfd4bce908 100644 (file)
@@ -7697,7 +7697,9 @@ gtk_text_view_start_selection_dnd (GtkTextView       *text_view,
   else
     actions = GDK_ACTION_COPY;
   content = gtk_text_buffer_get_selection_content (buffer);
-  source = gtk_drag_source_new (content, actions);
+  source = gtk_drag_source_new ();
+  gtk_drag_source_set_content (source, content);
+  gtk_drag_source_set_actions (source, actions);
   g_object_unref (content);
   if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
     {
index 42acb3f50bcc2a353e63a18cbfc853e24a6fa292..b88a2c0adff50735d98bcd5629449d1f2fbe5f7a 100644 (file)
@@ -12929,7 +12929,9 @@ gtk_tree_view_enable_model_drag_source (GtkTreeView       *tree_view,
   di = ensure_info (tree_view);
 
   content = gdk_content_provider_new_with_formats (formats, gtk_tree_view_drag_data_get, tree_view);
-  di->source = gtk_drag_source_new (content, actions);
+  di->source = gtk_drag_source_new ();
+  gtk_drag_source_set_content (di->source, content);
+  gtk_drag_source_set_actions (di->source, actions);
   g_object_unref (content);
   g_signal_connect (di->source, "drag-begin", G_CALLBACK (gtk_tree_view_drag_begin), tree_view);
   g_signal_connect (di->source, "drag-end", G_CALLBACK (gtk_tree_view_drag_end), tree_view);
index 4057e772355bce5d692106dea92d52e9260f4b41..ceefa34c5c44e4ff23410b598fab20c65f84dbed 100644 (file)
@@ -634,11 +634,14 @@ main (int argc, char **argv)
 
   button = gtk_button_new_with_label ("Drag Here\n");
 
+  source = gtk_drag_source_new ();
   g_value_init (&value, G_TYPE_STRING);
   g_value_set_string (&value, "I'm data!");
   content = gdk_content_provider_new_for_value (&value);
   g_value_unset (&value);
-  source = gtk_drag_source_new (content, GDK_ACTION_COPY | GDK_ACTION_MOVE);
+  gtk_drag_source_set_content (source, content);
+  g_object_unref (content);
+  gtk_drag_source_set_actions (source, GDK_ACTION_COPY|GDK_ACTION_MOVE);
   gtk_drag_source_attach (source, button, GDK_BUTTON1_MASK | GDK_BUTTON3_MASK);
   gtk_drag_source_set_icon (source, GDK_PAINTABLE (texture), 0, 0);
 
index b766d0460b87e63254744eb319d2a398a930aaa2..693da26ee2de66486a8b6303c54ffd12a34d3163 100644 (file)
@@ -298,7 +298,9 @@ make_image (const gchar *icon_name, int hotspot)
   formats = gtk_content_formats_add_text_targets (formats);
 
   content = gdk_content_provider_new_with_formats (formats, get_data, image);
-  source = gtk_drag_source_new (content, GDK_ACTION_COPY|GDK_ACTION_MOVE|GDK_ACTION_ASK);
+  source = gtk_drag_source_new ();
+  gtk_drag_source_set_content (source, content);
+  gtk_drag_source_set_actions (source, GDK_ACTION_COPY|GDK_ACTION_MOVE|GDK_ACTION_ASK);
   g_object_unref (content);
   update_source_icon (source, icon_name, hotspot);
 
@@ -342,7 +344,8 @@ make_spinner (void)
   g_value_init (&value, G_TYPE_STRING);
   g_value_set_string (&value, "ACTIVE");
   content = gdk_content_provider_new_for_value (&value);
-  source = gtk_drag_source_new (content, GDK_ACTION_COPY);
+  source = gtk_drag_source_new ();
+  gtk_drag_source_set_content (source, content);
   g_signal_connect (source, "drag-begin", G_CALLBACK (spinner_drag_begin), spinner);
   gtk_drag_source_attach (source, spinner, GDK_BUTTON1_MASK);
 
index 3cdf7872dc366ac15330715165d002cbd62cdf2a..2180544d045842412842c345ef0b1ff8dbd29eb6 100644 (file)
@@ -84,7 +84,9 @@ create_row (const gchar *text)
 
   bytes = g_bytes_new (&row, sizeof (gpointer));
   content = gdk_content_provider_new_for_bytes ("GTK_LIST_BOX_ROW", bytes);
-  source = gtk_drag_source_new (content, GDK_ACTION_MOVE);
+  source = gtk_drag_source_new ();
+  gtk_drag_source_set_content (source, content);
+  gtk_drag_source_set_actions (source, GDK_ACTION_MOVE);
   g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
   gtk_drag_source_attach (source, image, GDK_BUTTON1_MASK);
 
index 60c92ae79c429f6f7caf0d807a6400114ad81c51..ffbcacb7a52c64b3197e61568742afeefc888844 100644 (file)
@@ -618,7 +618,9 @@ main (gint argc, gchar **argv)
 
   targets = gdk_content_formats_new (target_table, G_N_ELEMENTS (target_table));
   content = gdk_content_provider_new_for_bytes (target_table[0], g_bytes_new ("", 1));
-  source = gtk_drag_source_new (content, GDK_ACTION_MOVE);
+  source = gtk_drag_source_new ();
+  gtk_drag_source_set_content (source, content);
+  gtk_drag_source_set_actions (source, GDK_ACTION_MOVE);
   g_object_unref (content);
   gtk_drag_source_attach (source, button, GDK_BUTTON1_MASK);
   dest = gtk_drop_target_new (targets, GDK_ACTION_MOVE);