forked from AuroraMiddleware/gtk
Merge branch 'wip/otte/dnd' into 'master'
some DND fixes See merge request GNOME/gtk!1440
This commit is contained in:
commit
47c8026e38
@ -162,6 +162,23 @@ gdk_drop_read_local_finish (GdkDrop *self,
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_add_formats (GdkDrop *self,
|
||||
GdkContentFormats *formats)
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
|
||||
formats = gdk_content_formats_union_deserialize_gtypes (gdk_content_formats_ref (formats));
|
||||
|
||||
if (priv->formats)
|
||||
{
|
||||
formats = gdk_content_formats_union (formats, priv->formats);
|
||||
gdk_content_formats_unref (priv->formats);
|
||||
}
|
||||
|
||||
priv->formats = formats;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drop_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
@ -186,10 +203,11 @@ gdk_drop_set_property (GObject *gobject,
|
||||
|
||||
case PROP_DRAG:
|
||||
priv->drag = g_value_dup_object (value);
|
||||
gdk_drop_add_formats (self, gdk_drag_get_formats (priv->drag));
|
||||
break;
|
||||
|
||||
case PROP_FORMATS:
|
||||
priv->formats = g_value_dup_boxed (value);
|
||||
gdk_drop_add_formats (self, g_value_get_boxed (value));
|
||||
g_assert (priv->formats != NULL);
|
||||
break;
|
||||
|
||||
|
@ -1127,6 +1127,10 @@ data_offer_offer (void *data,
|
||||
return;
|
||||
}
|
||||
|
||||
/* skip magic mime types */
|
||||
if (g_str_equal (type, GDK_WAYLAND_LOCAL_DND_MIME_TYPE))
|
||||
return;
|
||||
|
||||
gdk_content_formats_builder_add_mime_type (seat->pending_builder, type);
|
||||
}
|
||||
|
||||
|
@ -358,6 +358,7 @@ gdk_wayland_drag_create_data_source (GdkDrag *drag)
|
||||
g_message ("create data source, mime types=%s", s);
|
||||
g_free (s);});
|
||||
|
||||
wl_data_source_offer (drag_wayland->data_source, GDK_WAYLAND_LOCAL_DND_MIME_TYPE);
|
||||
for (i = 0; i < n_mimetypes; i++)
|
||||
wl_data_source_offer (drag_wayland->data_source, mimetypes[i]);
|
||||
|
||||
|
@ -97,6 +97,13 @@ gdk_wayland_drop_drop_set_status (GdkWaylandDrop *drop_wayland,
|
||||
const char *const *mimetypes;
|
||||
gsize i, n_mimetypes;
|
||||
|
||||
/* This is a local drag, treat it like that */
|
||||
if (gdk_drop_get_drag (GDK_DROP (drop_wayland)))
|
||||
{
|
||||
wl_data_offer_accept (drop_wayland->offer, drop_wayland->serial, GDK_WAYLAND_LOCAL_DND_MIME_TYPE);
|
||||
return;
|
||||
}
|
||||
|
||||
mimetypes = gdk_content_formats_get_mime_types (gdk_drop_get_formats (GDK_DROP (drop_wayland)), &n_mimetypes);
|
||||
for (i = 0; i < n_mimetypes; i++)
|
||||
{
|
||||
|
@ -44,6 +44,13 @@
|
||||
#define WL_SURFACE_HAS_BUFFER_SCALE 3
|
||||
#define WL_POINTER_HAS_FRAME 5
|
||||
|
||||
/* the magic mime type we use for local DND operations.
|
||||
* We offer it to every dnd operation, but will strip it out on the drop
|
||||
* site unless we can prove it's a local DND - then we will use only
|
||||
* this type
|
||||
*/
|
||||
#define GDK_WAYLAND_LOCAL_DND_MIME_TYPE "application/x-gtk-local-dnd"
|
||||
|
||||
GdkKeymap *_gdk_wayland_keymap_new (GdkDisplay *display);
|
||||
void _gdk_wayland_keymap_update_from_fd (GdkKeymap *keymap,
|
||||
uint32_t format,
|
||||
|
@ -566,14 +566,12 @@ gtk_drop_target_accept (GtkDropTarget *dest,
|
||||
{
|
||||
GdkDragAction dest_actions;
|
||||
GdkDragAction actions;
|
||||
GdkAtom target;
|
||||
|
||||
dest_actions = gtk_drop_target_get_actions (dest);
|
||||
|
||||
actions = dest_actions & gdk_drop_get_actions (drop);
|
||||
target = gtk_drop_target_match (dest, drop);
|
||||
|
||||
return actions && target;
|
||||
return actions && gdk_content_formats_match (dest->formats, gdk_drop_get_formats (drop));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1,8 +1,21 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static const char *entries[] = {
|
||||
"GTK_LIST_BOX_ROW"
|
||||
};
|
||||
static GdkContentProvider *
|
||||
prepare (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *row)
|
||||
{
|
||||
GdkContentProvider *content;
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
g_value_init (&value, GTK_TYPE_LIST_BOX_ROW);
|
||||
g_value_set_object (&value, row);
|
||||
content = gdk_content_provider_new_for_value (&value);
|
||||
g_value_unset (&value);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin (GtkDragSource *source,
|
||||
@ -29,46 +42,49 @@ got_row (GObject *src,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkDropTarget *dest = GTK_DROP_TARGET (src);
|
||||
GdkDrop *drop = GDK_DROP (src);
|
||||
GtkWidget *target = data;
|
||||
GtkWidget *row;
|
||||
GtkWidget *source;
|
||||
int pos;
|
||||
GtkSelectionData *selection_data;
|
||||
|
||||
selection_data = gtk_drop_target_read_selection_finish (dest, result, NULL);
|
||||
source = g_value_get_object (gdk_drop_read_value_finish (drop, result, NULL));
|
||||
if (source == NULL)
|
||||
{
|
||||
gdk_drop_finish (drop, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
pos = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (target));
|
||||
row = (gpointer)* (gpointer*)gtk_selection_data_get_data (selection_data);
|
||||
source = gtk_widget_get_ancestor (row, GTK_TYPE_LIST_BOX_ROW);
|
||||
|
||||
gtk_selection_data_free (selection_data);
|
||||
|
||||
if (source == target)
|
||||
{
|
||||
gdk_drop_finish (drop, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_ref (source);
|
||||
gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (source)), source);
|
||||
gtk_list_box_insert (GTK_LIST_BOX (gtk_widget_get_parent (target)), source, pos);
|
||||
g_object_unref (source);
|
||||
|
||||
gdk_drop_finish (drop, GDK_ACTION_MOVE);
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
drag_drop (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y,
|
||||
gpointer data)
|
||||
{
|
||||
gtk_drop_target_read_selection (dest, "GTK_LIST_BOX_ROW", NULL, got_row, data);
|
||||
gdk_drop_read_value_async (drop, GTK_TYPE_LIST_BOX_ROW, G_PRIORITY_DEFAULT, NULL, got_row, data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_row (const gchar *text)
|
||||
{
|
||||
GtkWidget *row, *box, *label, *image;
|
||||
GBytes *bytes;
|
||||
GdkContentProvider *content;
|
||||
GdkContentFormats *targets;
|
||||
GtkDragSource *source;
|
||||
GtkDropTarget *dest;
|
||||
@ -83,15 +99,13 @@ create_row (const gchar *text)
|
||||
gtk_container_add (GTK_CONTAINER (box), label);
|
||||
gtk_container_add (GTK_CONTAINER (box), image);
|
||||
|
||||
bytes = g_bytes_new (&row, sizeof (gpointer));
|
||||
content = gdk_content_provider_new_for_bytes ("GTK_LIST_BOX_ROW", bytes);
|
||||
source = gtk_drag_source_new ();
|
||||
gtk_drag_source_set_content (source, content);
|
||||
gtk_drag_source_set_actions (source, GDK_ACTION_MOVE);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (prepare), row);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
targets = gdk_content_formats_new (entries, 1);
|
||||
targets = gdk_content_formats_new_for_gtype (GTK_TYPE_LIST_BOX_ROW);
|
||||
dest = gtk_drop_target_new (targets, GDK_ACTION_MOVE);
|
||||
g_signal_connect (dest, "drag-drop", G_CALLBACK (drag_drop), row);
|
||||
gtk_widget_add_controller (GTK_WIDGET (row), GTK_EVENT_CONTROLLER (dest));
|
||||
|
Loading…
Reference in New Issue
Block a user