forked from AuroraMiddleware/gtk
wayland: Split handling of clipboard/DnD data offers
We currently only hold the last offer received, which is wrong, as both are independent and have different life cycles. This means we have to store per-selection wl_data_offer and targets, and maintain these as appropriate from the clipboard/DnD specific entry points.
This commit is contained in:
parent
da395606a2
commit
1178a0ac8b
@ -688,8 +688,7 @@ data_device_data_offer (void *data,
|
|||||||
g_message ("data device data offer, data device %p, offer %p",
|
g_message ("data device data offer, data device %p, offer %p",
|
||||||
data_device, offer));
|
data_device, offer));
|
||||||
|
|
||||||
gdk_wayland_selection_set_offer (device->display, offer);
|
gdk_wayland_selection_ensure_offer (device->display, offer);
|
||||||
emit_selection_owner_change_forall (gdk_atom_intern_static_string ("GdkWaylandSelection"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -703,6 +702,7 @@ data_device_enter (void *data,
|
|||||||
{
|
{
|
||||||
GdkWaylandDeviceData *device = (GdkWaylandDeviceData *)data;
|
GdkWaylandDeviceData *device = (GdkWaylandDeviceData *)data;
|
||||||
GdkWindow *dest_window, *dnd_owner;
|
GdkWindow *dest_window, *dnd_owner;
|
||||||
|
GdkAtom selection;
|
||||||
|
|
||||||
dest_window = wl_surface_get_user_data (surface);
|
dest_window = wl_surface_get_user_data (surface);
|
||||||
|
|
||||||
@ -720,7 +720,8 @@ data_device_enter (void *data,
|
|||||||
|
|
||||||
gdk_wayland_drop_context_update_targets (device->drop_context);
|
gdk_wayland_drop_context_update_targets (device->drop_context);
|
||||||
|
|
||||||
dnd_owner = gdk_selection_owner_get_for_display (device->display, gdk_drag_get_selection (device->drop_context));
|
selection = gdk_drag_get_selection (device->drop_context);
|
||||||
|
dnd_owner = gdk_selection_owner_get_for_display (device->display, selection);
|
||||||
|
|
||||||
if (!dnd_owner)
|
if (!dnd_owner)
|
||||||
dnd_owner = device->foreign_dnd_window;
|
dnd_owner = device->foreign_dnd_window;
|
||||||
@ -734,9 +735,9 @@ data_device_enter (void *data,
|
|||||||
wl_fixed_to_double (y));
|
wl_fixed_to_double (y));
|
||||||
_gdk_wayland_drag_context_emit_event (device->drop_context, GDK_DRAG_ENTER,
|
_gdk_wayland_drag_context_emit_event (device->drop_context, GDK_DRAG_ENTER,
|
||||||
GDK_CURRENT_TIME);
|
GDK_CURRENT_TIME);
|
||||||
gdk_wayland_selection_set_offer (device->display, offer);
|
|
||||||
emit_selection_owner_change (dest_window,
|
gdk_wayland_selection_set_offer (device->display, selection, offer);
|
||||||
gdk_atom_intern_static_string ("GdkWaylandSelection"));
|
emit_selection_owner_change_forall (selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -811,13 +812,15 @@ data_device_selection (void *data,
|
|||||||
struct wl_data_offer *offer)
|
struct wl_data_offer *offer)
|
||||||
{
|
{
|
||||||
GdkWaylandDeviceData *device = (GdkWaylandDeviceData *) data;
|
GdkWaylandDeviceData *device = (GdkWaylandDeviceData *) data;
|
||||||
|
GdkAtom selection;
|
||||||
|
|
||||||
GDK_NOTE (EVENTS,
|
GDK_NOTE (EVENTS,
|
||||||
g_message ("data device selection, data device %p, data offer %p",
|
g_message ("data device selection, data device %p, data offer %p",
|
||||||
wl_data_device, offer));
|
wl_data_device, offer));
|
||||||
|
|
||||||
gdk_wayland_selection_set_offer (device->display, offer);
|
selection = gdk_atom_intern_static_string ("CLIPBOARD");
|
||||||
emit_selection_owner_change_forall (gdk_atom_intern_static_string ("CLIPBOARD"));
|
gdk_wayland_selection_set_offer (device->display, selection, offer);
|
||||||
|
emit_selection_owner_change_forall (selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_data_device_listener data_device_listener = {
|
static const struct wl_data_device_listener data_device_listener = {
|
||||||
|
@ -43,7 +43,6 @@ struct _GdkWaylandDragContext
|
|||||||
GdkWindow *dnd_window;
|
GdkWindow *dnd_window;
|
||||||
struct wl_surface *dnd_surface;
|
struct wl_surface *dnd_surface;
|
||||||
struct wl_data_source *data_source;
|
struct wl_data_source *data_source;
|
||||||
struct wl_data_offer *offer;
|
|
||||||
uint32_t serial;
|
uint32_t serial;
|
||||||
gdouble x;
|
gdouble x;
|
||||||
gdouble y;
|
gdouble y;
|
||||||
@ -196,8 +195,10 @@ gdk_wayland_drop_context_set_status (GdkDragContext *context,
|
|||||||
struct wl_data_offer *wl_offer;
|
struct wl_data_offer *wl_offer;
|
||||||
|
|
||||||
context_wayland = GDK_WAYLAND_DRAG_CONTEXT (context);
|
context_wayland = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||||
display = gdk_window_get_display (context->source_window);
|
|
||||||
wl_offer = gdk_wayland_selection_get_offer (display);
|
display = gdk_device_get_display (gdk_drag_context_get_device (context));
|
||||||
|
wl_offer = gdk_wayland_selection_get_offer (display,
|
||||||
|
gdk_drag_get_selection (context));
|
||||||
|
|
||||||
if (!wl_offer)
|
if (!wl_offer)
|
||||||
return;
|
return;
|
||||||
@ -247,10 +248,15 @@ gdk_wayland_drag_context_drop_finish (GdkDragContext *context,
|
|||||||
gboolean success,
|
gboolean success,
|
||||||
guint32 time)
|
guint32 time)
|
||||||
{
|
{
|
||||||
GdkDisplay *display = gdk_window_get_display (context->source_window);
|
GdkDisplay *display = gdk_device_get_display (gdk_drag_context_get_device (context));
|
||||||
|
GdkAtom selection;
|
||||||
|
|
||||||
if (gdk_selection_owner_get_for_display (display, gdk_drag_get_selection (context)))
|
selection = gdk_drag_get_selection (context);
|
||||||
gdk_wayland_selection_unset_data_source (display, gdk_drag_get_selection (context));
|
|
||||||
|
if (gdk_selection_owner_get_for_display (display, selection))
|
||||||
|
gdk_wayland_selection_unset_data_source (display, selection);
|
||||||
|
|
||||||
|
gdk_wayland_selection_set_offer (display, selection, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -396,7 +402,8 @@ gdk_wayland_drop_context_update_targets (GdkDragContext *context)
|
|||||||
device = gdk_drag_context_get_device (context);
|
device = gdk_drag_context_get_device (context);
|
||||||
display = gdk_device_get_display (device);
|
display = gdk_device_get_display (device);
|
||||||
g_list_free (context->targets);
|
g_list_free (context->targets);
|
||||||
context->targets = g_list_copy (gdk_wayland_selection_get_targets (display));
|
context->targets = g_list_copy (gdk_wayland_selection_get_targets (display,
|
||||||
|
gdk_drag_get_selection (context)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -237,10 +237,15 @@ GdkWaylandSelection * gdk_wayland_display_get_selection (GdkDisplay *display);
|
|||||||
GdkWaylandSelection * gdk_wayland_selection_new (void);
|
GdkWaylandSelection * gdk_wayland_selection_new (void);
|
||||||
void gdk_wayland_selection_free (GdkWaylandSelection *selection);
|
void gdk_wayland_selection_free (GdkWaylandSelection *selection);
|
||||||
|
|
||||||
|
void gdk_wayland_selection_ensure_offer (GdkDisplay *display,
|
||||||
|
struct wl_data_offer *wl_offer);
|
||||||
void gdk_wayland_selection_set_offer (GdkDisplay *display,
|
void gdk_wayland_selection_set_offer (GdkDisplay *display,
|
||||||
|
GdkAtom selection,
|
||||||
struct wl_data_offer *wl_offer);
|
struct wl_data_offer *wl_offer);
|
||||||
struct wl_data_offer * gdk_wayland_selection_get_offer (GdkDisplay *display);
|
struct wl_data_offer * gdk_wayland_selection_get_offer (GdkDisplay *display,
|
||||||
GList * gdk_wayland_selection_get_targets (GdkDisplay *display);
|
GdkAtom selection);
|
||||||
|
GList * gdk_wayland_selection_get_targets (GdkDisplay *display,
|
||||||
|
GdkAtom selection);
|
||||||
|
|
||||||
void gdk_wayland_selection_store (GdkWindow *window,
|
void gdk_wayland_selection_store (GdkWindow *window,
|
||||||
GdkAtom type,
|
GdkAtom type,
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
typedef struct _SelectionBuffer SelectionBuffer;
|
typedef struct _SelectionBuffer SelectionBuffer;
|
||||||
typedef struct _StoredSelection StoredSelection;
|
typedef struct _StoredSelection StoredSelection;
|
||||||
typedef struct _AsyncWriteData AsyncWriteData;
|
typedef struct _AsyncWriteData AsyncWriteData;
|
||||||
|
typedef struct _DataOfferData DataOfferData;
|
||||||
|
|
||||||
struct _SelectionBuffer
|
struct _SelectionBuffer
|
||||||
{
|
{
|
||||||
@ -64,6 +65,13 @@ struct _DataSourceData
|
|||||||
GdkAtom selection;
|
GdkAtom selection;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _DataOfferData
|
||||||
|
{
|
||||||
|
struct wl_data_offer *offer;
|
||||||
|
GList *targets; /* List of GdkAtom */
|
||||||
|
GdkAtom requested_target;
|
||||||
|
};
|
||||||
|
|
||||||
struct _AsyncWriteData
|
struct _AsyncWriteData
|
||||||
{
|
{
|
||||||
GOutputStream *stream;
|
GOutputStream *stream;
|
||||||
@ -81,11 +89,10 @@ static GdkAtom atoms[2] = { 0 };
|
|||||||
struct _GdkWaylandSelection
|
struct _GdkWaylandSelection
|
||||||
{
|
{
|
||||||
/* Destination-side data */
|
/* Destination-side data */
|
||||||
struct wl_data_offer *offer;
|
DataOfferData *dnd_offer;
|
||||||
GdkAtom source_requested_target;
|
DataOfferData *clipboard_offer;
|
||||||
|
GHashTable *offers; /* Currently alive offers, Hashtable of wl_data_offer->DataOfferData */
|
||||||
GHashTable *selection_buffers; /* Hashtable of target_atom->SelectionBuffer */
|
GHashTable *selection_buffers; /* Hashtable of target_atom->SelectionBuffer */
|
||||||
GList *targets; /* List of GdkAtom */
|
|
||||||
|
|
||||||
/* Source-side data */
|
/* Source-side data */
|
||||||
StoredSelection stored_selection;
|
StoredSelection stored_selection;
|
||||||
@ -260,6 +267,25 @@ selection_buffer_read (SelectionBuffer *buffer)
|
|||||||
buffer);
|
buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DataOfferData *
|
||||||
|
data_offer_data_new (struct wl_data_offer *offer)
|
||||||
|
{
|
||||||
|
DataOfferData *info;
|
||||||
|
|
||||||
|
info = g_slice_new0 (DataOfferData);
|
||||||
|
info->offer = offer;
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
data_offer_data_free (DataOfferData *info)
|
||||||
|
{
|
||||||
|
wl_data_offer_destroy (info->offer);
|
||||||
|
g_list_free (info->targets);
|
||||||
|
g_slice_free (DataOfferData, info);
|
||||||
|
}
|
||||||
|
|
||||||
GdkWaylandSelection *
|
GdkWaylandSelection *
|
||||||
gdk_wayland_selection_new (void)
|
gdk_wayland_selection_new (void)
|
||||||
{
|
{
|
||||||
@ -271,8 +297,11 @@ gdk_wayland_selection_new (void)
|
|||||||
|
|
||||||
selection = g_new0 (GdkWaylandSelection, 1);
|
selection = g_new0 (GdkWaylandSelection, 1);
|
||||||
selection->selection_buffers =
|
selection->selection_buffers =
|
||||||
g_hash_table_new_full (NULL, NULL, NULL,
|
g_hash_table_new_full (NULL, NULL, NULL,
|
||||||
(GDestroyNotify) selection_buffer_cancel_and_unref);
|
(GDestroyNotify) selection_buffer_cancel_and_unref);
|
||||||
|
selection->offers =
|
||||||
|
g_hash_table_new_full (NULL, NULL, NULL,
|
||||||
|
(GDestroyNotify) data_offer_data_free);
|
||||||
selection->stored_selection.fd = -1;
|
selection->stored_selection.fd = -1;
|
||||||
selection->source_targets = g_array_new (FALSE, FALSE, sizeof (GdkAtom));
|
selection->source_targets = g_array_new (FALSE, FALSE, sizeof (GdkAtom));
|
||||||
return selection;
|
return selection;
|
||||||
@ -284,9 +313,7 @@ gdk_wayland_selection_free (GdkWaylandSelection *selection)
|
|||||||
g_hash_table_destroy (selection->selection_buffers);
|
g_hash_table_destroy (selection->selection_buffers);
|
||||||
g_array_unref (selection->source_targets);
|
g_array_unref (selection->source_targets);
|
||||||
|
|
||||||
if (selection->targets)
|
g_hash_table_destroy (selection->offers);
|
||||||
g_list_free (selection->targets);
|
|
||||||
|
|
||||||
g_free (selection->stored_selection.data);
|
g_free (selection->stored_selection.data);
|
||||||
|
|
||||||
if (selection->stored_selection.cancellable)
|
if (selection->stored_selection.cancellable)
|
||||||
@ -298,8 +325,6 @@ gdk_wayland_selection_free (GdkWaylandSelection *selection)
|
|||||||
if (selection->stored_selection.fd > 0)
|
if (selection->stored_selection.fd > 0)
|
||||||
close (selection->stored_selection.fd);
|
close (selection->stored_selection.fd);
|
||||||
|
|
||||||
if (selection->offer)
|
|
||||||
wl_data_offer_destroy (selection->offer);
|
|
||||||
if (selection->clipboard_source)
|
if (selection->clipboard_source)
|
||||||
wl_data_source_destroy (selection->clipboard_source);
|
wl_data_source_destroy (selection->clipboard_source);
|
||||||
if (selection->dnd_source)
|
if (selection->dnd_source)
|
||||||
@ -314,57 +339,105 @@ data_offer_offer (void *data,
|
|||||||
const char *type)
|
const char *type)
|
||||||
{
|
{
|
||||||
GdkWaylandSelection *selection = data;
|
GdkWaylandSelection *selection = data;
|
||||||
|
DataOfferData *info;
|
||||||
GdkAtom atom = gdk_atom_intern (type, FALSE);
|
GdkAtom atom = gdk_atom_intern (type, FALSE);
|
||||||
|
|
||||||
if (g_list_find (selection->targets, atom))
|
info = g_hash_table_lookup (selection->offers, wl_data_offer);
|
||||||
|
|
||||||
|
if (!info || g_list_find (info->targets, atom))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
selection->targets = g_list_prepend (selection->targets, atom);
|
info->targets = g_list_prepend (info->targets, atom);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_data_offer_listener data_offer_listener = {
|
static const struct wl_data_offer_listener data_offer_listener = {
|
||||||
data_offer_offer,
|
data_offer_offer,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DataOfferData *
|
||||||
|
selection_lookup_offer_by_atom (GdkWaylandSelection *selection,
|
||||||
|
GdkAtom selection_atom)
|
||||||
|
{
|
||||||
|
if (selection_atom == atoms[ATOM_CLIPBOARD])
|
||||||
|
return selection->clipboard_offer;
|
||||||
|
else if (selection_atom == atoms[ATOM_DND])
|
||||||
|
return selection->dnd_offer;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdk_wayland_selection_ensure_offer (GdkDisplay *display,
|
||||||
|
struct wl_data_offer *wl_offer)
|
||||||
|
{
|
||||||
|
GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
|
||||||
|
DataOfferData *info;
|
||||||
|
|
||||||
|
info = g_hash_table_lookup (selection->offers, wl_offer);
|
||||||
|
|
||||||
|
if (!info)
|
||||||
|
{
|
||||||
|
info = data_offer_data_new (wl_offer);
|
||||||
|
g_hash_table_insert (selection->offers, wl_offer, info);
|
||||||
|
wl_data_offer_add_listener (wl_offer,
|
||||||
|
&data_offer_listener,
|
||||||
|
selection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gdk_wayland_selection_set_offer (GdkDisplay *display,
|
gdk_wayland_selection_set_offer (GdkDisplay *display,
|
||||||
|
GdkAtom selection_atom,
|
||||||
struct wl_data_offer *wl_offer)
|
struct wl_data_offer *wl_offer)
|
||||||
{
|
{
|
||||||
GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
|
GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
|
||||||
|
struct wl_data_offer *prev_offer;
|
||||||
|
DataOfferData *info;
|
||||||
|
|
||||||
if (selection->offer == wl_offer)
|
info = g_hash_table_lookup (selection->offers, wl_offer);
|
||||||
return;
|
|
||||||
|
|
||||||
if (selection->offer)
|
prev_offer = gdk_wayland_selection_get_offer (display, selection_atom);
|
||||||
wl_data_offer_destroy (selection->offer);
|
|
||||||
|
|
||||||
selection->offer = wl_offer;
|
if (prev_offer)
|
||||||
|
g_hash_table_remove (selection->offers, prev_offer);
|
||||||
|
|
||||||
if (wl_offer)
|
if (selection_atom == atoms[ATOM_CLIPBOARD])
|
||||||
wl_data_offer_add_listener (wl_offer,
|
selection->clipboard_offer = info;
|
||||||
&data_offer_listener,
|
else if (selection_atom == atoms[ATOM_DND])
|
||||||
selection);
|
selection->dnd_offer = info;
|
||||||
|
|
||||||
/* Clear all buffers */
|
/* Clear all buffers */
|
||||||
g_hash_table_remove_all (selection->selection_buffers);
|
g_hash_table_remove_all (selection->selection_buffers);
|
||||||
g_list_free (selection->targets);
|
|
||||||
selection->targets = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wl_data_offer *
|
struct wl_data_offer *
|
||||||
gdk_wayland_selection_get_offer (GdkDisplay *display)
|
gdk_wayland_selection_get_offer (GdkDisplay *display,
|
||||||
|
GdkAtom selection_atom)
|
||||||
{
|
{
|
||||||
GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
|
GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
|
||||||
|
const DataOfferData *info;
|
||||||
|
|
||||||
return selection->offer;
|
info = selection_lookup_offer_by_atom (selection, selection_atom);
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
return info->offer;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
GList *
|
GList *
|
||||||
gdk_wayland_selection_get_targets (GdkDisplay *display)
|
gdk_wayland_selection_get_targets (GdkDisplay *display,
|
||||||
|
GdkAtom selection_atom)
|
||||||
{
|
{
|
||||||
GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
|
GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
|
||||||
|
const DataOfferData *info;
|
||||||
|
|
||||||
return selection->targets;
|
info = selection_lookup_offer_by_atom (selection, selection_atom);
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
return info->targets;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -584,6 +657,7 @@ gdk_wayland_selection_request_target (GdkWaylandSelection *wayland_selection,
|
|||||||
GdkAtom target,
|
GdkAtom target,
|
||||||
gint fd)
|
gint fd)
|
||||||
{
|
{
|
||||||
|
DataOfferData *offer;
|
||||||
GdkAtom selection;
|
GdkAtom selection;
|
||||||
|
|
||||||
if (wayland_selection->clipboard_owner == window)
|
if (wayland_selection->clipboard_owner == window)
|
||||||
@ -593,8 +667,10 @@ gdk_wayland_selection_request_target (GdkWaylandSelection *wayland_selection,
|
|||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
offer = selection_lookup_offer_by_atom (wayland_selection, selection);
|
||||||
|
|
||||||
if (wayland_selection->stored_selection.fd == fd &&
|
if (wayland_selection->stored_selection.fd == fd &&
|
||||||
wayland_selection->source_requested_target == target)
|
offer->requested_target == target)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* If we didn't issue gdk_wayland_selection_check_write() yet
|
/* If we didn't issue gdk_wayland_selection_check_write() yet
|
||||||
@ -605,8 +681,7 @@ gdk_wayland_selection_request_target (GdkWaylandSelection *wayland_selection,
|
|||||||
close (wayland_selection->stored_selection.fd);
|
close (wayland_selection->stored_selection.fd);
|
||||||
|
|
||||||
wayland_selection->stored_selection.fd = fd;
|
wayland_selection->stored_selection.fd = fd;
|
||||||
|
offer->requested_target = target;
|
||||||
wayland_selection->source_requested_target = target;
|
|
||||||
|
|
||||||
if (window &&
|
if (window &&
|
||||||
gdk_wayland_selection_source_handles_target (wayland_selection, target))
|
gdk_wayland_selection_source_handles_target (wayland_selection, target))
|
||||||
@ -707,8 +782,6 @@ data_source_send (void *data,
|
|||||||
_gdk_wayland_drag_context_emit_event (context, GDK_DROP_FINISHED,
|
_gdk_wayland_drag_context_emit_event (context, GDK_DROP_FINISHED,
|
||||||
GDK_CURRENT_TIME);
|
GDK_CURRENT_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
wayland_selection->source_requested_target = GDK_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -931,9 +1004,14 @@ _gdk_wayland_display_convert_selection (GdkDisplay *display,
|
|||||||
{
|
{
|
||||||
GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);
|
GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);
|
||||||
SelectionBuffer *buffer_data;
|
SelectionBuffer *buffer_data;
|
||||||
|
struct wl_data_offer *offer;
|
||||||
gchar *mimetype;
|
gchar *mimetype;
|
||||||
|
GList *target_list;
|
||||||
|
|
||||||
if (!wayland_selection->offer)
|
offer = gdk_wayland_selection_get_offer (display, selection);
|
||||||
|
target_list = gdk_wayland_selection_get_targets (display, selection);
|
||||||
|
|
||||||
|
if (!offer)
|
||||||
{
|
{
|
||||||
GdkEvent *event;
|
GdkEvent *event;
|
||||||
|
|
||||||
@ -954,7 +1032,7 @@ _gdk_wayland_display_convert_selection (GdkDisplay *display,
|
|||||||
mimetype = gdk_atom_name (target);
|
mimetype = gdk_atom_name (target);
|
||||||
|
|
||||||
if (target != gdk_atom_intern_static_string ("TARGETS"))
|
if (target != gdk_atom_intern_static_string ("TARGETS"))
|
||||||
wl_data_offer_accept (wayland_selection->offer,
|
wl_data_offer_accept (offer,
|
||||||
_gdk_wayland_display_get_serial (GDK_WAYLAND_DISPLAY (display)),
|
_gdk_wayland_display_get_serial (GDK_WAYLAND_DISPLAY (display)),
|
||||||
mimetype);
|
mimetype);
|
||||||
|
|
||||||
@ -974,17 +1052,16 @@ _gdk_wayland_display_convert_selection (GdkDisplay *display,
|
|||||||
gint i = 0;
|
gint i = 0;
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
natoms = g_list_length (wayland_selection->targets);
|
natoms = g_list_length (target_list);
|
||||||
targets = g_new0 (GdkAtom, natoms);
|
targets = g_new0 (GdkAtom, natoms);
|
||||||
|
|
||||||
for (l = wayland_selection->targets; l; l = l->next)
|
for (l = target_list; l; l = l->next)
|
||||||
targets[i++] = l->data;
|
targets[i++] = l->data;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_unix_open_pipe (pipe_fd, FD_CLOEXEC, NULL);
|
g_unix_open_pipe (pipe_fd, FD_CLOEXEC, NULL);
|
||||||
wl_data_offer_receive (wayland_selection->offer,
|
wl_data_offer_receive (offer, mimetype, pipe_fd[1]);
|
||||||
mimetype, pipe_fd[1]);
|
|
||||||
stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
|
stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
|
||||||
close (pipe_fd[1]);
|
close (pipe_fd[1]);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user