Compare commits
	
		
			1 Commits
		
	
	
		
			pwood/fix-
			...
			wip/primar
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					297d11b323 | 
@@ -45,6 +45,8 @@ mutter_built_sources = \
 | 
			
		||||
 | 
			
		||||
if HAVE_WAYLAND
 | 
			
		||||
mutter_built_sources += \
 | 
			
		||||
	primary-selection-unstable-v1-protocol.c			\
 | 
			
		||||
	primary-selection-unstable-v1-server-protocol.h			\
 | 
			
		||||
	pointer-gestures-unstable-v1-protocol.c				\
 | 
			
		||||
	pointer-gestures-unstable-v1-server-protocol.h			\
 | 
			
		||||
	gtk-shell-protocol.c			\
 | 
			
		||||
 
 | 
			
		||||
@@ -31,4 +31,10 @@ G_DECLARE_FINAL_TYPE (MetaWaylandDataSourceWayland,
 | 
			
		||||
                      META, WAYLAND_DATA_SOURCE_WAYLAND,
 | 
			
		||||
                      MetaWaylandDataSource);
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY (meta_wayland_data_source_primary_get_type ())
 | 
			
		||||
G_DECLARE_FINAL_TYPE (MetaWaylandDataSourcePrimary,
 | 
			
		||||
                      meta_wayland_data_source_primary,
 | 
			
		||||
                      META, WAYLAND_DATA_SOURCE_PRIMARY,
 | 
			
		||||
                      MetaWaylandDataSourceWayland);
 | 
			
		||||
 | 
			
		||||
#endif /* META_WAYLAND_DATA_DEVICE_PRIVATE_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,8 @@
 | 
			
		||||
#include "meta-wayland-private.h"
 | 
			
		||||
#include "meta-dnd-actor-private.h"
 | 
			
		||||
 | 
			
		||||
#include "primary-selection-unstable-v1-server-protocol.h"
 | 
			
		||||
 | 
			
		||||
#define ALL_ACTIONS (WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | \
 | 
			
		||||
                     WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | \
 | 
			
		||||
                     WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
 | 
			
		||||
@@ -70,13 +72,22 @@ typedef struct _MetaWaylandDataSourceWayland
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
} MetaWaylandDataSourceWayland;
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaWaylandDataSourcePrimary
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourceWayland parent;
 | 
			
		||||
} MetaWaylandDataSourcePrimary;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandDataSource, meta_wayland_data_source,
 | 
			
		||||
                            G_TYPE_OBJECT);
 | 
			
		||||
G_DEFINE_TYPE (MetaWaylandDataSourceWayland, meta_wayland_data_source_wayland,
 | 
			
		||||
               META_TYPE_WAYLAND_DATA_SOURCE);
 | 
			
		||||
G_DEFINE_TYPE (MetaWaylandDataSourcePrimary, meta_wayland_data_source_primary,
 | 
			
		||||
               META_TYPE_WAYLAND_DATA_SOURCE_WAYLAND);
 | 
			
		||||
 | 
			
		||||
static MetaWaylandDataSource *
 | 
			
		||||
meta_wayland_data_source_wayland_new (struct wl_resource *resource);
 | 
			
		||||
static MetaWaylandDataSource *
 | 
			
		||||
meta_wayland_data_source_primary_new (struct wl_resource *resource);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
drag_grab_data_source_destroyed (gpointer data, GObject *where_the_object_was);
 | 
			
		||||
@@ -160,7 +171,8 @@ static void
 | 
			
		||||
meta_wayland_data_source_target (MetaWaylandDataSource *source,
 | 
			
		||||
                                 const char *mime_type)
 | 
			
		||||
{
 | 
			
		||||
  META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->target (source, mime_type);
 | 
			
		||||
  if (META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->target)
 | 
			
		||||
    META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->target (source, mime_type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -430,6 +442,32 @@ static const struct wl_data_offer_interface data_offer_interface = {
 | 
			
		||||
  data_offer_set_actions,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
primary_offer_receive (struct wl_client *client, struct wl_resource *resource,
 | 
			
		||||
                       const char *mime_type, int32_t fd, uint32_t serial)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
 | 
			
		||||
  MetaWaylandDataSource *source = offer->source;
 | 
			
		||||
  MetaWaylandSeat *seat;
 | 
			
		||||
 | 
			
		||||
  if (!source)
 | 
			
		||||
    {
 | 
			
		||||
      close (fd);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  seat = meta_wayland_data_source_get_seat (source);
 | 
			
		||||
 | 
			
		||||
  if (serial == seat->keyboard.key_serial ||
 | 
			
		||||
      serial == seat->pointer.click_serial)
 | 
			
		||||
    meta_wayland_data_source_send (source, mime_type, fd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct zwp_primary_selection_offer_v1_interface primary_offer_interface = {
 | 
			
		||||
  primary_offer_receive,
 | 
			
		||||
  data_offer_destroy,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_data_source_notify_drop_performed (MetaWaylandDataSource *source)
 | 
			
		||||
{
 | 
			
		||||
@@ -500,6 +538,35 @@ 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),
 | 
			
		||||
                                        &zwp_primary_selection_offer_v1_interface,
 | 
			
		||||
                                        wl_resource_get_version (target), 0);
 | 
			
		||||
  wl_resource_set_implementation (offer->resource,
 | 
			
		||||
                                  &primary_offer_interface,
 | 
			
		||||
                                  offer,
 | 
			
		||||
                                  destroy_data_offer);
 | 
			
		||||
 | 
			
		||||
  zwp_primary_selection_device_v1_send_data_offer (target, offer->resource);
 | 
			
		||||
 | 
			
		||||
  wl_array_for_each (p, &priv->mime_types)
 | 
			
		||||
    zwp_primary_selection_offer_v1_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)
 | 
			
		||||
@@ -561,6 +628,11 @@ static struct wl_data_source_interface data_source_interface = {
 | 
			
		||||
  data_source_set_actions
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct zwp_primary_selection_source_v1_interface primary_source_interface = {
 | 
			
		||||
  data_source_offer,
 | 
			
		||||
  data_source_destroy,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaWaylandDragGrab {
 | 
			
		||||
  MetaWaylandPointerGrab  generic;
 | 
			
		||||
 | 
			
		||||
@@ -1108,6 +1180,43 @@ meta_wayland_data_source_wayland_class_init (MetaWaylandDataSourceWaylandClass *
 | 
			
		||||
  data_source_class->drag_finished = meta_wayland_source_drag_finished;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_data_source_primary_send (MetaWaylandDataSource *source,
 | 
			
		||||
                                       const gchar           *mime_type,
 | 
			
		||||
                                       gint                   fd)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourceWayland *source_wayland;
 | 
			
		||||
 | 
			
		||||
  source_wayland = (MetaWaylandDataSourceWayland *) source;
 | 
			
		||||
  zwp_primary_selection_source_v1_send_send (source_wayland->resource,
 | 
			
		||||
                                             mime_type, fd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_data_source_primary_cancel (MetaWaylandDataSource *source)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourceWayland *source_wayland;
 | 
			
		||||
 | 
			
		||||
  source_wayland = (MetaWaylandDataSourceWayland *) source;
 | 
			
		||||
  zwp_primary_selection_source_v1_send_cancelled (source_wayland->resource);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_data_source_primary_init (MetaWaylandDataSourcePrimary *source_primary)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_data_source_primary_class_init (MetaWaylandDataSourcePrimaryClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourceClass *data_source_class =
 | 
			
		||||
    META_WAYLAND_DATA_SOURCE_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  data_source_class->send = meta_wayland_data_source_primary_send;
 | 
			
		||||
  data_source_class->cancel = meta_wayland_data_source_primary_cancel;
 | 
			
		||||
  data_source_class->target = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_data_source_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
@@ -1299,6 +1408,7 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
 | 
			
		||||
 | 
			
		||||
  if (source)
 | 
			
		||||
    {
 | 
			
		||||
      meta_wayland_data_source_set_seat (source, seat);
 | 
			
		||||
      g_object_weak_ref (G_OBJECT (source),
 | 
			
		||||
                         selection_data_source_destroyed,
 | 
			
		||||
                         data_device);
 | 
			
		||||
@@ -1351,6 +1461,93 @@ static const struct wl_data_device_interface data_device_interface = {
 | 
			
		||||
  data_device_release,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
primary_source_destroyed (gpointer  data,
 | 
			
		||||
                          GObject  *object_was_here)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataDevice *data_device = data;
 | 
			
		||||
  MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
 | 
			
		||||
  struct wl_client *focus_client = NULL;
 | 
			
		||||
 | 
			
		||||
  data_device->primary_data_source = NULL;
 | 
			
		||||
 | 
			
		||||
  focus_client = meta_wayland_keyboard_get_focus_client (&seat->keyboard);
 | 
			
		||||
  if (focus_client)
 | 
			
		||||
    {
 | 
			
		||||
      struct wl_resource *data_device_resource;
 | 
			
		||||
 | 
			
		||||
      data_device_resource = wl_resource_find_for_client (&data_device->primary_resource_list, focus_client);
 | 
			
		||||
      if (data_device_resource)
 | 
			
		||||
        zwp_primary_selection_device_v1_send_selection (data_device_resource, NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                                      MetaWaylandDataSource *source)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
 | 
			
		||||
  struct wl_resource *data_device_resource, *offer;
 | 
			
		||||
  struct wl_client *focus_client;
 | 
			
		||||
 | 
			
		||||
  if (data_device->primary_data_source)
 | 
			
		||||
    {
 | 
			
		||||
      meta_wayland_data_source_cancel (data_device->primary_data_source);
 | 
			
		||||
      g_object_weak_unref (G_OBJECT (data_device->primary_data_source),
 | 
			
		||||
                           primary_source_destroyed,
 | 
			
		||||
                           data_device);
 | 
			
		||||
      data_device->primary_data_source = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  data_device->primary_data_source = source;
 | 
			
		||||
 | 
			
		||||
  focus_client = meta_wayland_keyboard_get_focus_client (&seat->keyboard);
 | 
			
		||||
  if (focus_client)
 | 
			
		||||
    {
 | 
			
		||||
      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);
 | 
			
		||||
              zwp_primary_selection_device_v1_send_selection (data_device_resource, offer);
 | 
			
		||||
            }
 | 
			
		||||
          else
 | 
			
		||||
            {
 | 
			
		||||
              zwp_primary_selection_device_v1_send_selection (data_device_resource, NULL);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (source)
 | 
			
		||||
    {
 | 
			
		||||
      meta_wayland_data_source_set_seat (source, seat);
 | 
			
		||||
      g_object_weak_ref (G_OBJECT (source),
 | 
			
		||||
                         primary_source_destroyed,
 | 
			
		||||
                         data_device);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  wl_signal_emit (&data_device->primary_ownership_signal, source);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
primary_device_set_selection (struct wl_client   *client,
 | 
			
		||||
                              struct wl_resource *resource,
 | 
			
		||||
                              struct wl_resource *source_resource)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource);
 | 
			
		||||
  MetaWaylandDataSource *source;
 | 
			
		||||
 | 
			
		||||
  source = wl_resource_get_user_data (source_resource);
 | 
			
		||||
  meta_wayland_data_device_set_primary (data_device, source);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct zwp_primary_selection_device_v1_interface primary_device_interface = {
 | 
			
		||||
  primary_device_set_selection,
 | 
			
		||||
  data_device_release,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
destroy_data_source (struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
@@ -1389,6 +1586,48 @@ static const struct wl_data_device_manager_interface manager_interface = {
 | 
			
		||||
  get_data_device
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
primary_device_manager_create_source (struct wl_client   *client,
 | 
			
		||||
                                      struct wl_resource *manager_resource,
 | 
			
		||||
                                      guint32             id)
 | 
			
		||||
{
 | 
			
		||||
  struct wl_resource *source_resource;
 | 
			
		||||
 | 
			
		||||
  source_resource =
 | 
			
		||||
    wl_resource_create (client, &zwp_primary_selection_source_v1_interface,
 | 
			
		||||
                        wl_resource_get_version (manager_resource),
 | 
			
		||||
                        id);
 | 
			
		||||
  meta_wayland_data_source_primary_new (source_resource);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
primary_device_manager_get_device (struct wl_client   *client,
 | 
			
		||||
                                   struct wl_resource *manager_resource,
 | 
			
		||||
                                   guint32             id,
 | 
			
		||||
                                   struct wl_resource *seat_resource)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
 | 
			
		||||
  struct wl_resource *cr;
 | 
			
		||||
 | 
			
		||||
  cr = wl_resource_create (client, &zwp_primary_selection_device_v1_interface,
 | 
			
		||||
                           wl_resource_get_version (manager_resource), id);
 | 
			
		||||
  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));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
primary_device_manager_destroy (struct wl_client *client,
 | 
			
		||||
                                struct wl_resource *manager_resource)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct zwp_primary_selection_device_manager_v1_interface primary_manager_interface = {
 | 
			
		||||
  primary_device_manager_create_source,
 | 
			
		||||
  primary_device_manager_get_device,
 | 
			
		||||
  primary_device_manager_destroy
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
bind_manager (struct wl_client *client,
 | 
			
		||||
              void *data, guint32 version, guint32 id)
 | 
			
		||||
@@ -1398,6 +1637,19 @@ bind_manager (struct wl_client *client,
 | 
			
		||||
  wl_resource_set_implementation (resource, &manager_interface, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
bind_primary_manager (struct wl_client *client,
 | 
			
		||||
                      void             *data,
 | 
			
		||||
                      uint32_t          version,
 | 
			
		||||
                      uint32_t          id)
 | 
			
		||||
{
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
 | 
			
		||||
  resource = wl_resource_create (client, &zwp_primary_selection_device_manager_v1_interface,
 | 
			
		||||
                                 version, id);
 | 
			
		||||
  wl_resource_set_implementation (resource, &primary_manager_interface, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor)
 | 
			
		||||
{
 | 
			
		||||
@@ -1406,13 +1658,20 @@ meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor)
 | 
			
		||||
			META_WL_DATA_DEVICE_MANAGER_VERSION,
 | 
			
		||||
			NULL, bind_manager) == NULL)
 | 
			
		||||
    g_error ("Could not create data_device");
 | 
			
		||||
 | 
			
		||||
  if (wl_global_create (compositor->wayland_display,
 | 
			
		||||
			&zwp_primary_selection_device_manager_v1_interface,
 | 
			
		||||
			1, NULL, bind_primary_manager) == NULL)
 | 
			
		||||
    g_error ("Could not create data_device");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_data_device_init (MetaWaylandDataDevice *data_device)
 | 
			
		||||
{
 | 
			
		||||
  wl_list_init (&data_device->resource_list);
 | 
			
		||||
  wl_list_init (&data_device->primary_resource_list);
 | 
			
		||||
  wl_signal_init (&data_device->selection_ownership_signal);
 | 
			
		||||
  wl_signal_init (&data_device->primary_ownership_signal);
 | 
			
		||||
  wl_signal_init (&data_device->dnd_ownership_signal);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1435,17 +1694,32 @@ meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client);
 | 
			
		||||
  if (!data_device_resource)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  source = data_device->selection_data_source;
 | 
			
		||||
  if (source)
 | 
			
		||||
  if (data_device_resource)
 | 
			
		||||
    {
 | 
			
		||||
      offer = meta_wayland_data_source_send_offer (source, data_device_resource);
 | 
			
		||||
      wl_data_device_send_selection (data_device_resource, offer);
 | 
			
		||||
      source = data_device->selection_data_source;
 | 
			
		||||
      if (source)
 | 
			
		||||
        {
 | 
			
		||||
          offer = meta_wayland_data_source_send_offer (source, 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);
 | 
			
		||||
          zwp_primary_selection_device_v1_send_selection (data_device_resource, offer);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          zwp_primary_selection_device_v1_send_selection (data_device_resource, NULL);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    wl_data_device_send_selection (data_device_resource, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
@@ -1486,6 +1760,19 @@ meta_wayland_data_source_wayland_new (struct wl_resource *resource)
 | 
			
		||||
  return META_WAYLAND_DATA_SOURCE (source_wayland);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaWaylandDataSource *
 | 
			
		||||
meta_wayland_data_source_primary_new (struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourceWayland *source_wayland =
 | 
			
		||||
   g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY, NULL);
 | 
			
		||||
 | 
			
		||||
  source_wayland->resource = resource;
 | 
			
		||||
  wl_resource_set_implementation (resource, &primary_source_interface,
 | 
			
		||||
                                  source_wayland, destroy_data_source);
 | 
			
		||||
 | 
			
		||||
  return META_WAYLAND_DATA_SOURCE (source_wayland);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_wayland_data_source_add_mime_type (MetaWaylandDataSource *source,
 | 
			
		||||
                                        const gchar           *mime_type)
 | 
			
		||||
 
 | 
			
		||||
@@ -57,13 +57,16 @@ struct _MetaWaylandDataDevice
 | 
			
		||||
  uint32_t selection_serial;
 | 
			
		||||
  MetaWaylandDataSource *selection_data_source;
 | 
			
		||||
  MetaWaylandDataSource *dnd_data_source;
 | 
			
		||||
  MetaWaylandDataSource *primary_data_source;
 | 
			
		||||
  struct wl_listener selection_data_source_listener;
 | 
			
		||||
  struct wl_list resource_list;
 | 
			
		||||
  struct wl_list primary_resource_list;
 | 
			
		||||
  MetaWaylandDragGrab *current_grab;
 | 
			
		||||
  struct wl_client *focus_client;
 | 
			
		||||
 | 
			
		||||
  struct wl_signal selection_ownership_signal;
 | 
			
		||||
  struct wl_signal dnd_ownership_signal;
 | 
			
		||||
  struct wl_signal primary_ownership_signal;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor);
 | 
			
		||||
@@ -80,6 +83,8 @@ void meta_wayland_data_device_set_dnd_source     (MetaWaylandDataDevice *data_de
 | 
			
		||||
void meta_wayland_data_device_set_selection      (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                                                  MetaWaylandDataSource *source,
 | 
			
		||||
                                                  guint32 serial);
 | 
			
		||||
void meta_wayland_data_device_set_primary        (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                                                  MetaWaylandDataSource *source);
 | 
			
		||||
 | 
			
		||||
gboolean meta_wayland_data_source_add_mime_type  (MetaWaylandDataSource *source,
 | 
			
		||||
                                                  const gchar           *mime_type);
 | 
			
		||||
 
 | 
			
		||||
@@ -400,6 +400,9 @@ meta_wayland_pointer_send_button (MetaWaylandPointer *pointer,
 | 
			
		||||
      time = clutter_event_get_time (event);
 | 
			
		||||
      serial = wl_display_next_serial (display);
 | 
			
		||||
 | 
			
		||||
      if (event->type == CLUTTER_BUTTON_PRESS)
 | 
			
		||||
        pointer->click_serial = serial;
 | 
			
		||||
 | 
			
		||||
      wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
 | 
			
		||||
        {
 | 
			
		||||
          wl_pointer_send_button (resource, serial,
 | 
			
		||||
 
 | 
			
		||||
@@ -91,6 +91,7 @@ struct _MetaWaylandDataSourceXWayland
 | 
			
		||||
 | 
			
		||||
struct _MetaXWaylandSelection {
 | 
			
		||||
  MetaSelectionBridge clipboard;
 | 
			
		||||
  MetaSelectionBridge primary;
 | 
			
		||||
  MetaDndBridge dnd;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -396,6 +397,8 @@ atom_to_selection_bridge (MetaWaylandCompositor *compositor,
 | 
			
		||||
 | 
			
		||||
  if (selection_atom == selection_data->clipboard.selection_atom)
 | 
			
		||||
    return &selection_data->clipboard;
 | 
			
		||||
  else if (selection_atom == selection_data->primary.selection_atom)
 | 
			
		||||
    return &selection_data->primary;
 | 
			
		||||
  else if (selection_atom == selection_data->dnd.selection.selection_atom)
 | 
			
		||||
    return &selection_data->dnd.selection;
 | 
			
		||||
  else
 | 
			
		||||
@@ -530,6 +533,8 @@ data_device_get_active_source_for_atom (MetaWaylandDataDevice *data_device,
 | 
			
		||||
{
 | 
			
		||||
  if (selection_atom == gdk_x11_get_xatom_by_name ("CLIPBOARD"))
 | 
			
		||||
    return data_device->selection_data_source;
 | 
			
		||||
  else if (selection_atom == gdk_x11_get_xatom_by_name ("PRIMARY"))
 | 
			
		||||
    return data_device->primary_data_source;
 | 
			
		||||
  else if (selection_atom == xdnd_atoms[ATOM_DND_SELECTION])
 | 
			
		||||
    return data_device->dnd_data_source;
 | 
			
		||||
  else
 | 
			
		||||
@@ -1058,6 +1063,10 @@ meta_xwayland_selection_get_x11_targets (MetaWaylandCompositor *compositor,
 | 
			
		||||
          meta_wayland_data_device_set_selection (&compositor->seat->data_device, data_source,
 | 
			
		||||
                                                  wl_display_next_serial (compositor->wayland_display));
 | 
			
		||||
        }
 | 
			
		||||
      else if (selection->selection_atom == gdk_x11_get_xatom_by_name ("PRIMARY"))
 | 
			
		||||
        {
 | 
			
		||||
          meta_wayland_data_device_set_primary (&compositor->seat->data_device, data_source);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    g_object_unref (data_source);
 | 
			
		||||
@@ -1529,7 +1538,8 @@ meta_xwayland_selection_handle_xfixes_selection_notify (MetaWaylandCompositor *c
 | 
			
		||||
  if (!selection)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (selection->selection_atom == gdk_x11_get_xatom_by_name ("CLIPBOARD"))
 | 
			
		||||
  if (selection->selection_atom == gdk_x11_get_xatom_by_name ("CLIPBOARD") ||
 | 
			
		||||
      selection->selection_atom == gdk_x11_get_xatom_by_name ("PRIMARY"))
 | 
			
		||||
    {
 | 
			
		||||
      if (event->owner == None)
 | 
			
		||||
        {
 | 
			
		||||
@@ -1712,6 +1722,9 @@ meta_xwayland_init_selection (void)
 | 
			
		||||
  init_selection_bridge (&manager->selection_data->clipboard,
 | 
			
		||||
                         gdk_x11_get_xatom_by_name ("CLIPBOARD"),
 | 
			
		||||
                         &compositor->seat->data_device.selection_ownership_signal);
 | 
			
		||||
  init_selection_bridge (&manager->selection_data->primary,
 | 
			
		||||
                         gdk_x11_get_xatom_by_name ("PRIMARY"),
 | 
			
		||||
                         &compositor->seat->data_device.primary_ownership_signal);
 | 
			
		||||
  init_selection_bridge (&manager->selection_data->dnd.selection,
 | 
			
		||||
                         xdnd_atoms[ATOM_DND_SELECTION],
 | 
			
		||||
                         &compositor->seat->data_device.dnd_ownership_signal);
 | 
			
		||||
@@ -1730,6 +1743,7 @@ meta_xwayland_shutdown_selection (void)
 | 
			
		||||
 | 
			
		||||
  meta_xwayland_shutdown_dnd (manager);
 | 
			
		||||
  shutdown_selection_bridge (&selection->clipboard);
 | 
			
		||||
  shutdown_selection_bridge (&selection->primary);
 | 
			
		||||
  shutdown_selection_bridge (&selection->dnd.selection);
 | 
			
		||||
 | 
			
		||||
  g_slice_free (MetaXWaylandSelection, selection);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user