diff options
-rw-r--r-- | docs/reference/gtk/gtk4-sections.txt | 1 | ||||
-rw-r--r-- | gtk/gtkdnd.c | 63 | ||||
-rw-r--r-- | gtk/gtkdragdest.c | 26 | ||||
-rw-r--r-- | gtk/gtkselection.c | 56 | ||||
-rw-r--r-- | gtk/gtkselection.h | 3 | ||||
-rw-r--r-- | gtk/gtkselectionprivate.h | 7 |
6 files changed, 90 insertions, 66 deletions
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index 03f0186da0..36f22c9ddd 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -5219,6 +5219,7 @@ gtk_target_list_unref gtk_target_list_add gtk_target_list_add_table gtk_target_list_merge +gtk_target_list_intersects gtk_target_list_add_text_targets gtk_target_list_add_image_targets gtk_target_list_add_uri_targets diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c index abd223aebb..11f4cb3be8 100644 --- a/gtk/gtkdnd.c +++ b/gtk/gtkdnd.c @@ -1180,7 +1180,6 @@ gtk_drag_begin_internal (GtkWidget *widget, { GtkDragSourceInfo *info; GList *targets = NULL; - GList *tmp_list; guint32 time = GDK_CURRENT_TIME; GdkDragAction possible_actions, suggested_action; GdkDragContext *context; @@ -1190,6 +1189,8 @@ gtk_drag_begin_internal (GtkWidget *widget, GdkWindow *ipc_window; int start_x, start_y; GdkAtom selection; + GdkAtom *atoms; + guint i, n_atoms; gboolean managed; managed = gtk_drag_is_managed (widget); @@ -1261,12 +1262,12 @@ gtk_drag_begin_internal (GtkWidget *widget, gtk_device_grab_add (ipc_widget, pointer, FALSE); } - tmp_list = g_list_last (target_list->list); - while (tmp_list) + atoms = gtk_target_list_get_atoms (target_list, &n_atoms); + for (i = 0; i < n_atoms; i++) { - targets = g_list_prepend (targets, tmp_list->data); - tmp_list = tmp_list->prev; + targets = g_list_prepend (targets, (gpointer) atoms[i]); } + g_free (atoms); source_widgets = g_slist_prepend (source_widgets, ipc_widget); @@ -1791,14 +1792,9 @@ gtk_drag_source_check_selection (GtkDragSourceInfo *info, info->selections = g_list_prepend (info->selections, GUINT_TO_POINTER (selection)); - tmp_list = info->target_list->list; - while (tmp_list) - { - gtk_selection_add_target (info->ipc_widget, - selection, - tmp_list->data); - tmp_list = tmp_list->next; - } + gtk_selection_add_targets (info->ipc_widget, + selection, + info->target_list); gtk_selection_add_target (info->ipc_widget, selection, @@ -1852,33 +1848,32 @@ gtk_drag_drop (GtkDragSourceInfo *info, if (gdk_drag_context_get_protocol (info->context) == GDK_DRAG_PROTO_ROOTWIN) { GtkSelectionData selection_data; - GList *tmp_list; + GdkAtom found = NULL; /* GTK+ traditionally has used application/x-rootwin-drop, but the * XDND spec specifies x-rootwindow-drop. */ - GdkAtom target1 = gdk_atom_intern_static_string ("application/x-rootwindow-drop"); - GdkAtom target2 = gdk_atom_intern_static_string ("application/x-rootwin-drop"); + if (gtk_target_list_find (info->target_list, "application/x-rootwindow-drop")) + found = gdk_atom_intern ("application/x-rootwindow-drop", FALSE); + if (gtk_target_list_find (info->target_list, "application/x-rootwin-drop")) + found = gdk_atom_intern ("application/x-rootwin-drop", FALSE); + else found = NULL; - tmp_list = info->target_list->list; - while (tmp_list) + if (found) { - if (tmp_list->data == target1 || tmp_list->data == target2) - { - selection_data.selection = NULL; - selection_data.target = tmp_list->data; - selection_data.data = NULL; - selection_data.length = -1; - - g_signal_emit_by_name (info->widget, "drag-data-get", - info->context, &selection_data, - time); - - /* FIXME: Should we check for length >= 0 here? */ - gtk_drag_drop_finished (info, GTK_DRAG_RESULT_SUCCESS, time); - return; - } - tmp_list = tmp_list->next; + selection_data.selection = NULL; + selection_data.target = found; + selection_data.data = NULL; + selection_data.length = -1; + + g_signal_emit_by_name (info->widget, "drag-data-get", + info->context, &selection_data, + time); + + /* FIXME: Should we check for length >= 0 here? */ + gtk_drag_drop_finished (info, GTK_DRAG_RESULT_SUCCESS, time); + return; } + gtk_drag_drop_finished (info, GTK_DRAG_RESULT_NO_TARGET, time); } else diff --git a/gtk/gtkdragdest.c b/gtk/gtkdragdest.c index ea1da8abf7..482a5d2a84 100644 --- a/gtk/gtkdragdest.c +++ b/gtk/gtkdragdest.c @@ -411,8 +411,9 @@ gtk_drag_dest_find_target (GtkWidget *widget, GdkDragContext *context, GtkTargetList *target_list) { - GList *tmp_target; - GList *tmp_source = NULL; + GtkTargetList *source_list; + GList *tmp_source; + GdkAtom result; g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL); @@ -423,19 +424,18 @@ gtk_drag_dest_find_target (GtkWidget *widget, if (target_list == NULL) return NULL; - tmp_target = target_list->list; - while (tmp_target) + source_list = gtk_target_list_new (NULL, 0); + for (tmp_source = gdk_drag_context_list_targets (context); + tmp_source != NULL; + tmp_source = tmp_source->next) { - tmp_source = gdk_drag_context_list_targets (context); - while (tmp_source) - { - if (tmp_source->data == tmp_target->data) - return tmp_target->data; - tmp_source = tmp_source->next; - } - tmp_target = tmp_target->next; + gtk_target_list_add (source_list, tmp_source->data); } + + result = gtk_target_list_intersects (target_list, source_list); - return NULL; + gtk_target_list_unref (source_list); + + return result; } diff --git a/gtk/gtkselection.c b/gtk/gtkselection.c index 60c4e408ce..4dc11b11e6 100644 --- a/gtk/gtkselection.c +++ b/gtk/gtkselection.c @@ -154,6 +154,13 @@ struct _GtkIncrConversion * left to send */ }; +struct _GtkTargetList +{ + /*< private >*/ + GList *list; + guint ref_count; +}; + struct _GtkIncrInfo { GdkWindow *requestor; /* Requestor window - we create a GdkWindow @@ -495,6 +502,35 @@ gtk_target_list_merge (GtkTargetList *target, } /** + * gtk_target_list_intersects: + * @first: the primary #GtkTargetList to intersect + * @second: the #GtkTargeList to intersect with + * + * Finds the first element from @first that is also contained + * in @second. + * + * Returns: The first matching #GdkAtom or %NULL if the lists + * do not intersect. + */ +GdkAtom +gtk_target_list_intersects (const GtkTargetList *first, + const GtkTargetList *second) +{ + GList *l; + + g_return_val_if_fail (first != NULL, NULL); + g_return_val_if_fail (second != NULL, NULL); + + for (l = first->list; l; l = l->next) + { + if (g_list_find (second->list, l->data)) + return l->data; + } + + return NULL; +} + +/** * gtk_target_list_add_table: * @list: a #GtkTargetList * @targets: (array length=ntargets): the table of #GtkTargetEntry @@ -3085,18 +3121,17 @@ gtk_selection_default_handler (GtkWidget *widget, else if (data->target == gtk_selection_atoms[TARGETS]) { /* List of all targets supported for this widget/selection pair */ - GdkAtom *p; - guint count; - GList *tmp_list; + GdkAtom *p, *atoms; + guint count, i; GtkTargetList *target_list; target_list = gtk_selection_target_list_get (widget, data->selection); - count = g_list_length (target_list->list) + 3; + atoms = gtk_target_list_get_atoms (target_list, &count); data->type = GDK_SELECTION_TYPE_ATOM; data->format = 32; - data->length = count * sizeof (GdkAtom); + data->length = (count + 3) * sizeof (GdkAtom); /* selection data is always terminated by a trailing \0 */ @@ -3108,13 +3143,10 @@ gtk_selection_default_handler (GtkWidget *widget, *p++ = gtk_selection_atoms[TARGETS]; *p++ = gtk_selection_atoms[MULTIPLE]; - tmp_list = target_list->list; - while (tmp_list) - { - *p++ = (GdkAtom) tmp_list->data; - - tmp_list = tmp_list->next; - } + for (i = 0; i < count; i++) + *p++ = atoms[i]; + + g_free (atoms); } else if (data->target == gtk_selection_atoms[SAVE_TARGETS]) { diff --git a/gtk/gtkselection.h b/gtk/gtkselection.h index a7de3d6cd9..ee718e217c 100644 --- a/gtk/gtkselection.h +++ b/gtk/gtkselection.h @@ -58,6 +58,9 @@ void gtk_target_list_unref (GtkTargetList *list); GDK_AVAILABLE_IN_3_94 void gtk_target_list_merge (GtkTargetList *target, const GtkTargetList *source); +GDK_AVAILABLE_IN_3_94 +GdkAtom gtk_target_list_intersects(const GtkTargetList *first, + const GtkTargetList *second); GDK_AVAILABLE_IN_ALL void gtk_target_list_add (GtkTargetList *list, const char *target); diff --git a/gtk/gtkselectionprivate.h b/gtk/gtkselectionprivate.h index 49c1f5f71a..9ada28f997 100644 --- a/gtk/gtkselectionprivate.h +++ b/gtk/gtkselectionprivate.h @@ -47,13 +47,6 @@ struct _GtkSelectionData GdkDisplay *display; }; -struct _GtkTargetList -{ - /*< private >*/ - GList *list; - guint ref_count; -}; - GdkAtom *gtk_target_list_get_atoms (GtkTargetList *targets, guint *n_atoms); |