[mutter/gnome-42] x11/input-selection-stream: Handle Xwayland going away



commit 48f39beec0875f41859a939096026b0b299f3aa8
Author: Jonas Ådahl <jadahl gmail com>
Date:   Wed Apr 6 10:05:35 2022 +0200

    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>

 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 9747fa505e..fead3685d9 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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]