entry: Port icon dnd to GtkDragSource

This requires a small change in the api,
since we need to provide a GdkContentProvider now.
This commit is contained in:
Matthias Clasen 2019-12-31 02:45:02 -05:00
parent 2803a15a51
commit 337057eb35
3 changed files with 29 additions and 54 deletions

View File

@ -70,6 +70,8 @@
#include "gtkwindow.h" #include "gtkwindow.h"
#include "gtknative.h" #include "gtknative.h"
#include "gtkgestureclick.h" #include "gtkgestureclick.h"
#include "gtkdragsource.h"
#include "gtkwidgetpaintable.h"
#include "a11y/gtkentryaccessible.h" #include "a11y/gtkentryaccessible.h"
@ -172,7 +174,7 @@ struct _EntryIconInfo
guint in_drag : 1; guint in_drag : 1;
GdkDragAction actions; GdkDragAction actions;
GdkContentFormats *target_list; GdkContentProvider *content;
}; };
enum { enum {
@ -1320,8 +1322,7 @@ gtk_entry_finalize (GObject *object)
if (icon_info == NULL) if (icon_info == NULL)
continue; continue;
if (icon_info->target_list != NULL) g_clear_object (&icon_info->content);
gdk_content_formats_unref (icon_info->target_list);
gtk_widget_unparent (icon_info->widget); gtk_widget_unparent (icon_info->widget);
@ -1462,17 +1463,21 @@ icon_drag_update_cb (GtkGestureDrag *gesture,
pos = get_icon_position_from_controller (entry, GTK_EVENT_CONTROLLER (gesture)); pos = get_icon_position_from_controller (entry, GTK_EVENT_CONTROLLER (gesture));
icon_info = priv->icons[pos]; icon_info = priv->icons[pos];
if (icon_info->target_list != NULL && if (icon_info->content != NULL &&
gtk_drag_check_threshold (icon_info->widget, gtk_drag_check_threshold (icon_info->widget, start_x, start_y, x, y))
start_x, start_y,
x, y))
{ {
GtkDragSource *source;
GdkPaintable *paintable;
GdkDevice *device;
icon_info->in_drag = TRUE; icon_info->in_drag = TRUE;
gtk_drag_begin (GTK_WIDGET (entry), source = gtk_drag_source_new (icon_info->content, icon_info->actions);
gtk_gesture_get_device (GTK_GESTURE (gesture)), paintable = gtk_widget_paintable_new (icon_info->widget);
icon_info->target_list, gtk_drag_source_set_icon (source, paintable, -2, -2);
icon_info->actions, g_object_unref (paintable);
start_x, start_y); device = gtk_gesture_get_device (GTK_GESTURE (gesture));
gtk_drag_source_drag_begin (source, GTK_WIDGET (entry), device, start_x, start_y);
g_object_unref (source);
} }
} }
@ -2742,7 +2747,7 @@ gtk_entry_get_icon_at_pos (GtkEntry *entry,
void void
gtk_entry_set_icon_drag_source (GtkEntry *entry, gtk_entry_set_icon_drag_source (GtkEntry *entry,
GtkEntryIconPosition icon_pos, GtkEntryIconPosition icon_pos,
GdkContentFormats *formats, GdkContentProvider *provider,
GdkDragAction actions) GdkDragAction actions)
{ {
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry); GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
@ -2754,12 +2759,7 @@ gtk_entry_set_icon_drag_source (GtkEntry *entry,
if ((icon_info = priv->icons[icon_pos]) == NULL) if ((icon_info = priv->icons[icon_pos]) == NULL)
icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos); icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos);
if (icon_info->target_list) g_set_object (&icon_info->content, provider);
gdk_content_formats_unref (icon_info->target_list);
icon_info->target_list = formats;
if (icon_info->target_list)
gdk_content_formats_ref (icon_info->target_list);
icon_info->actions = actions; icon_info->actions = actions;
} }

View File

@ -266,7 +266,7 @@ gchar * gtk_entry_get_icon_tooltip_markup (GtkEntry *
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
void gtk_entry_set_icon_drag_source (GtkEntry *entry, void gtk_entry_set_icon_drag_source (GtkEntry *entry,
GtkEntryIconPosition icon_pos, GtkEntryIconPosition icon_pos,
GdkContentFormats *formats, GdkContentProvider *content,
GdkDragAction actions); GdkDragAction actions);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
gint gtk_entry_get_current_icon_drag_source (GtkEntry *entry); gint gtk_entry_get_current_icon_drag_source (GtkEntry *entry);

View File

@ -20,33 +20,6 @@ drag_begin_cb (GtkWidget *widget,
gtk_drag_set_icon_name (drag, "dialog-information", 2, 2); gtk_drag_set_icon_name (drag, "dialog-information", 2, 2);
} }
static void
drag_data_get_cb (GtkWidget *widget,
GdkDrag *drag,
GtkSelectionData *data,
gpointer user_data)
{
gint pos;
pos = gtk_entry_get_current_icon_drag_source (GTK_ENTRY (widget));
if (pos == GTK_ENTRY_ICON_PRIMARY)
{
gint start, end;
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (widget), &start, &end))
{
gchar *str;
str = gtk_editable_get_chars (GTK_EDITABLE (widget), start, end);
gtk_selection_data_set_text (data, str, -1);
g_free (str);
}
else
gtk_selection_data_set_text (data, "XXX", -1);
}
}
static void static void
set_blank (GtkWidget *button, set_blank (GtkWidget *button,
GtkEntry *entry) GtkEntry *entry)
@ -127,7 +100,8 @@ main (int argc, char **argv)
GtkWidget *button3; GtkWidget *button3;
GtkWidget *button4; GtkWidget *button4;
GIcon *icon; GIcon *icon;
GdkContentFormats *tlist; GdkContentProvider *content;
GValue value = G_VALUE_INIT;
gtk_init (); gtk_init ();
@ -190,16 +164,17 @@ main (int argc, char **argv)
gtk_entry_set_icon_tooltip_text (GTK_ENTRY (entry), gtk_entry_set_icon_tooltip_text (GTK_ENTRY (entry),
GTK_ENTRY_ICON_PRIMARY, GTK_ENTRY_ICON_PRIMARY,
"Save a file"); "Save a file");
tlist = gdk_content_formats_new (NULL, 0);
tlist = gtk_content_formats_add_text_targets (tlist); g_value_init (&value, G_TYPE_STRING);
g_value_set_string (&value, "Amazing");
content = gdk_content_provider_new_for_value (&value);
g_value_unset (&value);
gtk_entry_set_icon_drag_source (GTK_ENTRY (entry), gtk_entry_set_icon_drag_source (GTK_ENTRY (entry),
GTK_ENTRY_ICON_PRIMARY, GTK_ENTRY_ICON_PRIMARY,
tlist, GDK_ACTION_COPY); content, GDK_ACTION_COPY);
g_signal_connect_after (entry, "drag-begin", g_signal_connect_after (entry, "drag-begin",
G_CALLBACK (drag_begin_cb), NULL); G_CALLBACK (drag_begin_cb), NULL);
g_signal_connect (entry, "drag-data-get", g_object_unref (content);
G_CALLBACK (drag_data_get_cb), NULL);
gdk_content_formats_unref (tlist);
/* /*
* Search - Uses a helper function * Search - Uses a helper function