From c0a63e6dd2d5c5dfbe0a226d9ba38c82598a452a Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 2 Mar 2020 21:26:08 +0100 Subject: dnd: Fix some documentation gotchas --- docs/reference/gtk/gtk4-docs.xml | 1 + gtk/gtkdroptarget.c | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/reference/gtk/gtk4-docs.xml b/docs/reference/gtk/gtk4-docs.xml index 732173b671..aabc016df4 100644 --- a/docs/reference/gtk/gtk4-docs.xml +++ b/docs/reference/gtk/gtk4-docs.xml @@ -343,6 +343,7 @@ + diff --git a/gtk/gtkdroptarget.c b/gtk/gtkdroptarget.c index 3bd86fa93a..093fc0af1f 100644 --- a/gtk/gtkdroptarget.c +++ b/gtk/gtkdroptarget.c @@ -45,25 +45,25 @@ * receive Drag-and-Drop operations. * * The most basic way to use a #GtkDropTarget to receive drops on a - * widget, is to create it via gtk_drop_target_new(), passing in the + * widget is to create it via gtk_drop_target_new() passing in the * #GType of the data you want to receive and connect to the * GtkDropTarget::drop signal to receive the data. * * #GtkDropTarget supports more options, such as: * - * * rejecting potential drops via the GtkDropTarget::accept signal + * * rejecting potential drops via the #GtkDropTarget::accept signal * and the gtk_drop_target_reject() function to let other drop * targets handle the drop * * tracking an ongoing drag operation before the drop via the - * GtkDropTarget::enter, GtkDropTarget::motion and - * GtkDropTarget::leave signals + * #GtkDropTarget::enter, #GtkDropTarget::motion and + * #GtkDropTarget::leave signals * * configuring how to receive data by setting the - * GtkDropTarget:preload property and listening for its availability - * via the GtkDropTarget:value property + * #GtkDropTarget:preload property and listening for its availability + * via the #GtkDropTarget:value property * * However, #GtkDropTarget is ultimately modeled in a synchronous way * and only supports data transferred via #GType. - * If you want full control over an ongoing drop, the #GdkDropTargetAsync + * If you want full control over an ongoing drop, the #GtkDropTargetAsync * object gives you this ability. * * While a pointer is dragged over the drop target's widget and the drop @@ -590,11 +590,13 @@ gtk_drop_target_class_init (GtkDropTargetClass *class) * huge amounts of data by accident. * For example, if somebody drags a full document of gigabytes of text * from a text editor across a widget with a preloading drop target, - * this data will be downlaoded, even if the data is ultimately dropped + * this data will be downloaded, even if the data is ultimately dropped * elsewhere. * * For a lot of data formats, the amount of data is very small (like - * %GDK_TYPE_RGBA), so enabling this property does not hurt at all. + * %GDK_TYPE_RGBA), so enabling this property does not hurt at all. + * And for local-only drag'n'drop operations, no data transfer is done, + * so enabling it there is free. */ properties[PROP_PRELOAD] = g_param_spec_boolean ("preload", -- cgit v1.2.1 From 7427f4f311401e45a5d92cda91726606ba96ee8d Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 2 Mar 2020 21:45:42 +0100 Subject: drop: Don't use g_object_get() --- gdk/gdkdrop.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/gdk/gdkdrop.c b/gdk/gdkdrop.c index 20676937e1..1df4a4ffdb 100644 --- a/gdk/gdkdrop.c +++ b/gdk/gdkdrop.c @@ -785,14 +785,11 @@ gdk_drop_read_value_internal (GdkDrop *self, if (priv->drag) { GError *error = NULL; - GdkContentProvider *content; gboolean res; - g_object_get (priv->drag, "content", &content, NULL); - - res = gdk_content_provider_get_value (content, value, &error); - - g_object_unref (content); + res = gdk_content_provider_get_value (gdk_drag_get_content (priv->drag), + value, + &error); if (res) { -- cgit v1.2.1 From 2e55c9cf8c03be9a67eb515a4bd973bacf35d701 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 2 Mar 2020 21:45:59 +0100 Subject: droptarget: Fast-path local value load This way, we can ensure that for local same-type drops the GValue is set when ::enter is emitted. This is the common case for dnd between widgets inside larger applications, so it's worth it to speed it up. --- gtk/gtkdroptarget.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/gtk/gtkdroptarget.c b/gtk/gtkdroptarget.c index 093fc0af1f..89e91a9a9a 100644 --- a/gtk/gtkdroptarget.c +++ b/gtk/gtkdroptarget.c @@ -222,9 +222,31 @@ gtk_drop_target_load_done (GObject *source, gtk_drop_target_do_drop (self); } +static gboolean +gtk_drop_target_load_local (GtkDropTarget *self, + GType type) +{ + GdkDrag *drag; + + drag = gdk_drop_get_drag (self->drop); + if (drag == NULL) + return FALSE; + + g_value_init (&self->value, type); + if (gdk_content_provider_get_value (gdk_drag_get_content (drag), + &self->value, + NULL)) + return TRUE; + + g_value_unset (&self->value); + return FALSE; +} + static gboolean gtk_drop_target_load (GtkDropTarget *self) { + GType type; + g_assert (self->drop); if (G_IS_VALUE (&self->value)) @@ -233,10 +255,15 @@ gtk_drop_target_load (GtkDropTarget *self) if (self->cancellable) return FALSE; + type = gdk_content_formats_match_gtype (self->formats, gdk_drop_get_formats (self->drop)); + + if (gtk_drop_target_load_local (self, type)) + return TRUE; + self->cancellable = g_cancellable_new (); gdk_drop_read_value_async (self->drop, - gdk_content_formats_match_gtype (self->formats, gdk_drop_get_formats (self->drop)), + type, G_PRIORITY_DEFAULT, self->cancellable, gtk_drop_target_load_done, -- cgit v1.2.1