Merge branch 'wip/otte/for-master' into 'master'

Wip/otte/for master

See merge request GNOME/gtk!1496
This commit is contained in:
Benjamin Otte 2020-03-02 21:32:20 +00:00
commit 3ef1dca51c
3 changed files with 43 additions and 16 deletions

View File

@ -343,6 +343,7 @@
<xi:include href="xml/gtkdragsource.xml"/> <xi:include href="xml/gtkdragsource.xml"/>
<xi:include href="xml/gtkdragicon.xml"/> <xi:include href="xml/gtkdragicon.xml"/>
<xi:include href="xml/gtkdroptarget.xml"/> <xi:include href="xml/gtkdroptarget.xml"/>
<xi:include href="xml/gtkdroptargetasync.xml"/>
</chapter> </chapter>
</part> </part>

View File

@ -785,14 +785,11 @@ gdk_drop_read_value_internal (GdkDrop *self,
if (priv->drag) if (priv->drag)
{ {
GError *error = NULL; GError *error = NULL;
GdkContentProvider *content;
gboolean res; gboolean res;
g_object_get (priv->drag, "content", &content, NULL); res = gdk_content_provider_get_value (gdk_drag_get_content (priv->drag),
value,
res = gdk_content_provider_get_value (content, value, &error); &error);
g_object_unref (content);
if (res) if (res)
{ {

View File

@ -45,25 +45,25 @@
* receive Drag-and-Drop operations. * receive Drag-and-Drop operations.
* *
* The most basic way to use a #GtkDropTarget to receive drops on a * 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 * #GType of the data you want to receive and connect to the
* GtkDropTarget::drop signal to receive the data. * GtkDropTarget::drop signal to receive the data.
* *
* #GtkDropTarget supports more options, such as: * #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 * and the gtk_drop_target_reject() function to let other drop
* targets handle the drop * targets handle the drop
* * tracking an ongoing drag operation before the drop via the * * tracking an ongoing drag operation before the drop via the
* GtkDropTarget::enter, GtkDropTarget::motion and * #GtkDropTarget::enter, #GtkDropTarget::motion and
* GtkDropTarget::leave signals * #GtkDropTarget::leave signals
* * configuring how to receive data by setting the * * configuring how to receive data by setting the
* GtkDropTarget:preload property and listening for its availability * #GtkDropTarget:preload property and listening for its availability
* via the GtkDropTarget:value property * via the #GtkDropTarget:value property
* *
* However, #GtkDropTarget is ultimately modeled in a synchronous way * However, #GtkDropTarget is ultimately modeled in a synchronous way
* and only supports data transferred via #GType. * 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. * object gives you this ability.
* *
* While a pointer is dragged over the drop target's widget and the drop * While a pointer is dragged over the drop target's widget and the drop
@ -222,9 +222,31 @@ gtk_drop_target_load_done (GObject *source,
gtk_drop_target_do_drop (self); 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 static gboolean
gtk_drop_target_load (GtkDropTarget *self) gtk_drop_target_load (GtkDropTarget *self)
{ {
GType type;
g_assert (self->drop); g_assert (self->drop);
if (G_IS_VALUE (&self->value)) if (G_IS_VALUE (&self->value))
@ -233,10 +255,15 @@ gtk_drop_target_load (GtkDropTarget *self)
if (self->cancellable) if (self->cancellable)
return FALSE; 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 (); self->cancellable = g_cancellable_new ();
gdk_drop_read_value_async (self->drop, gdk_drop_read_value_async (self->drop,
gdk_content_formats_match_gtype (self->formats, gdk_drop_get_formats (self->drop)), type,
G_PRIORITY_DEFAULT, G_PRIORITY_DEFAULT,
self->cancellable, self->cancellable,
gtk_drop_target_load_done, gtk_drop_target_load_done,
@ -590,11 +617,13 @@ gtk_drop_target_class_init (GtkDropTargetClass *class)
* huge amounts of data by accident. * huge amounts of data by accident.
* For example, if somebody drags a full document of gigabytes of text * For example, if somebody drags a full document of gigabytes of text
* from a text editor across a widget with a preloading drop target, * 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. * elsewhere.
* *
* For a lot of data formats, the amount of data is very small (like * 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] = properties[PROP_PRELOAD] =
g_param_spec_boolean ("preload", g_param_spec_boolean ("preload",