From a86900091de30715da5f2f3181cb5314358e8e13 Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Wed, 12 Apr 2023 22:38:42 +0200 Subject: [PATCH] wayland: Set compositor when creating MetaWaylandDataSourceXWayland create_and_send_dnd_offer() sets the compositor of the offer to the one from the MetaWaylandDataSource. This then later gets used in display_from_offer() when trying to get the context from the compositor. meta_wayland_data_source_xwayland_new() however was not setting the compositor, so this was causing crashes when dragging things from X11 windows on Wayland. Fixes: 2731f0cda ("wayland: Setup and use ownership chains") Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2723 Part-of: --- src/wayland/meta-wayland-data-source.c | 77 ++++++++++++++++++++++++-- src/wayland/meta-xwayland-dnd.c | 9 ++- 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/src/wayland/meta-wayland-data-source.c b/src/wayland/meta-wayland-data-source.c index 7a781982b..d4d9520d6 100644 --- a/src/wayland/meta-wayland-data-source.c +++ b/src/wayland/meta-wayland-data-source.c @@ -49,6 +49,17 @@ typedef struct _MetaWaylandDataSourcePrivate guint drop_performed : 1; } MetaWaylandDataSourcePrivate; +enum +{ + PROP_0, + + PROP_COMPOSITOR, + + N_PROPS +}; + +static GParamSpec *props[N_PROPS] = { 0 }; + G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandDataSource, meta_wayland_data_source, G_TYPE_OBJECT); @@ -145,6 +156,46 @@ meta_wayland_data_source_finalize (GObject *object) G_OBJECT_CLASS (meta_wayland_data_source_parent_class)->finalize (object); } +static void +meta_wayland_data_source_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaWaylandDataSource *source = META_WAYLAND_DATA_SOURCE (object); + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + switch (prop_id) + { + case PROP_COMPOSITOR: + priv->compositor = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_wayland_data_source_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaWaylandDataSource *source = META_WAYLAND_DATA_SOURCE (object); + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + switch (prop_id) + { + case PROP_COMPOSITOR: + g_value_set_pointer (value, priv->compositor); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + static void meta_wayland_data_source_init (MetaWaylandDataSource *source) { @@ -162,6 +213,8 @@ meta_wayland_data_source_class_init (MetaWaylandDataSourceClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = meta_wayland_data_source_finalize; + object_class->set_property = meta_wayland_data_source_set_property; + object_class->get_property = meta_wayland_data_source_get_property; klass->send = meta_wayland_data_source_real_send; klass->target = meta_wayland_data_source_real_target; @@ -169,8 +222,18 @@ meta_wayland_data_source_class_init (MetaWaylandDataSourceClass *klass) klass->action = meta_wayland_data_source_real_action; klass->drop_performed = meta_wayland_data_source_real_drop_performed; klass->drag_finished = meta_wayland_data_source_real_drag_finished; -} + props[PROP_COMPOSITOR] = + g_param_spec_object ("compositor", + "compositor", + "MetaWaylandCompositor", + META_TYPE_WAYLAND_COMPOSITOR, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPS, props); +} static void data_source_offer (struct wl_client *client, @@ -245,12 +308,14 @@ MetaWaylandDataSource * meta_wayland_data_source_new (MetaWaylandCompositor *compositor, struct wl_resource *resource) { - MetaWaylandDataSource *source = - g_object_new (META_TYPE_WAYLAND_DATA_SOURCE, NULL); - MetaWaylandDataSourcePrivate *priv = - meta_wayland_data_source_get_instance_private (source); + MetaWaylandDataSource *source; + MetaWaylandDataSourcePrivate *priv; + + source = g_object_new (META_TYPE_WAYLAND_DATA_SOURCE, + "compositor", compositor, + NULL); + priv = meta_wayland_data_source_get_instance_private (source); - priv->compositor = compositor; meta_wayland_data_source_set_resource (source, resource); wl_resource_set_implementation (resource, &data_source_interface, source, destroy_data_source); diff --git a/src/wayland/meta-xwayland-dnd.c b/src/wayland/meta-xwayland-dnd.c index dc10da5bb..314880cdb 100644 --- a/src/wayland/meta-xwayland-dnd.c +++ b/src/wayland/meta-xwayland-dnd.c @@ -595,11 +595,14 @@ meta_wayland_data_source_xwayland_class_init (MetaWaylandDataSourceXWaylandClass } static MetaWaylandDataSource * -meta_wayland_data_source_xwayland_new (MetaXWaylandDnd *dnd) +meta_wayland_data_source_xwayland_new (MetaXWaylandDnd *dnd, + MetaWaylandCompositor *compositor) { MetaWaylandDataSourceXWayland *source_xwayland; - source_xwayland = g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_XWAYLAND, NULL); + source_xwayland = g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_XWAYLAND, + "compositor", compositor, + NULL); source_xwayland->dnd = dnd; return META_WAYLAND_DATA_SOURCE (source_xwayland); @@ -1032,7 +1035,7 @@ meta_xwayland_dnd_handle_xfixes_selection_notify (MetaWaylandCompositor *composi if (event->owner != None && event->owner != x11_display->selection.xwindow && focus && meta_xwayland_is_xwayland_surface (focus)) { - dnd->source = meta_wayland_data_source_xwayland_new (dnd); + dnd->source = meta_wayland_data_source_xwayland_new (dnd, compositor); meta_wayland_data_device_set_dnd_source (&compositor->seat->data_device, dnd->source);