gdkdnd: Make GdkDragContext->formats a GdkContentFormats

Instead of it being a GList of GdkAtoms.
This commit is contained in:
Benjamin Otte 2017-11-18 05:53:25 +01:00
parent 9a6ec4e959
commit d6a209816b
19 changed files with 234 additions and 241 deletions

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -100,7 +100,7 @@ struct _GdkDragContext {
GdkWindow *dest_window;
GdkWindow *drag_window;
GList *targets;
GdkContentFormats *formats;
GdkDragAction actions;
GdkDragAction suggested_action;
GdkDragAction action;

View File

@ -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);
}
/**

View File

@ -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);

View File

@ -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

View File

@ -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,

View File

@ -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
{

View File

@ -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;

View File

@ -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);

View File

@ -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))

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}