x11/input-selection-stream: Handle Xwayland going away

Xwayland can disappear at any time, for example during a new_async() or
read_async() call. When we eventually finalize the stream, the X11
display it was created for is gone, thus can't clean up the X11
resources. Handle this by making the MetaX11Display pointer a weak
pointer, and ignore cleaning up if it disappeared. This is fine since
the X11 server it created those resources one is gone already.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2364>
This commit is contained in:
Jonas Ådahl 2022-04-06 10:05:35 +02:00 committed by Marge Bot
parent 6c0a917832
commit 82d9ef7a55

View File

@ -270,9 +270,14 @@ meta_x11_selection_input_stream_dispose (GObject *object)
META_X11_SELECTION_INPUT_STREAM (object); META_X11_SELECTION_INPUT_STREAM (object);
MetaX11SelectionInputStreamPrivate *priv = MetaX11SelectionInputStreamPrivate *priv =
meta_x11_selection_input_stream_get_instance_private (stream); meta_x11_selection_input_stream_get_instance_private (stream);
MetaX11Display *x11_display;
priv->x11_display->selection.input_streams = x11_display = priv->x11_display;
g_list_remove (priv->x11_display->selection.input_streams, stream); if (x11_display)
{
x11_display->selection.input_streams =
g_list_remove (x11_display->selection.input_streams, stream);
}
G_OBJECT_CLASS (meta_x11_selection_input_stream_parent_class)->dispose (object); G_OBJECT_CLASS (meta_x11_selection_input_stream_parent_class)->dispose (object);
} }
@ -284,11 +289,20 @@ meta_x11_selection_input_stream_finalize (GObject *object)
META_X11_SELECTION_INPUT_STREAM (object); META_X11_SELECTION_INPUT_STREAM (object);
MetaX11SelectionInputStreamPrivate *priv = MetaX11SelectionInputStreamPrivate *priv =
meta_x11_selection_input_stream_get_instance_private (stream); meta_x11_selection_input_stream_get_instance_private (stream);
Display *xdisplay = priv->x11_display->xdisplay; MetaX11Display *x11_display;
g_async_queue_unref (priv->chunks); g_async_queue_unref (priv->chunks);
XDestroyWindow (xdisplay, priv->window); x11_display = priv->x11_display;
if (x11_display)
{
Display *xdisplay = meta_x11_display_get_xdisplay (x11_display);
XDestroyWindow (xdisplay, priv->window);
g_object_remove_weak_pointer (G_OBJECT (x11_display),
(gpointer *) &priv->x11_display);
}
G_OBJECT_CLASS (meta_x11_selection_input_stream_parent_class)->finalize (object); G_OBJECT_CLASS (meta_x11_selection_input_stream_parent_class)->finalize (object);
} }
@ -522,6 +536,9 @@ meta_x11_selection_input_stream_new_async (MetaX11Display *x11_display,
attributes.override_redirect = True; attributes.override_redirect = True;
priv->x11_display = x11_display; priv->x11_display = x11_display;
g_object_add_weak_pointer (G_OBJECT (x11_display),
(gpointer *) &priv->x11_display);
x11_display->selection.input_streams = x11_display->selection.input_streams =
g_list_prepend (x11_display->selection.input_streams, stream); g_list_prepend (x11_display->selection.input_streams, stream);
priv->xselection = XInternAtom (x11_display->xdisplay, selection, False); priv->xselection = XInternAtom (x11_display->xdisplay, selection, False);