mirror of
https://github.com/brl/mutter.git
synced 2024-11-09 15:37:00 -05:00
wayland: Integrate with MetaSelection
Make MetaWaylandDataDevice use MetaSelection and MetaSelectionSource to handle primary/clipboard/dnd. https://gitlab.gnome.org/GNOME/mutter/merge_requests/320
This commit is contained in:
parent
5c009c20ab
commit
634f512bb0
@ -27,6 +27,7 @@
|
||||
#include "wayland/meta-wayland-data-device.h"
|
||||
#include "wayland/meta-wayland-data-device-private.h"
|
||||
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <glib-unix.h>
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
@ -35,6 +36,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "compositor/meta-dnd-actor-private.h"
|
||||
#include "wayland/meta-selection-source-wayland-private.h"
|
||||
#include "wayland/meta-wayland-dnd-surface.h"
|
||||
#include "wayland/meta-wayland-pointer.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
@ -101,6 +103,11 @@ meta_wayland_data_source_primary_new (struct wl_resource *resource);
|
||||
static void
|
||||
drag_grab_data_source_destroyed (gpointer data, GObject *where_the_object_was);
|
||||
|
||||
static struct wl_resource * create_and_send_clipboard_offer (MetaWaylandDataDevice *data_device,
|
||||
struct wl_resource *target);
|
||||
static struct wl_resource * create_and_send_primary_offer (MetaWaylandDataDevice *data_device,
|
||||
struct wl_resource *target);
|
||||
|
||||
static void
|
||||
unbind_resource (struct wl_resource *resource)
|
||||
{
|
||||
@ -364,16 +371,60 @@ data_offer_accept (struct wl_client *client,
|
||||
offer->accepted = mime_type != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
transfer_cb (MetaSelection *selection,
|
||||
GAsyncResult *res,
|
||||
GOutputStream *stream)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!meta_selection_transfer_finish (selection, res, &error))
|
||||
{
|
||||
g_warning ("Could not fetch selection data: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_output_stream_close (stream, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
data_offer_receive (struct wl_client *client, struct wl_resource *resource,
|
||||
const char *mime_type, int32_t fd)
|
||||
{
|
||||
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
MetaSelectionType selection_type;
|
||||
GList *mime_types;
|
||||
gboolean found;
|
||||
|
||||
if (offer->source)
|
||||
meta_wayland_data_source_send (offer->source, mime_type, fd);
|
||||
if (offer->dnd_actions != 0)
|
||||
selection_type = META_SELECTION_DND;
|
||||
else
|
||||
selection_type = META_SELECTION_CLIPBOARD;
|
||||
|
||||
mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
||||
selection_type);
|
||||
found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL;
|
||||
g_list_free_full (mime_types, g_free);
|
||||
|
||||
if (found)
|
||||
{
|
||||
GOutputStream *stream;
|
||||
|
||||
stream = g_unix_output_stream_new (fd, TRUE);
|
||||
meta_selection_transfer_async (meta_display_get_selection (display),
|
||||
selection_type,
|
||||
mime_type,
|
||||
-1,
|
||||
stream,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) transfer_cb,
|
||||
stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
close (fd);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -460,26 +511,31 @@ static void
|
||||
primary_offer_receive (struct wl_client *client, struct wl_resource *resource,
|
||||
const char *mime_type, int32_t fd)
|
||||
{
|
||||
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||
MetaWaylandDataSource *source = offer->source;
|
||||
MetaWaylandSeat *seat;
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
GOutputStream *stream;
|
||||
GList *mime_types;
|
||||
gboolean found;
|
||||
|
||||
if (!offer->source)
|
||||
mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
||||
META_SELECTION_CLIPBOARD);
|
||||
found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL;
|
||||
g_list_free_full (mime_types, g_free);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
close (fd);
|
||||
return;
|
||||
}
|
||||
|
||||
seat = meta_wayland_data_source_get_seat (source);
|
||||
|
||||
if (wl_resource_get_client (offer->resource) !=
|
||||
meta_wayland_keyboard_get_focus_client (seat->keyboard))
|
||||
{
|
||||
close (fd);
|
||||
return;
|
||||
}
|
||||
|
||||
meta_wayland_data_source_send (offer->source, mime_type, fd);
|
||||
stream = g_unix_output_stream_new (fd, TRUE);
|
||||
meta_selection_transfer_async (meta_display_get_selection (display),
|
||||
META_SELECTION_PRIMARY,
|
||||
mime_type,
|
||||
-1,
|
||||
stream,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) transfer_cb,
|
||||
stream);
|
||||
}
|
||||
|
||||
static const struct gtk_primary_selection_offer_interface primary_offer_interface = {
|
||||
@ -583,35 +639,6 @@ meta_wayland_data_source_send_offer (MetaWaylandDataSource *source,
|
||||
return offer->resource;
|
||||
}
|
||||
|
||||
static struct wl_resource *
|
||||
meta_wayland_data_source_send_primary_offer (MetaWaylandDataSource *source,
|
||||
struct wl_resource *target)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
MetaWaylandDataOffer *offer = g_slice_new0 (MetaWaylandDataOffer);
|
||||
char **p;
|
||||
|
||||
offer->source = source;
|
||||
g_object_add_weak_pointer (G_OBJECT (source), (gpointer *)&offer->source);
|
||||
offer->resource = wl_resource_create (wl_resource_get_client (target),
|
||||
>k_primary_selection_offer_interface,
|
||||
wl_resource_get_version (target), 0);
|
||||
wl_resource_set_implementation (offer->resource,
|
||||
&primary_offer_interface,
|
||||
offer,
|
||||
destroy_primary_offer);
|
||||
|
||||
gtk_primary_selection_device_send_data_offer (target, offer->resource);
|
||||
|
||||
wl_array_for_each (p, &priv->mime_types)
|
||||
gtk_primary_selection_offer_send_offer (offer->resource, *p);
|
||||
|
||||
meta_wayland_data_source_set_current_offer (source, offer);
|
||||
|
||||
return offer->resource;
|
||||
}
|
||||
|
||||
static void
|
||||
data_source_offer (struct wl_client *client,
|
||||
struct wl_resource *resource, const char *type)
|
||||
@ -712,6 +739,34 @@ struct _MetaWaylandDragGrab {
|
||||
guint need_initial_focus : 1;
|
||||
};
|
||||
|
||||
static void
|
||||
set_selection_source (MetaWaylandDataDevice *data_device,
|
||||
MetaSelectionType selection_type,
|
||||
MetaSelectionSource *selection_source)
|
||||
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
meta_selection_set_owner (meta_display_get_selection (display),
|
||||
selection_type, selection_source);
|
||||
g_set_object (&data_device->owners[selection_type], selection_source);
|
||||
}
|
||||
|
||||
static void
|
||||
unset_selection_source (MetaWaylandDataDevice *data_device,
|
||||
MetaSelectionType selection_type)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
if (!data_device->owners[selection_type])
|
||||
return;
|
||||
|
||||
meta_selection_unset_owner (meta_display_get_selection (display),
|
||||
selection_type,
|
||||
data_device->owners[selection_type]);
|
||||
g_clear_object (&data_device->owners[selection_type]);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_drag_focus (struct wl_listener *listener, void *data)
|
||||
{
|
||||
@ -1005,6 +1060,7 @@ drag_grab_button (MetaWaylandPointerGrab *grab,
|
||||
meta_wayland_data_source_cancel (source);
|
||||
meta_wayland_data_source_set_current_offer (source, NULL);
|
||||
meta_wayland_data_device_set_dnd_source (&seat->data_device, NULL);
|
||||
unset_selection_source (&seat->data_device, META_SELECTION_DND);
|
||||
success= FALSE;
|
||||
}
|
||||
|
||||
@ -1066,6 +1122,7 @@ destroy_data_device_origin (struct wl_listener *listener, void *data)
|
||||
|
||||
drag_grab->drag_origin = NULL;
|
||||
meta_wayland_data_device_set_dnd_source (&drag_grab->seat->data_device, NULL);
|
||||
unset_selection_source (&drag_grab->seat->data_device, META_SELECTION_DND);
|
||||
data_device_end_drag_grab (drag_grab);
|
||||
}
|
||||
|
||||
@ -1076,6 +1133,7 @@ drag_grab_data_source_destroyed (gpointer data, GObject *where_the_object_was)
|
||||
|
||||
drag_grab->drag_data_source = NULL;
|
||||
meta_wayland_data_device_set_dnd_source (&drag_grab->seat->data_device, NULL);
|
||||
unset_selection_source (&drag_grab->seat->data_device, META_SELECTION_DND);
|
||||
data_device_end_drag_grab (drag_grab);
|
||||
}
|
||||
|
||||
@ -1091,6 +1149,18 @@ destroy_data_device_icon (struct wl_listener *listener, void *data)
|
||||
clutter_actor_remove_all_children (drag_grab->feedback_actor);
|
||||
}
|
||||
|
||||
static GList *
|
||||
copy_string_array_to_list (struct wl_array *array)
|
||||
{
|
||||
GList *l = NULL;
|
||||
char **p;
|
||||
|
||||
wl_array_for_each (p, array)
|
||||
l = g_list_prepend (l, g_strdup (*p));
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data_device,
|
||||
struct wl_client *client,
|
||||
@ -1189,6 +1259,8 @@ data_device_start_drag (struct wl_client *client,
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
MetaWaylandSurface *surface = NULL, *icon_surface = NULL;
|
||||
MetaWaylandDataSource *drag_source = NULL;
|
||||
MetaSelectionSource *selection_source;
|
||||
GList *mimetypes;
|
||||
|
||||
if (origin_resource)
|
||||
surface = wl_resource_get_user_data (origin_resource);
|
||||
@ -1224,6 +1296,15 @@ data_device_start_drag (struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
mimetypes = copy_string_array_to_list (meta_wayland_data_source_get_mime_types (drag_source));
|
||||
selection_source = meta_selection_source_wayland_new (source_resource,
|
||||
mimetypes,
|
||||
wl_data_source_send_send,
|
||||
wl_data_source_send_cancelled);
|
||||
g_list_free_full (mimetypes, g_free);
|
||||
set_selection_source (data_device, META_SELECTION_DND,
|
||||
selection_source);
|
||||
|
||||
meta_wayland_pointer_set_focus (seat->pointer, NULL);
|
||||
meta_wayland_data_device_start_drag (data_device, client,
|
||||
&drag_grab_interface,
|
||||
@ -1256,6 +1337,7 @@ selection_data_source_destroyed (gpointer data, GObject *object_was_here)
|
||||
}
|
||||
|
||||
wl_signal_emit (&data_device->selection_ownership_signal, NULL);
|
||||
unset_selection_source (data_device, META_SELECTION_CLIPBOARD);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1315,6 +1397,8 @@ meta_wayland_source_drop_performed (MetaWaylandDataSource *source)
|
||||
static void
|
||||
meta_wayland_source_drag_finished (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
|
||||
MetaWaylandDataSourceWayland *source_wayland =
|
||||
META_WAYLAND_DATA_SOURCE_WAYLAND (source);
|
||||
enum wl_data_device_manager_dnd_action action;
|
||||
@ -1328,6 +1412,8 @@ meta_wayland_source_drag_finished (MetaWaylandDataSource *source)
|
||||
if (wl_resource_get_version (source_wayland->resource) >=
|
||||
WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION)
|
||||
wl_data_source_send_dnd_finished (source_wayland->resource);
|
||||
|
||||
unset_selection_source (data_device, META_SELECTION_DND);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1554,7 +1640,7 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
|
||||
guint32 serial)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
struct wl_resource *data_device_resource, *offer;
|
||||
struct wl_resource *data_device_resource;
|
||||
struct wl_client *focus_client;
|
||||
|
||||
if (data_device->selection_data_source &&
|
||||
@ -1579,24 +1665,37 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client);
|
||||
if (data_device_resource)
|
||||
{
|
||||
if (data_device->selection_data_source)
|
||||
{
|
||||
offer = meta_wayland_data_source_send_offer (data_device->selection_data_source, data_device_resource);
|
||||
struct wl_resource *offer;
|
||||
offer = create_and_send_clipboard_offer (data_device, data_device_resource);
|
||||
wl_data_device_send_selection (data_device_resource, offer);
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_data_device_send_selection (data_device_resource, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (source)
|
||||
{
|
||||
MetaWaylandDataSourceWayland *source_wayland =
|
||||
META_WAYLAND_DATA_SOURCE_WAYLAND (source);
|
||||
MetaSelectionSource *selection_source;
|
||||
GList *mimetypes;
|
||||
|
||||
meta_wayland_data_source_set_seat (source, seat);
|
||||
g_object_weak_ref (G_OBJECT (source),
|
||||
selection_data_source_destroyed,
|
||||
data_device);
|
||||
|
||||
mimetypes = copy_string_array_to_list (meta_wayland_data_source_get_mime_types (source));
|
||||
selection_source = meta_selection_source_wayland_new (source_wayland->resource,
|
||||
mimetypes,
|
||||
wl_data_source_send_send,
|
||||
wl_data_source_send_cancelled);
|
||||
g_list_free_full (mimetypes, g_free);
|
||||
|
||||
set_selection_source (data_device, META_SELECTION_CLIPBOARD,
|
||||
selection_source);
|
||||
}
|
||||
else
|
||||
{
|
||||
unset_selection_source (data_device, META_SELECTION_CLIPBOARD);
|
||||
}
|
||||
|
||||
wl_signal_emit (&data_device->selection_ownership_signal, source);
|
||||
@ -1661,6 +1760,7 @@ primary_source_destroyed (gpointer data,
|
||||
}
|
||||
|
||||
wl_signal_emit (&data_device->primary_ownership_signal, NULL);
|
||||
unset_selection_source (data_device, META_SELECTION_PRIMARY);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1669,7 +1769,7 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device,
|
||||
guint32 serial)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
struct wl_resource *data_device_resource, *offer;
|
||||
struct wl_resource *data_device_resource;
|
||||
struct wl_client *focus_client;
|
||||
|
||||
if (META_IS_WAYLAND_DATA_SOURCE_PRIMARY (source))
|
||||
@ -1704,25 +1804,35 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device,
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->primary_resource_list, focus_client);
|
||||
if (data_device_resource)
|
||||
{
|
||||
if (data_device->primary_data_source)
|
||||
{
|
||||
offer = meta_wayland_data_source_send_primary_offer (data_device->primary_data_source,
|
||||
data_device_resource);
|
||||
struct wl_resource *offer;
|
||||
offer = create_and_send_primary_offer (data_device, data_device_resource);
|
||||
gtk_primary_selection_device_send_selection (data_device_resource, offer);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_primary_selection_device_send_selection (data_device_resource, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (source)
|
||||
{
|
||||
MetaSelectionSource *selection_source;
|
||||
GList *mimetypes;
|
||||
|
||||
meta_wayland_data_source_set_seat (source, seat);
|
||||
g_object_weak_ref (G_OBJECT (source),
|
||||
primary_source_destroyed,
|
||||
data_device);
|
||||
|
||||
mimetypes = copy_string_array_to_list (meta_wayland_data_source_get_mime_types (source));
|
||||
selection_source = meta_selection_source_wayland_new (META_WAYLAND_DATA_SOURCE_PRIMARY (source)->resource,
|
||||
mimetypes,
|
||||
gtk_primary_selection_source_send_send,
|
||||
gtk_primary_selection_source_send_cancelled);
|
||||
g_list_free_full (mimetypes, g_free);
|
||||
|
||||
set_selection_source (data_device, META_SELECTION_PRIMARY,
|
||||
selection_source);
|
||||
}
|
||||
else
|
||||
{
|
||||
unset_selection_source (data_device, META_SELECTION_PRIMARY);
|
||||
}
|
||||
|
||||
wl_signal_emit (&data_device->primary_ownership_signal, source);
|
||||
@ -1767,6 +1877,72 @@ create_data_source (struct wl_client *client,
|
||||
meta_wayland_data_source_wayland_new (source_resource);
|
||||
}
|
||||
|
||||
static void
|
||||
owner_changed_cb (MetaSelection *selection,
|
||||
MetaSelectionType selection_type,
|
||||
MetaSelectionSource *new_owner,
|
||||
MetaWaylandDataDevice *data_device)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaWaylandSeat *seat = compositor->seat;
|
||||
struct wl_resource *data_device_resource;
|
||||
struct wl_client *focus_client;
|
||||
|
||||
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
|
||||
if (!focus_client)
|
||||
return;
|
||||
|
||||
if (selection_type == META_SELECTION_PRIMARY)
|
||||
{
|
||||
data_device_resource =
|
||||
wl_resource_find_for_client (&data_device->primary_resource_list,
|
||||
focus_client);
|
||||
if (data_device_resource)
|
||||
{
|
||||
struct wl_resource *offer = NULL;
|
||||
|
||||
if (new_owner)
|
||||
{
|
||||
offer = create_and_send_primary_offer (data_device,
|
||||
data_device_resource);
|
||||
}
|
||||
|
||||
gtk_primary_selection_device_send_selection (data_device_resource,
|
||||
offer);
|
||||
}
|
||||
}
|
||||
else if (selection_type == META_SELECTION_CLIPBOARD)
|
||||
{
|
||||
data_device_resource =
|
||||
wl_resource_find_for_client (&data_device->resource_list, focus_client);
|
||||
|
||||
if (data_device_resource)
|
||||
{
|
||||
struct wl_resource *offer = NULL;
|
||||
|
||||
if (new_owner)
|
||||
{
|
||||
offer = create_and_send_clipboard_offer (data_device,
|
||||
data_device_resource);
|
||||
}
|
||||
|
||||
wl_data_device_send_selection (data_device_resource, offer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_owners_changed_handler_connected (MetaWaylandDataDevice *data_device)
|
||||
{
|
||||
if (data_device->selection_owner_signal_id != 0)
|
||||
return;
|
||||
|
||||
data_device->selection_owner_signal_id =
|
||||
g_signal_connect (meta_display_get_selection (meta_get_display ()),
|
||||
"owner-changed",
|
||||
G_CALLBACK (owner_changed_cb), data_device);
|
||||
}
|
||||
|
||||
static void
|
||||
get_data_device (struct wl_client *client,
|
||||
struct wl_resource *manager_resource,
|
||||
@ -1778,6 +1954,8 @@ get_data_device (struct wl_client *client,
|
||||
cr = wl_resource_create (client, &wl_data_device_interface, wl_resource_get_version (manager_resource), id);
|
||||
wl_resource_set_implementation (cr, &data_device_interface, &seat->data_device, unbind_resource);
|
||||
wl_list_insert (&seat->data_device.resource_list, wl_resource_get_link (cr));
|
||||
|
||||
ensure_owners_changed_handler_connected (&seat->data_device);
|
||||
}
|
||||
|
||||
static const struct wl_data_device_manager_interface manager_interface = {
|
||||
@ -1822,6 +2000,8 @@ primary_device_manager_get_device (struct wl_client *client,
|
||||
wl_resource_set_implementation (cr, &primary_device_interface,
|
||||
&seat->data_device, unbind_resource);
|
||||
wl_list_insert (&seat->data_device.primary_resource_list, wl_resource_get_link (cr));
|
||||
|
||||
ensure_owners_changed_handler_connected (&seat->data_device);
|
||||
}
|
||||
|
||||
static const struct gtk_primary_selection_device_manager_interface primary_manager_interface = {
|
||||
@ -1877,13 +2057,76 @@ meta_wayland_data_device_init (MetaWaylandDataDevice *data_device)
|
||||
wl_signal_init (&data_device->dnd_ownership_signal);
|
||||
}
|
||||
|
||||
static struct wl_resource *
|
||||
create_and_send_clipboard_offer (MetaWaylandDataDevice *data_device,
|
||||
struct wl_resource *target)
|
||||
{
|
||||
MetaWaylandDataOffer *offer;
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
GList *mimetypes, *l;
|
||||
|
||||
mimetypes = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
||||
META_SELECTION_CLIPBOARD);
|
||||
if (!mimetypes)
|
||||
return NULL;
|
||||
|
||||
offer = g_slice_new0 (MetaWaylandDataOffer);
|
||||
offer->resource = wl_resource_create (wl_resource_get_client (target),
|
||||
&wl_data_offer_interface,
|
||||
wl_resource_get_version (target), 0);
|
||||
wl_resource_set_implementation (offer->resource,
|
||||
&data_offer_interface,
|
||||
offer,
|
||||
destroy_data_offer);
|
||||
|
||||
wl_data_device_send_data_offer (target, offer->resource);
|
||||
|
||||
for (l = mimetypes; l; l = l->next)
|
||||
wl_data_offer_send_offer (offer->resource, l->data);
|
||||
|
||||
g_list_free_full (mimetypes, g_free);
|
||||
|
||||
return offer->resource;
|
||||
}
|
||||
|
||||
static struct wl_resource *
|
||||
create_and_send_primary_offer (MetaWaylandDataDevice *data_device,
|
||||
struct wl_resource *target)
|
||||
{
|
||||
MetaWaylandDataOffer *offer;
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
GList *mimetypes, *l;
|
||||
|
||||
mimetypes = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
||||
META_SELECTION_PRIMARY);
|
||||
if (!mimetypes)
|
||||
return NULL;
|
||||
|
||||
offer = g_slice_new0 (MetaWaylandDataOffer);
|
||||
offer->resource = wl_resource_create (wl_resource_get_client (target),
|
||||
>k_primary_selection_offer_interface,
|
||||
wl_resource_get_version (target), 0);
|
||||
wl_resource_set_implementation (offer->resource,
|
||||
&primary_offer_interface,
|
||||
offer,
|
||||
destroy_primary_offer);
|
||||
|
||||
gtk_primary_selection_device_send_data_offer (target, offer->resource);
|
||||
|
||||
for (l = mimetypes; l; l = l->next)
|
||||
gtk_primary_selection_offer_send_offer (offer->resource, l->data);
|
||||
|
||||
g_list_free_full (mimetypes, g_free);
|
||||
|
||||
return offer->resource;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
struct wl_client *focus_client;
|
||||
struct wl_resource *data_device_resource, *offer;
|
||||
MetaWaylandDataSource *source;
|
||||
struct wl_resource *data_device_resource;
|
||||
|
||||
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
|
||||
|
||||
@ -1898,32 +2141,18 @@ meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device)
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client);
|
||||
if (data_device_resource)
|
||||
{
|
||||
source = data_device->selection_data_source;
|
||||
if (source)
|
||||
{
|
||||
offer = meta_wayland_data_source_send_offer (source, data_device_resource);
|
||||
struct wl_resource *offer;
|
||||
offer = create_and_send_clipboard_offer (data_device, data_device_resource);
|
||||
wl_data_device_send_selection (data_device_resource, offer);
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_data_device_send_selection (data_device_resource, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->primary_resource_list, focus_client);
|
||||
if (data_device_resource)
|
||||
{
|
||||
source = data_device->primary_data_source;
|
||||
if (source)
|
||||
{
|
||||
offer = meta_wayland_data_source_send_primary_offer (source, data_device_resource);
|
||||
struct wl_resource *offer;
|
||||
offer = create_and_send_primary_offer (data_device, data_device_resource);
|
||||
gtk_primary_selection_device_send_selection (data_device_resource, offer);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_primary_selection_device_send_selection (data_device_resource, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <wayland-server.h>
|
||||
|
||||
#include "clutter/clutter.h"
|
||||
#include "core/meta-selection-source.h"
|
||||
#include "wayland/meta-wayland-types.h"
|
||||
|
||||
typedef struct _MetaWaylandDragGrab MetaWaylandDragGrab;
|
||||
@ -69,6 +70,10 @@ struct _MetaWaylandDataDevice
|
||||
struct wl_signal selection_ownership_signal;
|
||||
struct wl_signal dnd_ownership_signal;
|
||||
struct wl_signal primary_ownership_signal;
|
||||
|
||||
guint selection_owner_signal_id;
|
||||
|
||||
MetaSelectionSource *owners[META_N_SELECTION_TYPES];
|
||||
};
|
||||
|
||||
void meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor);
|
||||
|
Loading…
Reference in New Issue
Block a user