diff --git a/docs/reference/gdk/gdk4-sections.txt b/docs/reference/gdk/gdk4-sections.txt index 2f55e16471..2752f03b18 100644 --- a/docs/reference/gdk/gdk4-sections.txt +++ b/docs/reference/gdk/gdk4-sections.txt @@ -373,6 +373,8 @@ gdk_fullscreen_mode_get_type gdk_content_formats_new gdk_content_formats_ref gdk_content_formats_unref +gdk_content_formats_print +gdk_content_formats_to_string gdk_content_formats_add gdk_content_formats_union gdk_content_formats_intersects @@ -865,7 +867,7 @@ gdk_window_get_drag_protocol gdk_drag_context_get_actions gdk_drag_context_get_suggested_action gdk_drag_context_get_selected_action -gdk_drag_context_list_targets +gdk_drag_context_get_formats gdk_drag_context_get_device gdk_drag_context_set_device gdk_drag_context_get_source_window diff --git a/gdk/broadway/gdkdnd-broadway.c b/gdk/broadway/gdkdnd-broadway.c index d280a26758..ebb36797ca 100644 --- a/gdk/broadway/gdkdnd-broadway.c +++ b/gdk/broadway/gdkdnd-broadway.c @@ -84,11 +84,11 @@ gdk_broadway_drag_context_finalize (GObject *object) /* Drag Contexts */ GdkDragContext * -_gdk_broadway_window_drag_begin (GdkWindow *window, - GdkDevice *device, - GList *targets, - gint x_root, - gint y_root) +_gdk_broadway_window_drag_begin (GdkWindow *window, + GdkDevice *device, + GdkContentFormats *formats, + gint x_root, + gint y_root) { GdkDragContext *new_context; diff --git a/gdk/broadway/gdkprivate-broadway.h b/gdk/broadway/gdkprivate-broadway.h index 30adbfe002..8df551d00d 100644 --- a/gdk/broadway/gdkprivate-broadway.h +++ b/gdk/broadway/gdkprivate-broadway.h @@ -40,11 +40,11 @@ void _gdk_broadway_resync_windows (void); void _gdk_broadway_window_register_dnd (GdkWindow *window); -GdkDragContext * _gdk_broadway_window_drag_begin (GdkWindow *window, - GdkDevice *device, - GList *targets, - gint x_root, - gint y_root); +GdkDragContext * _gdk_broadway_window_drag_begin (GdkWindow *window, + GdkDevice *device, + GdkContentFormats *formats, + gint x_root, + gint y_root); void _gdk_broadway_window_translate (GdkWindow *window, cairo_region_t *area, gint dx, diff --git a/gdk/gdkcontentformats.c b/gdk/gdkcontentformats.c index 78fab2ed76..c3cd9cde63 100644 --- a/gdk/gdkcontentformats.c +++ b/gdk/gdkcontentformats.c @@ -149,6 +149,59 @@ gdk_content_formats_unref (GdkContentFormats *formats) g_slice_free (GdkContentFormats, formats); } +/** + * gdk_content_formats_print: + * @formats: a #GdkContentFormats + * @string: a #GString to print into + * + * Prints the given @formats into a string for human consumption. + * This is meant for debugging and logging. + * + * The form of the representation may change at any time and is + * not guranteed to stay identical. + **/ +void +gdk_content_formats_print (GdkContentFormats *formats, + GString *string) +{ + GList *l; + + g_return_if_fail (formats != NULL); + g_return_if_fail (string != NULL); + + g_string_append (string, "{ "); + for (l = formats->formats; l; l = l->next) + { + if (l != formats->formats) + g_string_append (string, ", "); + g_string_append (string, l->data); + } + g_string_append (string, " }"); +} + +/** + * gdk_content_formats_to_string: + * @formats: a #GdkContentFormats + * + * Prints the given @formats into a human-readable string. + * This is a small wrapper around gdk_content_formats_print() to help + * when debugging. + * + * Returns: (transfer full): a new string + **/ +char * +gdk_content_formats_to_string (GdkContentFormats *formats) +{ + GString *string; + + g_return_val_if_fail (formats != NULL, NULL); + + string = g_string_new (NULL); + gdk_content_formats_print (formats, string); + + return g_string_free (string, FALSE); +} + /** * gdk_content_formats_add: * @formats: a #GdkContentFormats @@ -217,24 +270,6 @@ gdk_content_formats_intersects (const GdkContentFormats *first, return NULL; } -/** - * gdk_content_formats_remove: - * @formats: a #GdkContentFormats - * @mime_type: the mime type - * - * Removes a mime type. If the mime type was not part of @formats, nothing - * happens. - **/ -void -gdk_content_formats_remove (GdkContentFormats *formats, - const char *mime_type) -{ - g_return_if_fail (formats != NULL); - g_return_if_fail (mime_type != NULL); - - formats->formats = g_list_remove (formats->formats, (gpointer) gdk_atom_intern (mime_type, FALSE)); -} - /** * gdk_content_formats_contains: * @formats: a #GdkContentFormats diff --git a/gdk/gdkcontentformats.h b/gdk/gdkcontentformats.h index 8859658bfb..f73c5b4688 100644 --- a/gdk/gdkcontentformats.h +++ b/gdk/gdkcontentformats.h @@ -40,6 +40,12 @@ GdkContentFormats * gdk_content_formats_ref (GdkContentForma GDK_AVAILABLE_IN_3_94 void gdk_content_formats_unref (GdkContentFormats *formats); +GDK_AVAILABLE_IN_3_94 +void gdk_content_formats_print (GdkContentFormats *formats, + GString *string); +GDK_AVAILABLE_IN_3_94 +char * gdk_content_formats_to_string (GdkContentFormats *formats); + GDK_AVAILABLE_IN_3_94 void gdk_content_formats_union (GdkContentFormats *first, const GdkContentFormats *second); @@ -50,9 +56,6 @@ GDK_AVAILABLE_IN_3_94 void gdk_content_formats_add (GdkContentFormats *formats, const char *mime_type); GDK_AVAILABLE_IN_3_94 -void gdk_content_formats_remove (GdkContentFormats *formats, - const char *mime_type); -GDK_AVAILABLE_IN_3_94 gboolean gdk_content_formats_contains (const GdkContentFormats *formats, const char *mime_type); diff --git a/gdk/gdkdnd.c b/gdk/gdkdnd.c index 19712fdac5..7b9638d430 100644 --- a/gdk/gdkdnd.c +++ b/gdk/gdkdnd.c @@ -28,8 +28,9 @@ #include "gdkdisplay.h" #include "gdkwindow.h" #include "gdkintl.h" -#include "gdkenumtypes.h" +#include "gdkcontentformats.h" #include "gdkcursor.h" +#include "gdkenumtypes.h" #include "gdkeventsprivate.h" static struct { @@ -73,21 +74,21 @@ static GList *contexts = NULL; */ /** - * gdk_drag_context_list_targets: + * gdk_drag_context_get_formats: * @context: a #GdkDragContext * - * Retrieves the list of targets of the context. + * Retrieves the formats supported by this context. * - * Returns: (transfer none) (element-type GdkAtom): a #GList of targets + * Returns: (transfer none): a #GdkContentFormats * - * Since: 2.22 + * Since: 3.94 **/ -GList * -gdk_drag_context_list_targets (GdkDragContext *context) +GdkContentFormats * +gdk_drag_context_get_formats (GdkDragContext *context) { g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL); - return context->targets; + return context->formats; } /** @@ -253,7 +254,7 @@ gdk_drag_context_finalize (GObject *object) GdkDragContext *context = GDK_DRAG_CONTEXT (object); contexts = g_list_remove (contexts, context); - g_list_free (context->targets); + g_clear_pointer (&context->formats, gdk_content_formats_unref); if (context->source_window) g_object_unref (context->source_window); diff --git a/gdk/gdkdnd.h b/gdk/gdkdnd.h index a8b62668c2..b86bc7be90 100644 --- a/gdk/gdkdnd.h +++ b/gdk/gdkdnd.h @@ -117,8 +117,8 @@ void gdk_drag_context_set_device (GdkDragContext *context, GDK_AVAILABLE_IN_ALL GdkDevice * gdk_drag_context_get_device (GdkDragContext *context); -GDK_AVAILABLE_IN_ALL -GList *gdk_drag_context_list_targets (GdkDragContext *context); +GDK_AVAILABLE_IN_3_94 +GdkContentFormats *gdk_drag_context_get_formats (GdkDragContext *context); GDK_AVAILABLE_IN_ALL GdkDragAction gdk_drag_context_get_actions (GdkDragContext *context); GDK_AVAILABLE_IN_ALL @@ -153,19 +153,19 @@ GdkAtom gdk_drag_get_selection (GdkDragContext *context); /* Source side */ GDK_AVAILABLE_IN_ALL -GdkDragContext * gdk_drag_begin (GdkWindow *window, - GList *targets); +GdkDragContext * gdk_drag_begin (GdkWindow *window, + GdkContentFormats *formats); GDK_AVAILABLE_IN_ALL -GdkDragContext * gdk_drag_begin_for_device (GdkWindow *window, - GdkDevice *device, - GList *targets); +GdkDragContext * gdk_drag_begin_for_device (GdkWindow *window, + GdkDevice *device, + GdkContentFormats *formats); GDK_AVAILABLE_IN_3_20 -GdkDragContext * gdk_drag_begin_from_point (GdkWindow *window, - GdkDevice *device, - GList *targets, - gint x_root, - gint y_root); +GdkDragContext * gdk_drag_begin_from_point (GdkWindow *window, + GdkDevice *device, + GdkContentFormats *formats, + gint x_root, + gint y_root); GDK_AVAILABLE_IN_ALL void gdk_drag_find_window (GdkDragContext *context, diff --git a/gdk/gdkdndprivate.h b/gdk/gdkdndprivate.h index ad2b507bcf..bf0ab8bd89 100644 --- a/gdk/gdkdndprivate.h +++ b/gdk/gdkdndprivate.h @@ -100,7 +100,7 @@ struct _GdkDragContext { GdkWindow *dest_window; GdkWindow *drag_window; - GList *targets; + GdkContentFormats *formats; GdkDragAction actions; GdkDragAction suggested_action; GdkDragAction action; diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 1fbd5d055e..edb7d77467 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -7092,8 +7092,7 @@ gdk_window_get_drag_protocol (GdkWindow *window, /** * gdk_drag_begin: * @window: the source window for this drag. - * @targets: (transfer none) (element-type GdkAtom): the offered targets, - * as list of #GdkAtoms + * @formats: (transfer none): the offered formats * * Starts a drag and creates a new drag context for it. * This function assumes that the drag is controlled by the @@ -7105,8 +7104,8 @@ gdk_window_get_drag_protocol (GdkWindow *window, * Returns: (transfer full): a newly created #GdkDragContext */ GdkDragContext * -gdk_drag_begin (GdkWindow *window, - GList *targets) +gdk_drag_begin (GdkWindow *window, + GdkContentFormats *formats) { GdkDisplay *display; GdkDevice *device; @@ -7114,15 +7113,14 @@ gdk_drag_begin (GdkWindow *window, display = gdk_window_get_display (window); device = gdk_seat_get_pointer (gdk_display_get_default_seat (display)); - return gdk_drag_begin_for_device (window, device, targets); + return gdk_drag_begin_for_device (window, device, formats); } /** * gdk_drag_begin_for_device: * @window: the source window for this drag * @device: the device that controls this drag - * @targets: (transfer none) (element-type GdkAtom): the offered targets, - * as list of #GdkAtoms + * @formats: (transfer none): the offered formats * * Starts a drag and creates a new drag context for it. * @@ -7133,21 +7131,20 @@ gdk_drag_begin (GdkWindow *window, GdkDragContext * gdk_drag_begin_for_device (GdkWindow *window, GdkDevice *device, - GList *targets) + GdkContentFormats *formats) { gint x, y; gdk_device_get_position (device, &x, &y); - return gdk_drag_begin_from_point (window, device, targets, x, y); + return gdk_drag_begin_from_point (window, device, formats, x, y); } /** * gdk_drag_begin_from_point: * @window: the source window for this drag * @device: the device that controls this drag - * @targets: (transfer none) (element-type GdkAtom): the offered targets, - * as list of #GdkAtoms + * @formats: (transfer none): the offered formats * @x_root: the x coordinate where the drag nominally started * @y_root: the y coordinate where the drag nominally started * @@ -7160,13 +7157,13 @@ gdk_drag_begin_for_device (GdkWindow *window, * Since: 3.20 */ GdkDragContext * -gdk_drag_begin_from_point (GdkWindow *window, - GdkDevice *device, - GList *targets, - gint x_root, - gint y_root) +gdk_drag_begin_from_point (GdkWindow *window, + GdkDevice *device, + GdkContentFormats *formats, + gint x_root, + gint y_root) { - return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->drag_begin (window, device, targets, x_root, y_root); + return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->drag_begin (window, device, formats, x_root, y_root); } /** diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h index 2477ad6cb2..8c15aebfc0 100644 --- a/gdk/gdkwindowimpl.h +++ b/gdk/gdkwindowimpl.h @@ -219,11 +219,11 @@ struct _GdkWindowImplClass GdkDragProtocol (* get_drag_protocol) (GdkWindow *window, GdkWindow **target); void (* register_dnd) (GdkWindow *window); - GdkDragContext * (*drag_begin) (GdkWindow *window, - GdkDevice *device, - GList *targets, - gint x_root, - gint y_root); + GdkDragContext * (*drag_begin) (GdkWindow *window, + GdkDevice *device, + GdkContentFormats *formats, + gint x_root, + gint y_root); void (*process_updates_recurse) (GdkWindow *window, cairo_region_t *region); diff --git a/gdk/wayland/gdkdnd-wayland.c b/gdk/wayland/gdkdnd-wayland.c index dd7cdaa510..fb668702a4 100644 --- a/gdk/wayland/gdkdnd-wayland.c +++ b/gdk/wayland/gdkdnd-wayland.c @@ -22,6 +22,7 @@ #include "gdkinternals.h" #include "gdkproperty.h" #include "gdkprivate-wayland.h" +#include "gdkcontentformatsprivate.h" #include "gdkdisplay-wayland.h" #include "gdkseat-wayland.h" @@ -239,22 +240,26 @@ gdk_wayland_drop_context_set_status (GdkDragContext *context, if (accepted) { - GList *l; - - for (l = context->targets; l; l = l->next) + GdkAtom *atoms; + guint i, n_atoms; + + atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms); + for (i = 0; i < n_atoms; i++) { - if (l->data != gdk_atom_intern_static_string ("DELETE")) + if (atoms[i] != gdk_atom_intern_static_string ("DELETE")) break; } - if (l) + if (i < n_atoms) { - gchar *mimetype = gdk_atom_name (l->data); + gchar *mimetype = gdk_atom_name (atoms[i]); wl_data_offer_accept (wl_offer, context_wayland->serial, mimetype); - g_free (mimetype); + g_free (atoms); return; } + + g_free (atoms); } wl_data_offer_accept (wl_offer, context_wayland->serial, NULL); @@ -508,22 +513,23 @@ create_dnd_window (GdkDisplay *display) } GdkDragContext * -_gdk_wayland_window_drag_begin (GdkWindow *window, - GdkDevice *device, - GList *targets, - gint x_root, - gint y_root) +_gdk_wayland_window_drag_begin (GdkWindow *window, + GdkDevice *device, + GdkContentFormats *formats, + gint x_root, + gint y_root) { GdkWaylandDragContext *context_wayland; GdkDragContext *context; - GList *l; + GdkAtom *atoms; + guint i, n_atoms; context_wayland = g_object_new (GDK_TYPE_WAYLAND_DRAG_CONTEXT, NULL); context = GDK_DRAG_CONTEXT (context_wayland); context->display = gdk_window_get_display (window); context->source_window = g_object_ref (window); context->is_source = TRUE; - context->targets = g_list_copy (targets); + context->formats = gdk_content_formats_ref (formats); gdk_drag_context_set_device (context, device); @@ -533,13 +539,15 @@ _gdk_wayland_window_drag_begin (GdkWindow *window, gdk_wayland_selection_get_data_source (window, gdk_wayland_drag_context_get_selection (context)); - for (l = context->targets; l; l = l->next) + atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms); + for (i = 0; i < n_atoms; i++) { - gchar *mimetype = gdk_atom_name (l->data); + gchar *mimetype = gdk_atom_name (atoms[i]); wl_data_source_offer (context_wayland->data_source, mimetype); g_free (mimetype); } + g_free (atoms); return context; } @@ -567,9 +575,13 @@ gdk_wayland_drop_context_update_targets (GdkDragContext *context) device = gdk_drag_context_get_device (context); display = gdk_device_get_display (device); - g_list_free (context->targets); - context->targets = g_list_copy (gdk_wayland_selection_get_targets (display, - gdk_drag_get_selection (context))); + gdk_content_formats_unref (context->formats); + context->formats = gdk_wayland_selection_get_targets (display, + gdk_drag_get_selection (context)); + if (context->formats) + gdk_content_formats_ref (context->formats); + else + context->formats = gdk_content_formats_new (NULL, 0); } void diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index 48282fdabe..f987ddb3ca 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -92,12 +92,12 @@ void gdk_wayland_window_sync (GdkWindow *window); GdkDragProtocol _gdk_wayland_window_get_drag_protocol (GdkWindow *window, GdkWindow **target); -void _gdk_wayland_window_register_dnd (GdkWindow *window); -GdkDragContext *_gdk_wayland_window_drag_begin (GdkWindow *window, - GdkDevice *device, - GList *targets, - gint x_root, - gint y_root); +void _gdk_wayland_window_register_dnd (GdkWindow *window); +GdkDragContext *_gdk_wayland_window_drag_begin (GdkWindow *window, + GdkDevice *device, + GdkContentFormats *formats, + gint x_root, + gint y_root); void _gdk_wayland_window_offset_next_wl_buffer (GdkWindow *window, int x, int y); @@ -238,8 +238,8 @@ void gdk_wayland_selection_set_offer (GdkDisplay *display, gpointer offer); gpointer gdk_wayland_selection_get_offer (GdkDisplay *display, GdkAtom selection); -GList * gdk_wayland_selection_get_targets (GdkDisplay *display, - GdkAtom selection); +GdkContentFormats *gdk_wayland_selection_get_targets (GdkDisplay *display, + GdkAtom selection); void gdk_wayland_selection_store (GdkWindow *window, GdkAtom type, diff --git a/gdk/wayland/gdkselection-wayland.c b/gdk/wayland/gdkselection-wayland.c index 2d402fcb94..4b2acf8bc0 100644 --- a/gdk/wayland/gdkselection-wayland.c +++ b/gdk/wayland/gdkselection-wayland.c @@ -27,6 +27,7 @@ #include "gdkwayland.h" #include "gdkprivate-wayland.h" #include "gdkdisplay-wayland.h" +#include "gdkcontentformatsprivate.h" #include "gdkdndprivate.h" #include "gdkselection.h" #include "gdkproperty.h" @@ -70,7 +71,7 @@ struct _DataOfferData { GDestroyNotify destroy_notify; gpointer offer_data; - GList *targets; /* List of GdkAtom */ + GdkContentFormats *targets; }; struct _AsyncWriteData @@ -295,6 +296,7 @@ data_offer_data_new (gpointer offer, info = g_slice_new0 (DataOfferData); info->offer_data = offer; info->destroy_notify = destroy_notify; + info->targets = gdk_content_formats_new (NULL, 0); return info; } @@ -303,7 +305,7 @@ static void data_offer_data_free (DataOfferData *info) { info->destroy_notify (info->offer_data); - g_list_free (info->targets); + gdk_content_formats_unref (info->targets); g_slice_free (DataOfferData, info); } @@ -373,17 +375,16 @@ data_offer_offer (void *data, { GdkWaylandSelection *selection = data; DataOfferData *info; - GdkAtom atom = gdk_atom_intern (type, FALSE); info = g_hash_table_lookup (selection->offers, wl_data_offer); - if (!info || g_list_find (info->targets, GDK_ATOM_TO_POINTER (atom))) + if (!info || gdk_content_formats_contains (info->targets, type)) return; GDK_NOTE (EVENTS, g_message ("data offer offer, offer %p, type = %s", wl_data_offer, type)); - info->targets = g_list_prepend (info->targets, GDK_ATOM_TO_POINTER (atom)); + gdk_content_formats_add (info->targets, type); } static inline GdkDragAction @@ -461,17 +462,16 @@ primary_offer_offer (void *data, { GdkWaylandSelection *selection = data; DataOfferData *info; - GdkAtom atom = gdk_atom_intern (type, FALSE); info = g_hash_table_lookup (selection->offers, gtk_offer); - if (!info || g_list_find (info->targets, GDK_ATOM_TO_POINTER (atom))) + if (!info || gdk_content_formats_contains (info->targets, type)) return; GDK_NOTE (EVENTS, g_message ("primary offer offer, offer %p, type = %s", gtk_offer, type)); - info->targets = g_list_prepend (info->targets, GDK_ATOM_TO_POINTER (atom)); + gdk_content_formats_add (info->targets, type); } static const struct gtk_primary_selection_offer_listener primary_offer_listener = { @@ -574,7 +574,7 @@ gdk_wayland_selection_get_offer (GdkDisplay *display, return NULL; } -GList * +GdkContentFormats * gdk_wayland_selection_get_targets (GdkDisplay *display, GdkAtom selection_atom) { @@ -1289,14 +1289,14 @@ _gdk_wayland_display_convert_selection (GdkDisplay *display, SelectionBuffer *buffer_data; gpointer offer; gchar *mimetype; - GList *target_list; + GdkContentFormats *formats; selection_data = selection_lookup_offer_by_atom (wayland_selection, selection); if (!selection_data) return; offer = gdk_wayland_selection_get_offer (display, selection); - target_list = gdk_wayland_selection_get_targets (display, selection); + formats = gdk_wayland_selection_get_targets (display, selection); if (!offer || target == gdk_atom_intern_static_string ("DELETE")) { @@ -1308,7 +1308,7 @@ _gdk_wayland_display_convert_selection (GdkDisplay *display, if (target != gdk_atom_intern_static_string ("TARGETS")) { - if (!g_list_find (target_list, GDK_ATOM_TO_POINTER (target))) + if (!gdk_content_formats_contains (formats, GDK_ATOM_TO_POINTER (target))) { emit_empty_selection_notify (requestor, selection, target); return; @@ -1327,19 +1327,13 @@ _gdk_wayland_display_convert_selection (GdkDisplay *display, else { GInputStream *stream = NULL; - int pipe_fd[2], natoms = 0; + int pipe_fd[2]; + guint natoms = 0; GdkAtom *targets = NULL; if (target == gdk_atom_intern_static_string ("TARGETS")) { - gint i = 0; - GList *l; - - natoms = g_list_length (target_list); - targets = g_new0 (GdkAtom, natoms); - - for (l = target_list; l; l = l->next) - targets[i++] = l->data; + targets = gdk_content_formats_get_atoms (formats, &natoms); } else { diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c index 4c246fd509..82bb861a07 100644 --- a/gdk/x11/gdkdnd-x11.c +++ b/gdk/x11/gdkdnd-x11.c @@ -30,6 +30,7 @@ #include "gdkinternals.h" #include "gdkasync.h" +#include "gdkcontentformatsprivate.h" #include "gdkproperty.h" #include "gdkprivate-x11.h" #include "gdkscreen-x11.h" @@ -336,23 +337,18 @@ gdk_drag_context_find (GdkDisplay *display, static void precache_target_list (GdkDragContext *context) { - if (context->targets) + if (context->formats) { - GPtrArray *targets = g_ptr_array_new (); - GList *tmp_list; - int i; + GdkAtom *atoms; + guint n_atoms; - for (tmp_list = context->targets; tmp_list; tmp_list = tmp_list->next) - g_ptr_array_add (targets, gdk_atom_name (GDK_POINTER_TO_ATOM (tmp_list->data))); + atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms); _gdk_x11_precache_atoms (GDK_WINDOW_DISPLAY (context->source_window), - (const gchar **)targets->pdata, - targets->len); + (const gchar **) atoms, + n_atoms); - for (i =0; i < targets->len; i++) - g_free (targets->pdata[i]); - - g_ptr_array_free (targets, TRUE); + g_free (atoms); } } @@ -854,15 +850,11 @@ get_client_window_at_coords (GdkWindowCache *cache, #ifdef G_ENABLE_DEBUG static void -print_target_list (GList *targets) +print_target_list (GdkContentFormats *formats) { - while (targets) - { - gchar *name = gdk_atom_name (GDK_POINTER_TO_ATOM (targets->data)); - g_message ("\t%s", name); - g_free (name); - targets = targets->next; - } + gchar *name = gdk_content_formats_to_string (formats); + g_message ("DND formats: %s", name); + g_free (name); } #endif /* G_ENABLE_DEBUG */ @@ -1033,19 +1025,14 @@ xdnd_set_targets (GdkX11DragContext *context_x11) { GdkDragContext *context = GDK_DRAG_CONTEXT (context_x11); Atom *atomlist; - GList *tmp_list = context->targets; - gint i; - gint n_atoms = g_list_length (context->targets); + GdkAtom *atoms; + guint i, n_atoms; GdkDisplay *display = GDK_WINDOW_DISPLAY (context->source_window); + atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms); atomlist = g_new (Atom, n_atoms); - i = 0; - while (tmp_list) - { - atomlist[i] = gdk_x11_atom_to_xatom_for_display (display, GDK_POINTER_TO_ATOM (tmp_list->data)); - tmp_list = tmp_list->next; - i++; - } + for (i = 0; i < n_atoms; i++) + atomlist[i] = gdk_x11_atom_to_xatom_for_display (display, atoms[i]); XChangeProperty (GDK_WINDOW_XDISPLAY (context->source_window), GDK_WINDOW_XID (context->source_window), @@ -1054,6 +1041,7 @@ xdnd_set_targets (GdkX11DragContext *context_x11) (guchar *)atomlist, n_atoms); g_free (atomlist); + g_free (atoms); context_x11->xdnd_targets_set = 1; } @@ -1234,6 +1222,8 @@ xdnd_send_enter (GdkX11DragContext *context_x11) { GdkDragContext *context = GDK_DRAG_CONTEXT (context_x11); GdkDisplay *display = GDK_WINDOW_DISPLAY (context->dest_window); + GdkAtom *atoms; + guint i, n_atoms; XEvent xev; xev.xclient.type = ClientMessage; @@ -1251,7 +1241,9 @@ xdnd_send_enter (GdkX11DragContext *context_x11) GDK_NOTE(DND, g_message ("Sending enter source window %#lx XDND protocol version %d\n", GDK_WINDOW_XID (context->source_window), context_x11->version)); - if (g_list_length (context->targets) > 3) + atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms); + + if (n_atoms > 3) { if (!context_x11->xdnd_targets_set) xdnd_set_targets (context_x11); @@ -1259,15 +1251,9 @@ xdnd_send_enter (GdkX11DragContext *context_x11) } else { - GList *tmp_list = context->targets; - gint i = 2; - - while (tmp_list) + for (i = 0; i < n_atoms; i++) { - xev.xclient.data.l[i] = gdk_x11_atom_to_xatom_for_display (display, - GDK_POINTER_TO_ATOM (tmp_list->data)); - tmp_list = tmp_list->next; - i++; + xev.xclient.data.l[i + 2] = gdk_x11_atom_to_xatom_for_display (display, atoms[i]); } } @@ -1654,6 +1640,7 @@ xdnd_enter_filter (GdkXEvent *xev, gulong nitems, after; guchar *data; Atom *atoms; + GPtrArray *formats; guint32 source_window; gboolean get_types; gint version; @@ -1708,7 +1695,7 @@ xdnd_enter_filter (GdkXEvent *xev, context->dest_window = event->any.window; g_object_ref (context->dest_window); - context->targets = NULL; + formats = g_ptr_array_new (); if (get_types) { gdk_x11_display_error_trap_push (display); @@ -1730,12 +1717,9 @@ xdnd_enter_filter (GdkXEvent *xev, } atoms = (Atom *)data; - for (i = 0; i < nitems; i++) - context->targets = - g_list_append (context->targets, - GDK_ATOM_TO_POINTER (gdk_x11_xatom_to_atom_for_display (display, - atoms[i]))); + g_ptr_array_add (formats, + (gpointer) gdk_x11_get_xatom_name_for_display (display, atoms[i])); XFree (atoms); } @@ -1743,15 +1727,16 @@ xdnd_enter_filter (GdkXEvent *xev, { for (i = 0; i < 3; i++) if (xevent->xclient.data.l[2 + i]) - context->targets = - g_list_append (context->targets, - GDK_ATOM_TO_POINTER (gdk_x11_xatom_to_atom_for_display (display, - xevent->xclient.data.l[2 + i]))); + g_ptr_array_add (formats, + (gpointer) gdk_x11_get_xatom_name_for_display (display, + xevent->xclient.data.l[2 + i])); } + context->formats = gdk_content_formats_new ((const char **) formats->pdata, formats->len); + g_ptr_array_unref (formats); #ifdef G_ENABLE_DEBUG if (GDK_DEBUG_CHECK (DND)) - print_target_list (context->targets); + print_target_list (context->formats); #endif /* G_ENABLE_DEBUG */ xdnd_manage_source_filter (context, context->source_window, TRUE); @@ -1994,11 +1979,11 @@ create_drag_window (GdkDisplay *display) } GdkDragContext * -_gdk_x11_window_drag_begin (GdkWindow *window, - GdkDevice *device, - GList *targets, - gint x_root, - gint y_root) +_gdk_x11_window_drag_begin (GdkWindow *window, + GdkDevice *device, + GdkContentFormats *formats, + gint x_root, + gint y_root) { GdkDragContext *context; @@ -2009,7 +1994,7 @@ _gdk_x11_window_drag_begin (GdkWindow *window, context->source_window = window; g_object_ref (window); - context->targets = g_list_copy (targets); + context->formats = gdk_content_formats_ref (formats); precache_target_list (context); context->actions = 0; @@ -2325,13 +2310,8 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context, /* 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 (g_list_find (context->targets, - GDK_ATOM_TO_POINTER (target1)) || - g_list_find (context->targets, - GDK_ATOM_TO_POINTER (target2))) + if (gdk_content_formats_contains (context->formats, "application/x-rootwindow-drop") || + gdk_content_formats_contains (context->formats, "application/x-rootwin-drop")) context->action = context->suggested_action; else context->action = 0; diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h index 17c235e982..b594e8605d 100644 --- a/gdk/x11/gdkprivate-x11.h +++ b/gdk/x11/gdkprivate-x11.h @@ -282,11 +282,11 @@ void _gdk_x11_cursor_display_finalize (GdkDisplay *display); void _gdk_x11_window_register_dnd (GdkWindow *window); -GdkDragContext * _gdk_x11_window_drag_begin (GdkWindow *window, - GdkDevice *device, - GList *targets, - gint x_root, - gint y_root); +GdkDragContext * _gdk_x11_window_drag_begin (GdkWindow *window, + GdkDevice *device, + GdkContentFormats *formats, + gint x_root, + gint y_root); GdkGrabStatus _gdk_x11_convert_grab_status (gint status); diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c index 45e693201b..2e8af5a8c3 100644 --- a/gtk/gtkdnd.c +++ b/gtk/gtkdnd.c @@ -1180,7 +1180,6 @@ gtk_drag_begin_internal (GtkWidget *widget, int y) { GtkDragSourceInfo *info; - GList *targets = NULL; guint32 time = GDK_CURRENT_TIME; GdkDragAction possible_actions, suggested_action; GdkDragContext *context; @@ -1190,8 +1189,6 @@ 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); @@ -1263,13 +1260,6 @@ gtk_drag_begin_internal (GtkWidget *widget, gtk_device_grab_add (ipc_widget, pointer, FALSE); } - atoms = gdk_content_formats_get_atoms (target_list, &n_atoms); - for (i = 0; i < n_atoms; i++) - { - targets = g_list_prepend (targets, (gpointer) atoms[i]); - } - g_free (atoms); - source_widgets = g_slist_prepend (source_widgets, ipc_widget); if (x != -1 && y != -1) @@ -1291,10 +1281,9 @@ gtk_drag_begin_internal (GtkWidget *widget, else gdk_device_get_position (pointer, &start_x, &start_y); - context = gdk_drag_begin_from_point (ipc_window, pointer, targets, start_x, start_y); + context = gdk_drag_begin_from_point (ipc_window, pointer, target_list, start_x, start_y); gdk_drag_context_set_device (context, pointer); - g_list_free (targets); if (managed && !gdk_drag_context_manage_dnd (context, ipc_window, actions)) diff --git a/gtk/gtkdragdest.c b/gtk/gtkdragdest.c index cd9ee3c5f4..91afffba79 100644 --- a/gtk/gtkdragdest.c +++ b/gtk/gtkdragdest.c @@ -411,8 +411,6 @@ gtk_drag_dest_find_target (GtkWidget *widget, GdkDragContext *context, GdkContentFormats *target_list) { - GdkContentFormats *source_list; - GList *tmp_source; GdkAtom result; g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); @@ -424,17 +422,8 @@ gtk_drag_dest_find_target (GtkWidget *widget, if (target_list == NULL) return NULL; - source_list = gdk_content_formats_new (NULL, 0); - for (tmp_source = gdk_drag_context_list_targets (context); - tmp_source != NULL; - tmp_source = tmp_source->next) - { - gdk_content_formats_add (source_list, tmp_source->data); - } - - result = gdk_content_formats_intersects (target_list, source_list); - - gdk_content_formats_unref (source_list); + result = gdk_content_formats_intersects (target_list, + gdk_drag_context_get_formats (context)); return result; } diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index e6c5df7b44..8bf79a9094 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -8149,25 +8149,18 @@ gtk_text_view_drag_data_received (GtkWidget *widget, /* try to find a suitable rich text target instead */ GdkAtom *atoms; gint n_atoms; - GList *list; + GdkContentFormats *dnd_formats, *buffer_formats; GdkAtom target = NULL; copy_tags = FALSE; atoms = gtk_text_buffer_get_deserialize_formats (buffer, &n_atoms); + buffer_formats = gdk_content_formats_new (atoms, n_atoms); + dnd_formats = gdk_drag_context_get_formats (context); - for (list = gdk_drag_context_list_targets (context); list; list = list->next) - { - gint i; - - for (i = 0; i < n_atoms; i++) - if (GUINT_TO_POINTER (atoms[i]) == list->data) - { - target = atoms[i]; - break; - } - } + target = gdk_content_formats_intersects (dnd_formats, buffer_formats); + gdk_content_formats_unref (buffer_formats); g_free (atoms); if (target != NULL) diff --git a/tests/testdnd.c b/tests/testdnd.c index d405fd840b..934fbe554d 100644 --- a/tests/testdnd.c +++ b/tests/testdnd.c @@ -315,7 +315,7 @@ target_drag_motion (GtkWidget *widget, guint time) { GtkWidget *source_widget; - GList *tmp_list; + char *s; if (!have_drag) { @@ -328,15 +328,8 @@ target_drag_motion (GtkWidget *widget, G_OBJECT_TYPE_NAME (source_widget) : "NULL"); - tmp_list = gdk_drag_context_list_targets (context); - while (tmp_list) - { - char *name = gdk_atom_name (GDK_POINTER_TO_ATOM (tmp_list->data)); - g_print ("%s\n", name); - g_free (name); - - tmp_list = tmp_list->next; - } + s = gdk_content_formats_to_string (gdk_drag_context_get_formats (context)); + g_print ("%s\n", s); gdk_drag_status (context, gdk_drag_context_get_suggested_action (context), time); @@ -350,15 +343,20 @@ target_drag_drop (GtkWidget *widget, gint y, guint time) { + GdkContentFormats *formats; + GdkAtom format; + g_print("drop\n"); have_drag = FALSE; gtk_image_set_from_pixbuf (GTK_IMAGE (widget), trashcan_closed); - if (gdk_drag_context_list_targets (context)) + formats = gdk_drag_context_get_formats (context); + format = gdk_content_formats_intersects (formats, formats); + if (format) { gtk_drag_get_data (widget, context, - GDK_POINTER_TO_ATOM (gdk_drag_context_list_targets (context)->data), + format, time); return TRUE; }