From 82d9ef7a55c585559c6643dfbec43ed0940cc5f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 6 Apr 2022 10:05:35 +0200 Subject: [PATCH] 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: --- src/x11/meta-x11-selection-input-stream.c | 25 +++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/x11/meta-x11-selection-input-stream.c b/src/x11/meta-x11-selection-input-stream.c index 9747fa505..fead3685d 100644 --- a/src/x11/meta-x11-selection-input-stream.c +++ b/src/x11/meta-x11-selection-input-stream.c @@ -270,9 +270,14 @@ meta_x11_selection_input_stream_dispose (GObject *object) META_X11_SELECTION_INPUT_STREAM (object); MetaX11SelectionInputStreamPrivate *priv = meta_x11_selection_input_stream_get_instance_private (stream); + MetaX11Display *x11_display; - priv->x11_display->selection.input_streams = - g_list_remove (priv->x11_display->selection.input_streams, stream); + x11_display = priv->x11_display; + 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); } @@ -284,11 +289,20 @@ meta_x11_selection_input_stream_finalize (GObject *object) META_X11_SELECTION_INPUT_STREAM (object); MetaX11SelectionInputStreamPrivate *priv = meta_x11_selection_input_stream_get_instance_private (stream); - Display *xdisplay = priv->x11_display->xdisplay; + MetaX11Display *x11_display; 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); } @@ -522,6 +536,9 @@ meta_x11_selection_input_stream_new_async (MetaX11Display *x11_display, attributes.override_redirect = True; priv->x11_display = x11_display; + g_object_add_weak_pointer (G_OBJECT (x11_display), + (gpointer *) &priv->x11_display); + x11_display->selection.input_streams = g_list_prepend (x11_display->selection.input_streams, stream); priv->xselection = XInternAtom (x11_display->xdisplay, selection, False);