[gtk/gi-fixes: 1/6] Add a notify function to GdkContentProvider
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gi-fixes: 1/6] Add a notify function to GdkContentProvider
- Date: Tue, 11 Feb 2020 17:45:11 +0000 (UTC)
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]