Compare commits
8 Commits
wip/garnac
...
wip/primar
Author | SHA1 | Date | |
---|---|---|---|
![]() |
297d11b323 | ||
![]() |
3f60a2e48a | ||
![]() |
3729e592a6 | ||
![]() |
56beedf9f2 | ||
![]() |
bed82427c6 | ||
![]() |
e097bc8353 | ||
![]() |
4e82a751fb | ||
![]() |
acd50508dc |
@@ -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 \
|
||||
|
@@ -38,11 +38,8 @@
|
||||
*/
|
||||
#define STARTUP_TIMEOUT 15000000
|
||||
|
||||
typedef struct _MetaStartupNotification MetaStartupNotification;
|
||||
typedef struct _MetaStartupNotificationSequence MetaStartupNotificationSequence;
|
||||
typedef struct _MetaStartupNotificationSequenceClass MetaStartupNotificationSequenceClass;
|
||||
typedef struct _MetaStartupNotificationSequenceX11 MetaStartupNotificationSequenceX11;
|
||||
typedef struct _MetaStartupNotificationSequenceX11Class MetaStartupNotificationSequenceX11Class;
|
||||
|
||||
enum {
|
||||
PROP_SN_0,
|
||||
@@ -86,11 +83,18 @@ struct _MetaStartupNotification
|
||||
guint startup_sequence_timeout;
|
||||
};
|
||||
|
||||
struct _MetaStartupNotificationSequence {
|
||||
GObject parent_instance;
|
||||
#define META_TYPE_STARTUP_NOTIFICATION_SEQUENCE \
|
||||
(meta_startup_notification_sequence_get_type ())
|
||||
|
||||
G_DECLARE_DERIVABLE_TYPE (MetaStartupNotificationSequence,
|
||||
meta_startup_notification_sequence,
|
||||
META, STARTUP_NOTIFICATION_SEQUENCE,
|
||||
GObject)
|
||||
|
||||
typedef struct {
|
||||
gchar *id;
|
||||
time_t timestamp;
|
||||
};
|
||||
} MetaStartupNotificationSequencePrivate;
|
||||
|
||||
struct _MetaStartupNotificationSequenceClass {
|
||||
GObjectClass parent_class;
|
||||
@@ -98,22 +102,12 @@ struct _MetaStartupNotificationSequenceClass {
|
||||
void (* complete) (MetaStartupNotificationSequence *sequence);
|
||||
};
|
||||
|
||||
GType meta_startup_notification_get_type (void) G_GNUC_CONST;
|
||||
GType meta_startup_notification_sequence_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#define META_TYPE_STARTUP_NOTIFICATION_SEQUENCE (meta_startup_notification_sequence_get_type ())
|
||||
#define META_STARTUP_NOTIFICATION_SEQUENCE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), META_TYPE_STARTUP_NOTIFICATION_SEQUENCE, MetaStartupNotificationSequence))
|
||||
#define META_STARTUP_NOTIFICATION_SEQUENCE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), META_TYPE_STARTUP_NOTIFICATION_SEQUENCE, MetaStartupNotificationSequenceClass))
|
||||
#define META_IS_STARTUP_NOTIFICATION_SEQUENCE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), META_TYPE_STARTUP_NOTIFICATION_SEQUENCE))
|
||||
#define META_IS_STARTUP_NOTIFICATION_SEQUENCE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), META_TYPE_STARTUP_NOTIFICATION_SEQUENCE))
|
||||
#define META_STARTUP_NOTIFICATION_SEQUENCE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), META_TYPE_STARTUP_NOTIFICATION_SEQUENCE, MetaStartupNotificationSequenceClass))
|
||||
|
||||
G_DEFINE_TYPE (MetaStartupNotification,
|
||||
meta_startup_notification,
|
||||
G_TYPE_OBJECT)
|
||||
G_DEFINE_TYPE (MetaStartupNotificationSequence,
|
||||
meta_startup_notification_sequence,
|
||||
G_TYPE_OBJECT)
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaStartupNotificationSequence,
|
||||
meta_startup_notification_sequence,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
|
||||
@@ -128,20 +122,15 @@ struct _MetaStartupNotificationSequenceX11 {
|
||||
SnStartupSequence *seq;
|
||||
};
|
||||
|
||||
struct _MetaStartupNotificationSequenceX11Class {
|
||||
MetaStartupNotificationSequenceClass parent_class;
|
||||
};
|
||||
|
||||
static GParamSpec *seq_x11_props[N_SEQ_X11_PROPS];
|
||||
|
||||
GType meta_startup_notification_sequence_x11_get_type (void) G_GNUC_CONST;
|
||||
#define META_TYPE_STARTUP_NOTIFICATION_SEQUENCE_X11 \
|
||||
(meta_startup_notification_sequence_x11_get_type ())
|
||||
|
||||
#define META_TYPE_STARTUP_NOTIFICATION_SEQUENCE_X11 (meta_startup_notification_sequence_x11_get_type ())
|
||||
#define META_STARTUP_NOTIFICATION_SEQUENCE_X11(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), META_TYPE_STARTUP_NOTIFICATION_SEQUENCE_X11, MetaStartupNotificationSequenceX11))
|
||||
#define META_STARTUP_NOTIFICATION_SEQUENCE_X11_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), META_TYPE_STARTUP_NOTIFICATION_SEQUENCE_X11, MetaStartupNotificationSequenceX11Class))
|
||||
#define META_IS_STARTUP_NOTIFICATION_SEQUENCE_X11(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), META_TYPE_STARTUP_NOTIFICATION_SEQUENCE_X11))
|
||||
#define META_IS_STARTUP_NOTIFICATION_SEQUENCE_X11_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), META_TYPE_STARTUP_NOTIFICATION_SEQUENCE_X11))
|
||||
#define META_STARTUP_NOTIFICATION_SEQUENCE_X11_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), META_TYPE_STARTUP_NOTIFICATION_SEQUENCE_X11, MetaStartupNotificationSequenceX11Class))
|
||||
G_DECLARE_FINAL_TYPE (MetaStartupNotificationSequenceX11,
|
||||
meta_startup_notification_sequence_x11,
|
||||
META, STARTUP_NOTIFICATION_SEQUENCE_X11,
|
||||
MetaStartupNotificationSequence)
|
||||
|
||||
G_DEFINE_TYPE (MetaStartupNotificationSequenceX11,
|
||||
meta_startup_notification_sequence_x11,
|
||||
@@ -179,9 +168,12 @@ static void
|
||||
meta_startup_notification_sequence_finalize (GObject *object)
|
||||
{
|
||||
MetaStartupNotificationSequence *seq;
|
||||
MetaStartupNotificationSequencePrivate *priv;
|
||||
|
||||
seq = META_STARTUP_NOTIFICATION_SEQUENCE (object);
|
||||
g_free (seq->id);
|
||||
priv = meta_startup_notification_sequence_get_instance_private (seq);
|
||||
g_free (priv->id);
|
||||
|
||||
G_OBJECT_CLASS (meta_startup_notification_sequence_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -192,16 +184,18 @@ meta_startup_notification_sequence_set_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaStartupNotificationSequence *seq;
|
||||
MetaStartupNotificationSequencePrivate *priv;
|
||||
|
||||
seq = META_STARTUP_NOTIFICATION_SEQUENCE (object);
|
||||
priv = meta_startup_notification_sequence_get_instance_private (seq);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SEQ_ID:
|
||||
seq->id = g_value_dup_string (value);
|
||||
priv->id = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_SEQ_TIMESTAMP:
|
||||
seq->timestamp = g_value_get_int64 (value);
|
||||
priv->timestamp = g_value_get_int64 (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
@@ -216,16 +210,18 @@ meta_startup_notification_sequence_get_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaStartupNotificationSequence *seq;
|
||||
MetaStartupNotificationSequencePrivate *priv;
|
||||
|
||||
seq = META_STARTUP_NOTIFICATION_SEQUENCE (object);
|
||||
priv = meta_startup_notification_sequence_get_instance_private (seq);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SEQ_ID:
|
||||
g_value_set_string (value, seq->id);
|
||||
g_value_set_string (value, priv->id);
|
||||
break;
|
||||
case PROP_SEQ_TIMESTAMP:
|
||||
g_value_set_int64 (value, seq->timestamp);
|
||||
g_value_set_int64 (value, priv->timestamp);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
@@ -261,7 +257,25 @@ meta_startup_notification_sequence_class_init (MetaStartupNotificationSequenceCl
|
||||
g_object_class_install_properties (object_class, N_SEQ_PROPS, seq_props);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
meta_startup_notification_sequence_get_id (MetaStartupNotificationSequence *seq)
|
||||
{
|
||||
MetaStartupNotificationSequencePrivate *priv;
|
||||
|
||||
priv = meta_startup_notification_sequence_get_instance_private (seq);
|
||||
return priv->id;
|
||||
}
|
||||
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
static gint64
|
||||
meta_startup_notification_sequence_get_timestamp (MetaStartupNotificationSequence *seq)
|
||||
{
|
||||
MetaStartupNotificationSequencePrivate *priv;
|
||||
|
||||
priv = meta_startup_notification_sequence_get_instance_private (seq);
|
||||
return priv->timestamp;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_startup_notification_sequence_complete (MetaStartupNotificationSequence *seq)
|
||||
{
|
||||
@@ -272,7 +286,9 @@ meta_startup_notification_sequence_complete (MetaStartupNotificationSequence *se
|
||||
if (klass->complete)
|
||||
klass->complete (seq);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
static void
|
||||
meta_startup_notification_sequence_x11_complete (MetaStartupNotificationSequence *seq)
|
||||
{
|
||||
@@ -369,7 +385,7 @@ meta_startup_notification_sequence_x11_class_init (MetaStartupNotificationSequen
|
||||
static MetaStartupNotificationSequence *
|
||||
meta_startup_notification_sequence_x11_new (SnStartupSequence *seq)
|
||||
{
|
||||
return g_object_new (meta_startup_notification_sequence_x11_get_type (),
|
||||
return g_object_new (META_TYPE_STARTUP_NOTIFICATION_SEQUENCE_X11,
|
||||
"id", sn_startup_sequence_get_id (seq),
|
||||
"timestamp", sn_startup_sequence_get_timestamp (seq) * 1000,
|
||||
"seq", seq,
|
||||
@@ -393,13 +409,15 @@ collect_timed_out_foreach (void *element,
|
||||
{
|
||||
MetaStartupNotificationSequence *sequence = element;
|
||||
CollectTimedOutData *ctod = data;
|
||||
gint64 elapsed;
|
||||
gint64 elapsed, timestamp;
|
||||
|
||||
elapsed = ctod->now - sequence->timestamp;
|
||||
timestamp = meta_startup_notification_sequence_get_timestamp (sequence);
|
||||
elapsed = ctod->now - timestamp;
|
||||
|
||||
meta_topic (META_DEBUG_STARTUP,
|
||||
"Sequence used %ld ms vs. %d max: %s\n",
|
||||
elapsed, STARTUP_TIMEOUT, sequence->id);
|
||||
elapsed, STARTUP_TIMEOUT,
|
||||
meta_startup_notification_sequence_get_id (sequence));
|
||||
|
||||
if (elapsed > STARTUP_TIMEOUT)
|
||||
ctod->list = g_slist_prepend (ctod->list, sequence);
|
||||
@@ -424,7 +442,7 @@ startup_sequence_timeout (void *data)
|
||||
|
||||
meta_topic (META_DEBUG_STARTUP,
|
||||
"Timed out sequence %s\n",
|
||||
sequence->id);
|
||||
meta_startup_notification_sequence_get_id (sequence));
|
||||
|
||||
meta_startup_notification_sequence_complete (sequence);
|
||||
}
|
||||
@@ -482,13 +500,15 @@ meta_startup_notification_lookup_sequence (MetaStartupNotification *sn,
|
||||
const gchar *id)
|
||||
{
|
||||
MetaStartupNotificationSequence *seq;
|
||||
const gchar *seq_id;
|
||||
GSList *l;
|
||||
|
||||
for (l = sn->startup_sequences; l; l = l->next)
|
||||
{
|
||||
seq = l->data;
|
||||
seq_id = meta_startup_notification_sequence_get_id (seq);
|
||||
|
||||
if (g_str_equal (seq->id, id))
|
||||
if (g_str_equal (seq_id, id))
|
||||
return l->data;
|
||||
}
|
||||
|
||||
@@ -505,7 +525,18 @@ meta_startup_notification_finalize (GObject *object)
|
||||
{
|
||||
MetaStartupNotification *sn = META_STARTUP_NOTIFICATION (object);
|
||||
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
sn_monitor_context_unref (sn->sn_context);
|
||||
sn_display_unref (sn->sn_display);
|
||||
#endif
|
||||
|
||||
if (sn->startup_sequence_timeout)
|
||||
g_source_remove (sn->startup_sequence_timeout);
|
||||
|
||||
g_slist_foreach (sn->startup_sequences, (GFunc) g_object_unref, NULL);
|
||||
g_slist_free (sn->startup_sequences);
|
||||
sn->startup_sequences = NULL;
|
||||
|
||||
G_OBJECT_CLASS (meta_startup_notification_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -645,9 +676,9 @@ meta_startup_notification_constructed (GObject *object)
|
||||
meta_startup_notification_sn_event,
|
||||
sn,
|
||||
NULL);
|
||||
#endif
|
||||
sn->startup_sequences = NULL;
|
||||
sn->startup_sequence_timeout = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -715,12 +746,13 @@ meta_startup_notification_handle_xevent (MetaStartupNotification *sn,
|
||||
GSList *
|
||||
meta_startup_notification_get_sequences (MetaStartupNotification *sn)
|
||||
{
|
||||
GSList *l, *sequences = NULL;
|
||||
GSList *sequences = NULL;
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
GSList *l;
|
||||
|
||||
/* We return a list of SnStartupSequences here */
|
||||
for (l = sn->startup_sequences; l; l = l->next)
|
||||
{
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
MetaStartupNotificationSequenceX11 *seq_x11;
|
||||
|
||||
if (!META_IS_STARTUP_NOTIFICATION_SEQUENCE_X11 (l->data))
|
||||
@@ -728,8 +760,8 @@ meta_startup_notification_get_sequences (MetaStartupNotification *sn)
|
||||
|
||||
seq_x11 = META_STARTUP_NOTIFICATION_SEQUENCE_X11 (l->data);
|
||||
sequences = g_slist_prepend (sequences, seq_x11->seq);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return sequences;
|
||||
}
|
||||
|
@@ -7388,10 +7388,31 @@ meta_window_set_gtk_dbus_properties (MetaWindow *window,
|
||||
g_object_thaw_notify (G_OBJECT (window));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_transient_for_loop (MetaWindow *window,
|
||||
MetaWindow *parent)
|
||||
{
|
||||
while (parent)
|
||||
{
|
||||
if (parent->transient_for == window)
|
||||
return TRUE;
|
||||
parent = parent->transient_for;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_set_transient_for (MetaWindow *window,
|
||||
MetaWindow *parent)
|
||||
{
|
||||
if (check_transient_for_loop (window, parent))
|
||||
{
|
||||
meta_warning ("Setting %s transient for %s would create a loop.\n",
|
||||
window->desc, parent->desc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (meta_window_appears_focused (window) && window->transient_for != NULL)
|
||||
meta_window_propagate_focus_appearance (window, FALSE);
|
||||
|
||||
|
@@ -51,32 +51,30 @@ void
|
||||
meta_wayland_buffer_unref (MetaWaylandBuffer *buffer)
|
||||
{
|
||||
buffer->ref_count--;
|
||||
|
||||
if (buffer->ref_count == 0)
|
||||
{
|
||||
g_clear_pointer (&buffer->texture, cogl_object_unref);
|
||||
g_warn_if_fail (buffer->use_count == 0);
|
||||
|
||||
if (buffer->accessible)
|
||||
meta_wayland_buffer_release_control (buffer);
|
||||
g_clear_pointer (&buffer->texture, cogl_object_unref);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_buffer_take_control (MetaWaylandBuffer *buffer)
|
||||
meta_wayland_buffer_ref_use_count (MetaWaylandBuffer *buffer)
|
||||
{
|
||||
if (buffer->accessible)
|
||||
meta_fatal ("buffer control taken twice");
|
||||
|
||||
buffer->accessible = TRUE;
|
||||
buffer->use_count++;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_buffer_release_control (MetaWaylandBuffer *buffer)
|
||||
meta_wayland_buffer_unref_use_count (MetaWaylandBuffer *buffer)
|
||||
{
|
||||
if (!buffer->accessible)
|
||||
meta_fatal ("buffer released when not in control");
|
||||
g_return_if_fail (buffer->use_count != 0);
|
||||
|
||||
wl_resource_queue_event (buffer->resource, WL_BUFFER_RELEASE);
|
||||
buffer->accessible = FALSE;
|
||||
buffer->use_count--;
|
||||
|
||||
if (buffer->use_count == 0)
|
||||
wl_resource_queue_event (buffer->resource, WL_BUFFER_RELEASE);
|
||||
}
|
||||
|
||||
MetaWaylandBuffer *
|
||||
@@ -114,8 +112,7 @@ meta_wayland_buffer_ensure_texture (MetaWaylandBuffer *buffer)
|
||||
CoglTexture *texture;
|
||||
struct wl_shm_buffer *shm_buffer;
|
||||
|
||||
if (!buffer->accessible)
|
||||
meta_warning ("attempted to process damage on uncommitted buffer");
|
||||
g_return_val_if_fail (buffer->use_count != 0, NULL);
|
||||
|
||||
if (buffer->texture)
|
||||
goto out;
|
||||
@@ -140,9 +137,6 @@ meta_wayland_buffer_ensure_texture (MetaWaylandBuffer *buffer)
|
||||
|
||||
buffer->texture = texture;
|
||||
|
||||
if (shm_buffer)
|
||||
buffer->copied_data = TRUE;
|
||||
|
||||
out:
|
||||
return buffer->texture;
|
||||
}
|
||||
@@ -153,8 +147,7 @@ meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
|
||||
{
|
||||
struct wl_shm_buffer *shm_buffer;
|
||||
|
||||
if (!buffer->accessible)
|
||||
meta_warning ("attempted to process damage on uncommitted buffer");
|
||||
g_return_if_fail (buffer->use_count != 0);
|
||||
|
||||
shm_buffer = wl_shm_buffer_get (buffer->resource);
|
||||
|
||||
|
@@ -39,16 +39,14 @@ struct _MetaWaylandBuffer
|
||||
|
||||
CoglTexture *texture;
|
||||
uint32_t ref_count;
|
||||
|
||||
uint32_t accessible : 1;
|
||||
uint32_t copied_data : 1;
|
||||
uint32_t use_count;
|
||||
};
|
||||
|
||||
MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource);
|
||||
void meta_wayland_buffer_ref (MetaWaylandBuffer *buffer);
|
||||
void meta_wayland_buffer_unref (MetaWaylandBuffer *buffer);
|
||||
void meta_wayland_buffer_take_control (MetaWaylandBuffer *buffer);
|
||||
void meta_wayland_buffer_release_control (MetaWaylandBuffer *buffer);
|
||||
void meta_wayland_buffer_ref_use_count (MetaWaylandBuffer *buffer);
|
||||
void meta_wayland_buffer_unref_use_count (MetaWaylandBuffer *buffer);
|
||||
CoglTexture * meta_wayland_buffer_ensure_texture (MetaWaylandBuffer *buffer);
|
||||
void meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
|
||||
cairo_region_t *region);
|
||||
|
@@ -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,
|
||||
|
@@ -174,6 +174,25 @@ meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
surface_use_buffer (MetaWaylandSurface *surface)
|
||||
{
|
||||
g_return_if_fail (!surface->using_buffer);
|
||||
|
||||
meta_wayland_buffer_ref_use_count (surface->buffer);
|
||||
surface->using_buffer = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
surface_stop_using_buffer (MetaWaylandSurface *surface)
|
||||
{
|
||||
if (!surface->using_buffer)
|
||||
return;
|
||||
|
||||
meta_wayland_buffer_unref_use_count (surface->buffer);
|
||||
surface->using_buffer = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
surface_set_buffer (MetaWaylandSurface *surface,
|
||||
MetaWaylandBuffer *buffer)
|
||||
@@ -184,6 +203,8 @@ surface_set_buffer (MetaWaylandSurface *surface,
|
||||
if (surface->buffer)
|
||||
{
|
||||
wl_list_remove (&surface->buffer_destroy_listener.link);
|
||||
|
||||
surface_stop_using_buffer (surface);
|
||||
meta_wayland_buffer_unref (surface->buffer);
|
||||
}
|
||||
|
||||
@@ -345,6 +366,12 @@ toplevel_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
|
||||
queue_surface_actor_frame_callbacks (surface, pending);
|
||||
|
||||
/* If there's no new buffer pending, then there's nothing else to
|
||||
* do
|
||||
*/
|
||||
if (!pending->newly_attached)
|
||||
return;
|
||||
|
||||
if (META_IS_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE (surface->role))
|
||||
{
|
||||
/* For wl_shell, it's equivalent to an unmap. Semantics
|
||||
@@ -642,6 +669,8 @@ static void
|
||||
apply_pending_state (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
gboolean release_new_buffer = FALSE;
|
||||
|
||||
if (pending->newly_attached)
|
||||
{
|
||||
if (!surface->buffer && surface->window)
|
||||
@@ -649,11 +678,18 @@ apply_pending_state (MetaWaylandSurface *surface,
|
||||
|
||||
surface_set_buffer (surface, pending->buffer);
|
||||
|
||||
if (pending->buffer)
|
||||
if (pending->buffer && !surface->using_buffer)
|
||||
{
|
||||
meta_wayland_buffer_take_control (pending->buffer);
|
||||
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (pending->buffer->resource);
|
||||
|
||||
surface_use_buffer (surface);
|
||||
CoglTexture *texture = meta_wayland_buffer_ensure_texture (pending->buffer);
|
||||
meta_surface_actor_wayland_set_texture (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor), texture);
|
||||
|
||||
/* Release the buffer as soon as possible, so the client can reuse it
|
||||
*/
|
||||
if (shm_buffer)
|
||||
release_new_buffer = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -663,8 +699,8 @@ apply_pending_state (MetaWaylandSurface *surface,
|
||||
if (!cairo_region_is_empty (pending->damage))
|
||||
surface_process_damage (surface, pending->damage);
|
||||
|
||||
if (pending->buffer && pending->buffer->copied_data)
|
||||
meta_wayland_buffer_release_control (pending->buffer);
|
||||
if (release_new_buffer)
|
||||
surface_stop_using_buffer (surface);
|
||||
|
||||
surface->offset_x += pending->dx;
|
||||
surface->offset_y += pending->dy;
|
||||
|
@@ -152,6 +152,7 @@ struct _MetaWaylandSurface
|
||||
MetaWaylandSurfaceRole *role;
|
||||
MetaWindow *window;
|
||||
MetaWaylandBuffer *buffer;
|
||||
gboolean using_buffer;
|
||||
struct wl_listener buffer_destroy_listener;
|
||||
cairo_region_t *input_region;
|
||||
cairo_region_t *opaque_region;
|
||||
|
@@ -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