[gtk/gi-fixes: 1/6] Add a notify function to GdkContentProvider



commit e8da00729723891fe78dde35a00b6399d4739f48
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Tue Feb 11 17:24:01 2020 +0000

    Add a notify function to GdkContentProvider
    
    The callback-based content providers need a GDestroyNotify function to
    free the data passed to them on construction, otherwise they are going
    to leak.

 demos/gtk-demo/clipboard.c          |  2 +-
 demos/icon-browser/iconbrowserwin.c |  4 +--
 gdk/gdkcontentproviderimpl.c        | 58 +++++++++++++++++++++++++++++++++----
 gdk/gdkcontentproviderimpl.h        |  6 ++--
 gtk/gtkcolorbutton.c                |  2 +-
 gtk/gtkcolorswatch.c                |  3 +-
 gtk/gtkiconview.c                   |  5 ++--
 gtk/gtknotebook.c                   |  3 +-
 gtk/gtkplacessidebar.c              |  3 +-
 gtk/gtktreeview.c                   |  5 +++-
 tests/testdnd2.c                    |  2 +-
 11 files changed, 74 insertions(+), 19 deletions(-)
---
diff --git a/demos/gtk-demo/clipboard.c b/demos/gtk-demo/clipboard.c
index e71fb47047..c5a83d7e05 100644
--- a/demos/gtk-demo/clipboard.c
+++ b/demos/gtk-demo/clipboard.c
@@ -154,7 +154,7 @@ prepare_drag (GtkDragSource *source,
               double         y,
               GtkWidget     *image)
 {
-  return gdk_content_provider_new_with_callback (GDK_TYPE_TEXTURE, get_texture, image);
+  return gdk_content_provider_new_with_callback (GDK_TYPE_TEXTURE, get_texture, image, NULL);
 }
 
 static void
diff --git a/demos/icon-browser/iconbrowserwin.c b/demos/icon-browser/iconbrowserwin.c
index c0fe825031..d094c029d1 100644
--- a/demos/icon-browser/iconbrowserwin.c
+++ b/demos/icon-browser/iconbrowserwin.c
@@ -444,7 +444,7 @@ setup_image_dnd (GtkWidget *image)
   GtkDragSource *source;
 
   source = gtk_drag_source_new ();
-  content = gdk_content_provider_new_with_callback (GDK_TYPE_TEXTURE, get_texture, image);
+  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, "drag-begin", G_CALLBACK (drag_begin), image);
@@ -458,7 +458,7 @@ setup_scalable_image_dnd (GtkWidget *image)
   GtkDragSource *source;
 
   source = gtk_drag_source_new ();
-  content = gdk_content_provider_new_with_callback (G_TYPE_FILE, get_file, image);
+  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);
 
diff --git a/gdk/gdkcontentproviderimpl.c b/gdk/gdkcontentproviderimpl.c
index c114e8c3b2..e5c86a396c 100644
--- a/gdk/gdkcontentproviderimpl.c
+++ b/gdk/gdkcontentproviderimpl.c
@@ -295,6 +295,7 @@ struct _GdkContentProviderCallback
   GType type;
   GdkContentProviderGetValueFunc func;
   gpointer data;
+  GDestroyNotify notify;
 };
 
 struct _GdkContentProviderCallbackClass
@@ -330,10 +331,28 @@ gdk_content_provider_callback_get_value (GdkContentProvider  *provider,
   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;
@@ -345,10 +364,12 @@ gdk_content_provider_callback_init (GdkContentProviderCallback *content)
 }
 
 /**
- * gdk_content_provider_new_for_callback:
+ * gdk_content_provider_new_for_callback: (constructor)
  * @type: the type that the callback provides
- * @func: callback to populate a #GValue
+ * @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.
  *
@@ -357,14 +378,18 @@ gdk_content_provider_callback_init (GdkContentProviderCallback *content)
 GdkContentProvider *
 gdk_content_provider_new_with_callback (GType                          type,
                                         GdkContentProviderGetValueFunc func,
-                                        gpointer                       data)
+                                        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);
 }
@@ -382,6 +407,7 @@ struct _GdkContentProviderCallback2
   GdkContentFormats *formats;
   GdkContentProviderGetBytesFunc func;
   gpointer data;
+  GDestroyNotify notify;
 };
 
 struct _GdkContentProviderCallback2Class
@@ -472,10 +498,28 @@ gdk_content_provider_callback2_write_mime_type_finish (GdkContentProvider *provi
   return g_task_propagate_boolean (G_TASK (result), error);
 }
 
+static void
+gdk_content_provider_callback2_dispose (GObject *gobject)
+{
+  GdkContentProviderCallback2 *self = GDK_CONTENT_PROVIDER_CALLBACK2 (gobject);
+
+  if (self->notify != NULL)
+    self->notify (self->data);
+
+  self->notify = NULL;
+  self->data = NULL;
+  self->func = NULL;
+
+  G_OBJECT_CLASS (gdk_content_provider_callback2_parent_class)->dispose (gobject);
+}
+
 static void
 gdk_content_provider_callback2_class_init (GdkContentProviderCallback2Class *class)
 {
   GdkContentProviderClass *provider_class = GDK_CONTENT_PROVIDER_CLASS (class);
+  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+  gobject_class->dispose = gdk_content_provider_callback2_dispose;
 
   provider_class->ref_formats = gdk_content_provider_callback2_ref_formats;
   provider_class->write_mime_type_async = gdk_content_provider_callback2_write_mime_type_async;
@@ -491,7 +535,9 @@ gdk_content_provider_callback2_init (GdkContentProviderCallback2 *content)
  * gdk_content_provider_new_with_formats:
  * @formats: formats to advertise
  * @func: callback to populate a #GValue
- * @data: data that gets passed to @func
+ * @data: (closure func): data that gets passed to @func
+ * @notify: a function called to free @data when the content provider
+ *   goes away
  *
  * Create a content provider that provides data that is provided via a callback.
  *
@@ -500,13 +546,15 @@ gdk_content_provider_callback2_init (GdkContentProviderCallback2 *content)
 GdkContentProvider *
 gdk_content_provider_new_with_formats (GdkContentFormats              *formats,
                                        GdkContentProviderGetBytesFunc  func,
-                                       gpointer                        data)
+                                       gpointer                        data,
+                                       GDestroyNotify                  notify)
 {
   GdkContentProviderCallback2 *content;
   content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_CALLBACK2, NULL);
   content->formats = gdk_content_formats_union_serialize_mime_types (gdk_content_formats_ref (formats));
   content->func = func;
   content->data = data;
+  content->notify = notify;
   
   return GDK_CONTENT_PROVIDER (content);
 }
diff --git a/gdk/gdkcontentproviderimpl.h b/gdk/gdkcontentproviderimpl.h
index 19ac6969e1..cea0b6b667 100644
--- a/gdk/gdkcontentproviderimpl.h
+++ b/gdk/gdkcontentproviderimpl.h
@@ -41,7 +41,8 @@ typedef void (*GdkContentProviderGetValueFunc) (GValue   *value,
 GDK_AVAILABLE_IN_ALL
 GdkContentProvider *    gdk_content_provider_new_with_callback (GType                           type,
                                                                 GdkContentProviderGetValueFunc  func,
-                                                                gpointer                        data);
+                                                                gpointer                        data,
+                                                                GDestroyNotify                  notify);
 
 typedef GBytes * (*GdkContentProviderGetBytesFunc) (const char *mime_type,
                                                     gpointer    data);
@@ -49,7 +50,8 @@ typedef GBytes * (*GdkContentProviderGetBytesFunc) (const char *mime_type,
 GDK_AVAILABLE_IN_ALL
 GdkContentProvider *    gdk_content_provider_new_with_formats  (GdkContentFormats              *formats,
                                                                 GdkContentProviderGetBytesFunc  func,
-                                                                gpointer                        data);
+                                                                gpointer                        data,
+                                                                GDestroyNotify                  notify);
 
 G_END_DECLS
 
diff --git a/gtk/gtkcolorbutton.c b/gtk/gtkcolorbutton.c
index 77e5086941..7ae781cd47 100644
--- a/gtk/gtkcolorbutton.c
+++ b/gtk/gtkcolorbutton.c
@@ -333,7 +333,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);
+  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, "drag-begin", G_CALLBACK (gtk_color_button_drag_begin), button);
diff --git a/gtk/gtkcolorswatch.c b/gtk/gtkcolorswatch.c
index 270556ed78..e66caa63e3 100644
--- a/gtk/gtkcolorswatch.c
+++ b/gtk/gtkcolorswatch.c
@@ -598,7 +598,7 @@ gtk_color_swatch_set_rgba (GtkColorSwatch *swatch,
       GtkDragSource *source;
 
       source = gtk_drag_source_new ();
-      content = gdk_content_provider_new_with_callback (GDK_TYPE_RGBA, get_rgba_value, swatch);
+      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, "drag-begin", G_CALLBACK (gtk_color_swatch_drag_begin), swatch);
@@ -618,7 +618,6 @@ gtk_color_swatch_set_rgba (GtkColorSwatch *swatch,
     {
       gtk_widget_add_css_class (GTK_WIDGET (swatch), "dark");
       gtk_widget_remove_css_class (GTK_WIDGET (swatch), "light");
-
     }
 
   gtk_widget_queue_draw (GTK_WIDGET (swatch));
diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c
index 1d8c7901ea..1cd7b1c3a7 100644
--- a/gtk/gtkiconview.c
+++ b/gtk/gtkiconview.c
@@ -6055,7 +6055,8 @@ gtk_icon_view_maybe_begin_drag (GtkIconView *icon_view,
 
   content = gdk_content_provider_new_with_formats (icon_view->priv->source_formats,
                                                    gtk_icon_view_drag_data_get,
-                                                   icon_view);
+                                                   icon_view,
+                                                   NULL);
 
   drag = gdk_drag_begin (surface,
                          device,
@@ -6064,7 +6065,7 @@ gtk_icon_view_maybe_begin_drag (GtkIconView *icon_view,
                          icon_view->priv->press_start_x,
                          icon_view->priv->press_start_y);
 
-   g_object_unref (content);
+  g_object_unref (content);
 
   g_signal_connect (drag, "dnd-finished", G_CALLBACK (gtk_icon_view_dnd_finished_cb), icon_view);
 
diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c
index 57fd7172f1..6f7894defe 100644
--- a/gtk/gtknotebook.c
+++ b/gtk/gtknotebook.c
@@ -2882,7 +2882,8 @@ gtk_notebook_motion (GtkEventController *controller,
 
       content = gdk_content_provider_new_with_formats (priv->source_targets,
                                                        gtk_notebook_drag_data_get,
-                                                       widget);
+                                                       widget,
+                                                       NULL);
       drag = gdk_drag_begin (surface, device, content, GDK_ACTION_MOVE, priv->drag_begin_x, 
priv->drag_begin_y);
       g_object_unref (content);
 
diff --git a/gtk/gtkplacessidebar.c b/gtk/gtkplacessidebar.c
index 4ed3f3ae3c..92bee5066f 100644
--- a/gtk/gtkplacessidebar.c
+++ b/gtk/gtkplacessidebar.c
@@ -3759,7 +3759,8 @@ on_row_dragged (GtkGestureDrag *gesture,
 
       content = gdk_content_provider_new_with_formats (sidebar->source_targets,
                                                        drag_data_get_callback,
-                                                       sidebar);
+                                                       sidebar,
+                                                       NULL);
  
       surface = gtk_native_get_surface (gtk_widget_get_native (GTK_WIDGET (sidebar)));
       device = gtk_gesture_get_device (GTK_GESTURE (gesture));
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 011a97c99c..27b0576477 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -7109,7 +7109,10 @@ gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view)
 
   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);
+  content = gdk_content_provider_new_with_formats (di->source_formats,
+                                                   gtk_tree_view_drag_data_get,
+                                                   tree_view,
+                                                   NULL);
 
   drag = gdk_drag_begin (surface, device, content, di->source_actions, start_x, start_y);
 
diff --git a/tests/testdnd2.c b/tests/testdnd2.c
index 5341459989..84ba7abc6e 100644
--- a/tests/testdnd2.c
+++ b/tests/testdnd2.c
@@ -399,7 +399,7 @@ make_image (const gchar *icon_name, int hotspot)
   gdk_content_formats_builder_add_gtype (builder, G_TYPE_STRING);
   formats = gdk_content_formats_builder_free_to_formats (builder);
 
-  content = gdk_content_provider_new_with_formats (formats, get_data, image);
+  content = gdk_content_provider_new_with_formats (formats, get_data, image, NULL);
   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);


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