From 7f8a8f221d60bc5da23602e5e024eb91f8b0f758 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 6 May 2018 02:06:53 +0200 Subject: [PATCH] wayland: Redo DND offer handling Instead of tracking offers in GdkWaylandSelection objects, track the pending offer in the GdkWaylandSeat and pass it to the GdkDragContext once we get an enter event. --- gdk/wayland/gdkdevice-wayland.c | 164 +++++++++++++++++-- gdk/wayland/gdkdnd-wayland.c | 84 ++++------ gdk/wayland/gdkprivate-wayland.h | 18 +-- gdk/wayland/gdkselection-wayland.c | 245 ----------------------------- 4 files changed, 184 insertions(+), 327 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index c9e710ae1e..edeb32f283 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -229,6 +229,11 @@ struct _GdkWaylandSeat uint32_t server_repeat_rate; uint32_t server_repeat_delay; + struct wl_data_offer *pending_offer; + GdkContentFormatsBuilder *pending_builder; + GdkDragAction pending_source_actions; + GdkDragAction pending_action; + struct wl_callback *repeat_callback; guint32 repeat_timer; guint32 repeat_key; @@ -1055,6 +1060,111 @@ _gdk_wayland_device_get_keymap (GdkDevice *device) return seat->keymap; } +static void +gdk_wayland_seat_discard_pending_offer (GdkWaylandSeat *seat) +{ + if (seat->pending_builder) + { + GdkContentFormats *ignore = gdk_content_formats_builder_free_to_formats (seat->pending_builder); + gdk_content_formats_unref (ignore); + seat->pending_builder = NULL; + } + g_clear_pointer (&seat->pending_offer, (GDestroyNotify) wl_data_offer_destroy); + seat->pending_source_actions = 0; + seat->pending_action = 0; +} + +static inline GdkDragAction +gdk_wayland_actions_to_gdk_actions (uint32_t dnd_actions) +{ + GdkDragAction actions = 0; + + if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) + actions |= GDK_ACTION_COPY; + if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) + actions |= GDK_ACTION_MOVE; + if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) + actions |= GDK_ACTION_ASK; + + return actions; +} + +static void +data_offer_offer (void *data, + struct wl_data_offer *offer, + const char *type) +{ + GdkWaylandSeat *seat = data; + + if (seat->pending_offer != offer) + { + GDK_DISPLAY_NOTE (gdk_seat_get_display (GDK_SEAT (seat)), EVENTS, + g_message ("%p: offer for unknown offer %p of %s", + seat, offer, type)); + return; + } + + gdk_content_formats_builder_add_mime_type (seat->pending_builder, type); +} + +static void +data_offer_source_actions (void *data, + struct wl_data_offer *offer, + uint32_t source_actions) +{ + GdkWaylandSeat *seat = data; + GdkDragContext *drop_context; + GdkDevice *device; + + if (offer == seat->pending_offer) + { + seat->pending_source_actions = gdk_wayland_actions_to_gdk_actions (source_actions); + return; + } + + device = gdk_seat_get_pointer (GDK_SEAT (seat)); + drop_context = gdk_wayland_device_get_drop_context (device); + if (drop_context == NULL) + return; + + drop_context->actions = gdk_wayland_actions_to_gdk_actions (source_actions); + + _gdk_wayland_drag_context_emit_event (drop_context, GDK_DRAG_MOTION, + GDK_CURRENT_TIME); +} + +static void +data_offer_action (void *data, + struct wl_data_offer *offer, + uint32_t action) +{ + GdkWaylandSeat *seat = data; + GdkDragContext *drop_context; + GdkDevice *device; + + if (offer == seat->pending_offer) + { + seat->pending_action = gdk_wayland_actions_to_gdk_actions (action); + return; + } + + device = gdk_seat_get_pointer (GDK_SEAT (seat)); + drop_context = gdk_wayland_device_get_drop_context (device); + if (drop_context == NULL) + return; + + drop_context->action = gdk_wayland_actions_to_gdk_actions (action); + + _gdk_wayland_drag_context_emit_event (drop_context, GDK_DRAG_MOTION, + GDK_CURRENT_TIME); +} + +static const struct wl_data_offer_listener data_offer_listener = { + data_offer_offer, + data_offer_source_actions, + data_offer_action +}; + static void data_device_data_offer (void *data, struct wl_data_device *data_device, @@ -1066,7 +1176,16 @@ data_device_data_offer (void *data, g_message ("data device data offer, data device %p, offer %p", data_device, offer)); - gdk_wayland_selection_ensure_offer (seat->display, offer); + gdk_wayland_seat_discard_pending_offer (seat); + + seat->pending_offer = offer; + wl_data_offer_add_listener (offer, + &data_offer_listener, + seat); + + seat->pending_builder = gdk_content_formats_builder_new (); + seat->pending_source_actions = 0; + seat->pending_action = 0; } static void @@ -1080,6 +1199,7 @@ data_device_enter (void *data, { GdkWaylandSeat *seat = data; GdkSurface *dest_surface, *dnd_owner; + GdkContentFormats *formats; GdkDevice *device; dest_surface = wl_surface_get_user_data (surface); @@ -1087,6 +1207,14 @@ data_device_enter (void *data, if (!GDK_IS_SURFACE (dest_surface)) return; + if (offer != seat->pending_offer) + { + GDK_DISPLAY_NOTE (gdk_seat_get_display (GDK_SEAT (seat)), EVENTS, + g_message ("%p: enter event for unknown offer %p, expected %p", + seat, offer, seat->pending_offer)); + return; + } + GDK_DISPLAY_NOTE (seat->display, EVENTS, g_message ("data device enter, data device %p serial %u, surface %p, x %f y %f, offer %p", data_device, serial, surface, wl_fixed_to_double (x), wl_fixed_to_double (y), offer)); @@ -1105,10 +1233,12 @@ data_device_enter (void *data, g_warning ("No device for DND enter, ignoring."); return; } - seat->drop_context = _gdk_wayland_drop_context_new (device, - seat->data_device); - gdk_wayland_drop_context_update_targets (seat->drop_context); + formats = gdk_content_formats_builder_free_to_formats (seat->pending_builder); + seat->pending_builder = NULL; + seat->pending_offer = NULL; + + seat->drop_context = _gdk_wayland_drop_context_new (device, formats, offer); dnd_owner = seat->foreign_dnd_surface; @@ -1119,10 +1249,11 @@ data_device_enter (void *data, _gdk_wayland_drag_context_set_coords (seat->drop_context, wl_fixed_to_double (x), wl_fixed_to_double (y)); + + gdk_wayland_seat_discard_pending_offer (seat); + _gdk_wayland_drag_context_emit_event (seat->drop_context, GDK_DRAG_ENTER, GDK_CURRENT_TIME); - - gdk_wayland_selection_set_offer (seat->display, offer); } static void @@ -1168,7 +1299,6 @@ data_device_motion (void *data, seat->pointer_info.surface_x = wl_fixed_to_double (x); seat->pointer_info.surface_y = wl_fixed_to_double (y); - gdk_wayland_drop_context_update_targets (seat->drop_context); _gdk_wayland_drag_context_set_coords (seat->drop_context, wl_fixed_to_double (x), wl_fixed_to_double (y)); @@ -1198,9 +1328,25 @@ data_device_selection (void *data, GdkContentFormats *formats; if (offer) - formats = gdk_wayland_selection_steal_offer (seat->display, offer); + { + if (offer == seat->pending_offer) + { + formats = gdk_content_formats_builder_free_to_formats (seat->pending_builder); + seat->pending_builder = NULL; + seat->pending_offer = NULL; + } + else + { + formats = gdk_content_formats_new (NULL, 0); + offer = NULL; + } + + gdk_wayland_seat_discard_pending_offer (seat); + } else - formats = gdk_content_formats_new (NULL, 0); + { + formats = gdk_content_formats_new (NULL, 0); + } gdk_wayland_clipboard_claim_remote (GDK_WAYLAND_CLIPBOARD (seat->clipboard), offer, diff --git a/gdk/wayland/gdkdnd-wayland.c b/gdk/wayland/gdkdnd-wayland.c index 1ff24fada5..81ed3505a8 100644 --- a/gdk/wayland/gdkdnd-wayland.c +++ b/gdk/wayland/gdkdnd-wayland.c @@ -50,6 +50,7 @@ struct _GdkWaylandDragContext GdkSurface *dnd_surface; struct wl_surface *dnd_wl_surface; struct wl_data_source *data_source; + struct wl_data_offer *offer; GdkDragAction selected_action; uint32_t serial; gdouble x; @@ -170,21 +171,11 @@ static void gdk_wayland_drop_context_set_status (GdkDragContext *context, gboolean accepted) { - GdkWaylandDragContext *context_wayland; - GdkDisplay *display; - struct wl_data_offer *wl_offer; + GdkWaylandDragContext *context_wayland = GDK_WAYLAND_DRAG_CONTEXT (context); if (!context->dest_surface) return; - context_wayland = GDK_WAYLAND_DRAG_CONTEXT (context); - - display = gdk_device_get_display (gdk_drag_context_get_device (context)); - wl_offer = gdk_wayland_selection_get_offer (display); - - if (!wl_offer) - return; - if (accepted) { const char *const *mimetypes; @@ -199,26 +190,33 @@ gdk_wayland_drop_context_set_status (GdkDragContext *context, if (i < n_mimetypes) { - wl_data_offer_accept (wl_offer, context_wayland->serial, mimetypes[i]); + wl_data_offer_accept (context_wayland->offer, context_wayland->serial, mimetypes[i]); return; } } - wl_data_offer_accept (wl_offer, context_wayland->serial, NULL); + wl_data_offer_accept (context_wayland->offer, context_wayland->serial, NULL); } static void gdk_wayland_drag_context_commit_status (GdkDragContext *context) { - GdkWaylandDragContext *wayland_context; + GdkWaylandDragContext *wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context); GdkDisplay *display; - uint32_t dnd_actions; + uint32_t dnd_actions, all_actions = 0; - wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context); display = gdk_device_get_display (gdk_drag_context_get_device (context)); dnd_actions = gdk_to_wl_actions (wayland_context->selected_action); - gdk_wayland_selection_set_current_offer_actions (display, dnd_actions); + + if (dnd_actions != 0) + all_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | + WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | + WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK; + + if (GDK_WAYLAND_DISPLAY (display)->data_device_manager_version >= + WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION) + wl_data_offer_set_actions (wayland_context->offer, all_actions, dnd_actions); gdk_wayland_drop_context_set_status (context, wayland_context->selected_action != 0); } @@ -239,25 +237,19 @@ gdk_wayland_drag_context_drop_finish (GdkDragContext *context, gboolean success, guint32 time) { + GdkWaylandDragContext *wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context); GdkDisplay *display = gdk_device_get_display (gdk_drag_context_get_device (context)); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); - GdkWaylandDragContext *wayland_context; - struct wl_data_offer *wl_offer; - - wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context); - wl_offer = gdk_wayland_selection_get_offer (display); - if (wl_offer && success && wayland_context->selected_action && + if (success && wayland_context->selected_action && wayland_context->selected_action != GDK_ACTION_ASK) { gdk_wayland_drag_context_commit_status (context); if (display_wayland->data_device_manager_version >= WL_DATA_OFFER_FINISH_SINCE_VERSION) - wl_data_offer_finish (wl_offer); + wl_data_offer_finish (wayland_context->offer); } - - gdk_wayland_selection_set_offer (display, NULL); } static void @@ -268,10 +260,9 @@ gdk_wayland_drag_context_read_async (GdkDragContext *context, GAsyncReadyCallback callback, gpointer user_data) { + GdkWaylandDragContext *wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context); GdkDisplay *display; - GdkContentFormats *dnd_formats; GInputStream *stream; - struct wl_data_offer *offer; const char *mime_type; int pipe_fd[2]; GError *error = NULL; @@ -285,17 +276,14 @@ gdk_wayland_drag_context_read_async (GdkDragContext *context, GDK_DISPLAY_NOTE (display, DND, char *s = gdk_content_formats_to_string (formats); g_message ("%p: read for %s", context, s); g_free (s); ); - dnd_formats = gdk_wayland_selection_get_targets (display); - mime_type = gdk_content_formats_match_mime_type (formats, dnd_formats); + mime_type = gdk_content_formats_match_mime_type (formats, + gdk_drag_context_get_formats (context)); if (mime_type == NULL) { g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("No compatible transfer format found")); return; } - /* offer formats should be empty if we have no offer */ - offer = gdk_wayland_selection_get_offer (display); - g_assert (offer); g_task_set_task_data (task, (gpointer) mime_type, NULL); @@ -305,10 +293,7 @@ gdk_wayland_drag_context_read_async (GdkDragContext *context, return; } - wl_data_offer_accept (offer, - _gdk_wayland_display_get_serial (GDK_WAYLAND_DISPLAY (display)), - mime_type); - wl_data_offer_receive (offer, mime_type, pipe_fd[1]); + wl_data_offer_receive (wayland_context->offer, mime_type, pipe_fd[1]); stream = g_unix_input_stream_new (pipe_fd[0], TRUE); close (pipe_fd[1]); g_task_return_pointer (task, stream, g_object_unref); @@ -515,8 +500,9 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface, GdkDragContext * -_gdk_wayland_drop_context_new (GdkDevice *device, - struct wl_data_device *data_device) +_gdk_wayland_drop_context_new (GdkDevice *device, + GdkContentFormats *formats, + struct wl_data_offer *offer) { GdkWaylandDragContext *context_wayland; GdkDragContext *context; @@ -526,27 +512,12 @@ _gdk_wayland_drop_context_new (GdkDevice *device, NULL); context = GDK_DRAG_CONTEXT (context_wayland); context->is_source = FALSE; - context->formats = gdk_content_formats_new (NULL, 0); + context->formats = formats; + context_wayland->offer = offer; return context; } -void -gdk_wayland_drop_context_update_targets (GdkDragContext *context) -{ - GdkDisplay *display; - GdkDevice *device; - - device = gdk_drag_context_get_device (context); - display = gdk_device_get_display (device); - gdk_content_formats_unref (context->formats); - context->formats = gdk_wayland_selection_get_targets (display); - if (context->formats) - gdk_content_formats_ref (context->formats); - else - context->formats = gdk_content_formats_new (NULL, 0); -} - void _gdk_wayland_drag_context_set_coords (GdkDragContext *context, gdouble x, @@ -579,7 +550,6 @@ _gdk_wayland_drag_context_set_dest_surface (GdkDragContext *context, context->dest_surface = dest_surface ? g_object_ref (dest_surface) : NULL; GDK_WAYLAND_DRAG_CONTEXT (context)->serial = serial; - gdk_wayland_drop_context_update_targets (context); } GdkDragContext * diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index 0403073c30..0795a0fe35 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -105,7 +105,8 @@ void _gdk_wayland_surface_offset_next_wl_buffer (GdkSurface *surface, int x, int y); GdkDragContext * _gdk_wayland_drop_context_new (GdkDevice *device, - struct wl_data_device *data_device); + GdkContentFormats *formats, + struct wl_data_offer *offer); void _gdk_wayland_drag_context_set_source_surface (GdkDragContext *context, GdkSurface *surface); void _gdk_wayland_drag_context_set_dest_surface (GdkDragContext *context, @@ -125,8 +126,6 @@ GdkDragContext * gdk_wayland_drag_context_lookup_by_data_source (struct wl_dat GdkDragContext * gdk_wayland_drag_context_lookup_by_source_surface (GdkSurface *surface); struct wl_data_source * gdk_wayland_drag_context_get_data_source (GdkDragContext *context); -void gdk_wayland_drop_context_update_targets (GdkDragContext *context); - void _gdk_wayland_display_create_surface_impl (GdkDisplay *display, GdkSurface *surface, GdkSurface *real_parent, @@ -198,21 +197,8 @@ GdkWaylandSelection * gdk_wayland_selection_new (void); 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_ensure_primary_offer (GdkDisplay *display, - struct gtk_primary_selection_offer *wp_offer); -GdkContentFormats *gdk_wayland_selection_steal_offer (GdkDisplay *display, gpointer wl_offer); - -void gdk_wayland_selection_set_offer (GdkDisplay *display, - gpointer offer); -gpointer gdk_wayland_selection_get_offer (GdkDisplay *display); -GdkContentFormats *gdk_wayland_selection_get_targets (GdkDisplay *display); - struct wl_data_source * gdk_wayland_selection_get_data_source (GdkSurface *owner); void gdk_wayland_selection_unset_data_source (GdkDisplay *display); -gboolean gdk_wayland_selection_set_current_offer_actions (GdkDisplay *display, - uint32_t actions); EGLSurface gdk_wayland_surface_get_egl_surface (GdkSurface *surface, EGLConfig config); diff --git a/gdk/wayland/gdkselection-wayland.c b/gdk/wayland/gdkselection-wayland.c index 66e5cc3b63..ba9dc49bb0 100644 --- a/gdk/wayland/gdkselection-wayland.c +++ b/gdk/wayland/gdkselection-wayland.c @@ -33,52 +33,11 @@ #include -typedef struct _SelectionData SelectionData; -typedef struct _DataOfferData DataOfferData; - -struct _DataOfferData -{ - GDestroyNotify destroy_notify; - gpointer offer_data; - GdkContentFormats *targets; -}; - -struct _SelectionData -{ - DataOfferData *offer; -}; - struct _GdkWaylandSelection { - /* Destination-side data */ - SelectionData selection; - GHashTable *offers; /* Currently alive offers, Hashtable of wl_data_offer->DataOfferData */ - struct wl_data_source *dnd_source; /* Owned by the GdkDragContext */ }; -static DataOfferData * -data_offer_data_new (gpointer offer, - GDestroyNotify destroy_notify) -{ - DataOfferData *info; - - info = g_slice_new0 (DataOfferData); - info->offer_data = offer; - info->destroy_notify = destroy_notify; - info->targets = gdk_content_formats_new (NULL, 0); - - return info; -} - -static void -data_offer_data_free (DataOfferData *info) -{ - info->destroy_notify (info->offer_data); - gdk_content_formats_unref (info->targets); - g_slice_free (DataOfferData, info); -} - GdkWaylandSelection * gdk_wayland_selection_new (void) { @@ -86,47 +45,18 @@ gdk_wayland_selection_new (void) selection = g_new0 (GdkWaylandSelection, 1); - selection->offers = - g_hash_table_new_full (NULL, NULL, NULL, - (GDestroyNotify) data_offer_data_free); return selection; } void gdk_wayland_selection_free (GdkWaylandSelection *selection) { - g_hash_table_destroy (selection->offers); - if (selection->dnd_source) wl_data_source_destroy (selection->dnd_source); g_free (selection); } -static void -data_offer_offer (void *data, - struct wl_data_offer *wl_data_offer, - const char *type) -{ - GdkWaylandSelection *selection = data; - GdkContentFormatsBuilder *builder; - DataOfferData *info; - - info = g_hash_table_lookup (selection->offers, wl_data_offer); - - if (!info || gdk_content_formats_contain_mime_type (info->targets, type)) - return; - - GDK_NOTE (EVENTS, - g_message ("data offer offer, offer %p, type = %s", wl_data_offer, type)); - - builder = gdk_content_formats_builder_new (); - gdk_content_formats_builder_add_formats (builder, info->targets); - gdk_content_formats_builder_add_mime_type (builder, type); - gdk_content_formats_unref (info->targets); - info->targets = gdk_content_formats_builder_free_to_formats (builder); -} - static inline GdkDragAction _wl_to_gdk_actions (uint32_t dnd_actions) { @@ -142,158 +72,6 @@ _wl_to_gdk_actions (uint32_t dnd_actions) return actions; } -static void -data_offer_source_actions (void *data, - struct wl_data_offer *wl_data_offer, - uint32_t source_actions) -{ - GdkDragContext *drop_context; - GdkDisplay *display; - GdkDevice *device; - GdkSeat *seat; - - display = gdk_display_get_default (); - seat = gdk_display_get_default_seat (display); - device = gdk_seat_get_pointer (seat); - drop_context = gdk_wayland_device_get_drop_context (device); - if (drop_context == NULL) - return; - - drop_context->actions = _wl_to_gdk_actions (source_actions); - - GDK_DISPLAY_NOTE (display, EVENTS, - g_message ("data offer source actions, offer %p, actions %d", wl_data_offer, source_actions)); - - _gdk_wayland_drag_context_emit_event (drop_context, GDK_DRAG_MOTION, - GDK_CURRENT_TIME); -} - -static void -data_offer_action (void *data, - struct wl_data_offer *wl_data_offer, - uint32_t action) -{ - GdkDragContext *drop_context; - GdkDisplay *display; - GdkDevice *device; - GdkSeat *seat; - - display = gdk_display_get_default (); - seat = gdk_display_get_default_seat (display); - device = gdk_seat_get_pointer (seat); - drop_context = gdk_wayland_device_get_drop_context (device); - if (drop_context == NULL) - return; - - drop_context->action = _wl_to_gdk_actions (action); - - _gdk_wayland_drag_context_emit_event (drop_context, GDK_DRAG_MOTION, - GDK_CURRENT_TIME); -} - -static const struct wl_data_offer_listener data_offer_listener = { - data_offer_offer, - data_offer_source_actions, - data_offer_action -}; - -static SelectionData * -selection_lookup_offer_by_atom (GdkWaylandSelection *selection) -{ - return &selection->selection; -} - -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, - (GDestroyNotify) wl_data_offer_destroy); - g_hash_table_insert (selection->offers, wl_offer, info); - wl_data_offer_add_listener (wl_offer, - &data_offer_listener, - selection); - } -} - -GdkContentFormats * -gdk_wayland_selection_steal_offer (GdkDisplay *display, - gpointer wl_offer) -{ - GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display); - GdkContentFormats *formats; - DataOfferData *info; - - info = g_hash_table_lookup (selection->offers, wl_offer); - if (info == NULL) - return NULL; - - g_hash_table_steal (selection->offers, wl_offer); - formats = info->targets; - g_slice_free (DataOfferData, info); - - return formats; -} - -void -gdk_wayland_selection_set_offer (GdkDisplay *display, - gpointer wl_offer) -{ - GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display); - struct wl_data_offer *prev_offer; - SelectionData *selection_data; - DataOfferData *info; - - info = g_hash_table_lookup (selection->offers, wl_offer); - - prev_offer = gdk_wayland_selection_get_offer (display); - - if (prev_offer) - g_hash_table_remove (selection->offers, prev_offer); - - selection_data = selection_lookup_offer_by_atom (selection); - - if (selection_data) - { - selection_data->offer = info; - } -} - -gpointer -gdk_wayland_selection_get_offer (GdkDisplay *display) -{ - GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display); - const SelectionData *data; - - data = selection_lookup_offer_by_atom (selection); - - if (data && data->offer) - return data->offer->offer_data; - - return NULL; -} - -GdkContentFormats * -gdk_wayland_selection_get_targets (GdkDisplay *display) -{ - GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display); - const SelectionData *data; - - data = selection_lookup_offer_by_atom (selection); - - if (data && data->offer) - return data->offer->targets; - - return NULL; -} - static void data_source_target (void *data, struct wl_data_source *source, @@ -565,26 +343,3 @@ _gdk_wayland_display_utf8_to_string_target (GdkDisplay *display, return sanitize_utf8 (str, TRUE); } -gboolean -gdk_wayland_selection_set_current_offer_actions (GdkDisplay *display, - uint32_t action) -{ - GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); - struct wl_data_offer *offer; - uint32_t all_actions = 0; - - offer = gdk_wayland_selection_get_offer (display); - - if (!offer) - return FALSE; - - if (action != 0) - all_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | - WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | - WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK; - - if (display_wayland->data_device_manager_version >= - WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION) - wl_data_offer_set_actions (offer, all_actions, action); - return TRUE; -} -- 2.30.2