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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2956>
This commit is contained in:
Sebastian Keller 2023-04-12 22:38:42 +02:00 committed by Marge Bot
parent 1b140e8cb9
commit a86900091d
2 changed files with 77 additions and 9 deletions

View File

@ -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);

View File

@ -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);