[gtk/wip/otte/dnd: 5/9] dnd: Remove gdk_content_provider_new_with_callback()



commit da83457a60b4a1f375efb14f06f6be7c45ea0128
Author: Benjamin Otte <otte redhat com>
Date:   Sun Feb 16 16:22:37 2020 +0100

    dnd: Remove gdk_content_provider_new_with_callback()
    
    Content providers are meant to be immutable, apart from very special
    cases, but in those cases they need to emit
    gdk_content_provider_content_changed().
    
    Having a constructor that just uses a get_func invites abuse of this
    by not making developers aware of those requirments.
    In fact, all users in GTK failed to do this.
    
    Instead, code should use the GtkDragSource::prepare signal to create
    content providers when needed.
    
    The same problem exists with gdk_content_provider_new_with_formats(),
    but this commit doesn't touch that.

 demos/gtk-demo/clipboard.c          |  17 ++----
 demos/icon-browser/iconbrowserwin.c |  46 ++++++++-------
 gdk/gdkcontentproviderimpl.c        | 112 ------------------------------------
 gdk/gdkcontentproviderimpl.h        |   9 ---
 gtk/gtkcolorbutton.c                |  18 +++---
 gtk/gtkcolorswatch.c                |  18 +++---
 6 files changed, 48 insertions(+), 172 deletions(-)
---
diff --git a/demos/gtk-demo/clipboard.c b/demos/gtk-demo/clipboard.c
index 97d0579f1d..7acc83093d 100644
--- a/demos/gtk-demo/clipboard.c
+++ b/demos/gtk-demo/clipboard.c
@@ -138,23 +138,18 @@ drag_begin (GtkDragSource *source,
     }
 }
 
-static void
-get_texture (GValue   *value,
-             gpointer  data)
-{
-  GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (data));
-
-  if (GDK_IS_TEXTURE (paintable))
-    g_value_set_object (value, paintable);
-}
-
 static GdkContentProvider *
 prepare_drag (GtkDragSource *source,
               double         x,
               double         y,
               GtkWidget     *image)
 {
-  return gdk_content_provider_new_with_callback (GDK_TYPE_TEXTURE, get_texture, image, NULL);
+  GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (image));
+
+  if (!GDK_IS_TEXTURE (paintable))
+    return NULL;
+
+  return gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, paintable);
 }
 
 static void
diff --git a/demos/icon-browser/iconbrowserwin.c b/demos/icon-browser/iconbrowserwin.c
index d094c029d1..28731b6e43 100644
--- a/demos/icon-browser/iconbrowserwin.c
+++ b/demos/icon-browser/iconbrowserwin.c
@@ -406,47 +406,53 @@ drag_begin (GtkDragSource *source,
     }
 }
 
-static void
-get_texture (GValue   *value,
-             gpointer  data)
+static GdkContentProvider *
+drag_prepare_texture (GtkDragSource *source,
+                      double         x,
+                      double         y,
+                      GtkWidget     *widget)
 {
-  GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (data));
+  GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (widget));
+
+  if (!GDK_IS_TEXTURE (paintable))
+    return NULL;
 
-  if (GDK_IS_TEXTURE (paintable))
-    g_value_set_object (value, paintable);
+  return gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, paintable);
 }
 
-static void
-get_file (GValue   *value,
-          gpointer  data)
+static GdkContentProvider *
+drag_prepare_file (GtkDragSource *source,
+                   double         x,
+                   double         y,
+                   GtkWidget     *widget)
 {
+  GdkContentProvider *content;
   GtkIconTheme *icon_theme;
   const char *name;
   GtkIconPaintable *info;
 
-  name = gtk_image_get_icon_name (GTK_IMAGE (data));
-  icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (data)));
+  name = gtk_image_get_icon_name (GTK_IMAGE (widget));
+  icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
 
   info = gtk_icon_theme_lookup_icon (icon_theme,
                                      name,
                                      NULL,
                                      32, 1,
-                                     gtk_widget_get_direction (GTK_WIDGET (data)),
+                                     gtk_widget_get_direction (widget),
                                      0);
-  g_value_take_object (value, gtk_icon_paintable_get_file (info));
+  content = gdk_content_provider_new_typed (G_TYPE_FILE,  gtk_icon_paintable_get_file (info));
   g_object_unref (info);
+
+  return content;
 }
 
 static void
 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, NULL);
-  gtk_drag_source_set_content (source, content);
-  g_object_unref (content);
+  g_signal_connect (source, "prepare", G_CALLBACK (drag_prepare_texture), image);
   g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
   gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
 }
@@ -454,14 +460,10 @@ setup_image_dnd (GtkWidget *image)
 static void
 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, NULL);
-  gtk_drag_source_set_content (source, content);
-  g_object_unref (content);
-
+  g_signal_connect (source, "prepare", G_CALLBACK (drag_prepare_file), image);
   g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
   gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
 }
diff --git a/gdk/gdkcontentproviderimpl.c b/gdk/gdkcontentproviderimpl.c
index 3be95cbed7..05857c75a6 100644
--- a/gdk/gdkcontentproviderimpl.c
+++ b/gdk/gdkcontentproviderimpl.c
@@ -322,118 +322,6 @@ gdk_content_provider_new_for_bytes (const char *mime_type,
   return GDK_CONTENT_PROVIDER (content);
 }
 
-#define GDK_TYPE_CONTENT_PROVIDER_CALLBACK            (gdk_content_provider_callback_get_type ())
-#define GDK_CONTENT_PROVIDER_CALLBACK(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GDK_TYPE_CONTENT_PROVIDER_CALLBACK, GdkContentProviderCallback))
-
-typedef struct _GdkContentProviderCallback GdkContentProviderCallback;
-typedef struct _GdkContentProviderCallbackClass GdkContentProviderCallbackClass;
-
-struct _GdkContentProviderCallback
-{
-  GdkContentProvider parent;
-
-  GType type;
-  GdkContentProviderGetValueFunc func;
-  gpointer data;
-  GDestroyNotify notify;
-};
-
-struct _GdkContentProviderCallbackClass
-{
-  GdkContentProviderClass parent_class;
-};
-
-GType gdk_content_provider_callback_get_type (void) G_GNUC_CONST;
-
-G_DEFINE_TYPE (GdkContentProviderCallback, gdk_content_provider_callback, GDK_TYPE_CONTENT_PROVIDER)
-
-static GdkContentFormats *
-gdk_content_provider_callback_ref_formats (GdkContentProvider *provider)
-{
-  GdkContentProviderCallback *callback = GDK_CONTENT_PROVIDER_CALLBACK (provider);
-
-  return gdk_content_formats_new_for_gtype (callback->type);
-}
-
-static gboolean
-gdk_content_provider_callback_get_value (GdkContentProvider  *provider,
-                                         GValue              *value,
-                                         GError             **error)
-{
-  GdkContentProviderCallback *callback = GDK_CONTENT_PROVIDER_CALLBACK (provider);
-
-  if (G_VALUE_HOLDS (value, callback->type) && callback->func != NULL)
-    {
-      callback->func (value, callback->data);
-      return TRUE;
-    }
-
-  return GDK_CONTENT_PROVIDER_CLASS (gdk_content_provider_callback_parent_class)->get_value (provider, 
value, error);
-}
-
-static void
-gdk_content_provider_callback_dispose (GObject *gobject)
-{
-  GdkContentProviderCallback *self = GDK_CONTENT_PROVIDER_CALLBACK (gobject);
-
-  if (self->notify != NULL)
-    self->notify (self->data);
-
-  self->func = NULL;
-  self->data = NULL;
-  self->notify = NULL;
-
-  G_OBJECT_CLASS (gdk_content_provider_callback_parent_class)->dispose (gobject);
-}
-
-static void
-gdk_content_provider_callback_class_init (GdkContentProviderCallbackClass *class)
-{
-  GdkContentProviderClass *provider_class = GDK_CONTENT_PROVIDER_CLASS (class);
-  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
-
-  gobject_class->dispose = gdk_content_provider_callback_dispose;
-
-  provider_class->ref_formats = gdk_content_provider_callback_ref_formats;
-  provider_class->get_value = gdk_content_provider_callback_get_value;
-}
-
-static void
-gdk_content_provider_callback_init (GdkContentProviderCallback *content)
-{
-}
-
-/**
- * gdk_content_provider_new_for_callback: (constructor)
- * @type: the type that the callback provides
- * @func: (not nullable): callback to populate a #GValue
- * @data: (closure): data that gets passed to @func
- * @notify: a function to be called to free @data when the content provider
- *   goes away
- *
- * Create a content provider that provides data that is provided via a callback.
- *
- * Returns: a new #GdkContentProvider
- **/
-GdkContentProvider *
-gdk_content_provider_new_with_callback (GType                          type,
-                                        GdkContentProviderGetValueFunc func,
-                                        gpointer                       data,
-                                        GDestroyNotify                 notify)
-{
-  GdkContentProviderCallback *content;
-
-  g_return_val_if_fail (func != NULL, NULL);
-
-  content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_CALLBACK, NULL);
-  content->type = type;
-  content->func = func;
-  content->data = data;
-  content->notify = notify;
-  
-  return GDK_CONTENT_PROVIDER (content);
-}
-
 #define GDK_TYPE_CONTENT_PROVIDER_CALLBACK2            (gdk_content_provider_callback2_get_type ())
 #define GDK_CONTENT_PROVIDER_CALLBACK2(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GDK_TYPE_CONTENT_PROVIDER_CALLBACK2, GdkContentProviderCallback2))
 
diff --git a/gdk/gdkcontentproviderimpl.h b/gdk/gdkcontentproviderimpl.h
index c10158e5bb..907ed5015c 100644
--- a/gdk/gdkcontentproviderimpl.h
+++ b/gdk/gdkcontentproviderimpl.h
@@ -38,15 +38,6 @@ GDK_AVAILABLE_IN_ALL
 GdkContentProvider *    gdk_content_provider_new_for_bytes              (const char             *mime_type,
                                                                          GBytes                 *bytes);
 
-typedef void (*GdkContentProviderGetValueFunc) (GValue   *value,
-                                                gpointer  data);
-
-GDK_AVAILABLE_IN_ALL
-GdkContentProvider *    gdk_content_provider_new_with_callback (GType                           type,
-                                                                GdkContentProviderGetValueFunc  func,
-                                                                gpointer                        data,
-                                                                GDestroyNotify                  notify);
-
 typedef GBytes * (*GdkContentProviderGetBytesFunc) (const char *mime_type,
                                                     gpointer    data);
 
diff --git a/gtk/gtkcolorbutton.c b/gtk/gtkcolorbutton.c
index 7ae781cd47..4d304c1a46 100644
--- a/gtk/gtkcolorbutton.c
+++ b/gtk/gtkcolorbutton.c
@@ -285,12 +285,15 @@ gtk_color_button_drag_begin (GtkDragSource  *source,
   g_object_unref (paintable);
 }
 
-static void
-get_rgba_value (GValue   *value,
-                gpointer  data)
+static GdkContentProvider *
+gtk_color_button_drag_prepare (GtkDragSource  *source,
+                               double          x,
+                               double          y,
+                               GtkColorButton *button)
 {
-  GtkColorButtonPrivate *priv = gtk_color_button_get_instance_private (GTK_COLOR_BUTTON (data));
-  g_value_set_boxed (value, &priv->rgba);
+  GtkColorButtonPrivate *priv = gtk_color_button_get_instance_private (button);
+
+  return gdk_content_provider_new_typed (GDK_TYPE_RGBA, &priv->rgba);
 }
 
 static void
@@ -300,7 +303,6 @@ gtk_color_button_init (GtkColorButton *button)
   PangoLayout *layout;
   PangoRectangle rect;
   GdkContentFormats *targets;
-  GdkContentProvider *content;
   GtkDragSource *source;
   GtkDropTarget *dest;
 
@@ -333,9 +335,7 @@ gtk_color_button_init (GtkColorButton *button)
   gdk_content_formats_unref (targets);
 
   source = gtk_drag_source_new ();
-  content = gdk_content_provider_new_with_callback (GDK_TYPE_RGBA, get_rgba_value, button, NULL);
-  gtk_drag_source_set_content (source, content);
-  g_object_unref (content);
+  g_signal_connect (source, "prepare", G_CALLBACK (gtk_color_button_drag_prepare), button);
   g_signal_connect (source, "drag-begin", G_CALLBACK (gtk_color_button_drag_begin), button);
   gtk_widget_add_controller (priv->button, GTK_EVENT_CONTROLLER (source));
 
diff --git a/gtk/gtkcolorswatch.c b/gtk/gtkcolorswatch.c
index e66caa63e3..4a2ad7e93b 100644
--- a/gtk/gtkcolorswatch.c
+++ b/gtk/gtkcolorswatch.c
@@ -578,12 +578,15 @@ static const char *dnd_targets[] = {
   "application/x-color"
 };
 
-static void
-get_rgba_value (GValue   *value,
-                gpointer  data)
+static GdkContentProvider *
+gtk_color_swatch_drag_prepare (GtkDragSource  *source,
+                               double          x,
+                               double          y,
+                               GtkColorSwatch *swatch)
 {
-  GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (GTK_COLOR_SWATCH (data));
-  g_value_set_boxed (value, &priv->color);
+  GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (swatch);
+
+  return gdk_content_provider_new_typed (GDK_TYPE_RGBA, &priv->color);
 }
 
 void
@@ -594,13 +597,10 @@ gtk_color_swatch_set_rgba (GtkColorSwatch *swatch,
 
   if (!priv->has_color)
     {
-      GdkContentProvider *content;
       GtkDragSource *source;
 
       source = gtk_drag_source_new ();
-      content = gdk_content_provider_new_with_callback (GDK_TYPE_RGBA, get_rgba_value, swatch, NULL);
-      gtk_drag_source_set_content (source, content);
-      g_object_unref (content);
+      g_signal_connect (source, "prepare", G_CALLBACK (gtk_color_swatch_drag_prepare), swatch);
       g_signal_connect (source, "drag-begin", G_CALLBACK (gtk_color_swatch_drag_begin), swatch);
 
       gtk_widget_add_controller (GTK_WIDGET (swatch), GTK_EVENT_CONTROLLER (source));


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