[gtk/matthiasc/for-master: 1/2] inspector: Fix teardown of the general tab




commit a4ba25f0f8e081ae763096c5b1d5842a072d6695
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Sep 5 22:35:30 2020 -0400

    inspector: Fix teardown of the general tab
    
    We were connecting signal handlers to the display
    and seats here, and never cleaning them up, leading
    to crashes after the inspector is closed. This is
    fairly easy to reproduce under Wayland, where the
    scroll device is only created the first time we
    create a scroll event.

 gtk/inspector/general.c | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)
---
diff --git a/gtk/inspector/general.c b/gtk/inspector/general.c
index 76bd0011e2..ab368e2f8d 100644
--- a/gtk/inspector/general.c
+++ b/gtk/inspector/general.c
@@ -817,6 +817,13 @@ add_seat (GtkInspectorGeneral *gen,
   g_list_free (list);
 }
 
+static void
+disconnect_seat (GtkInspectorGeneral *gen,
+                 GdkSeat             *seat)
+{
+  g_signal_handlers_disconnect_by_func (seat, G_CALLBACK (populate_seats), gen);
+}
+
 static void
 populate_seats (GtkInspectorGeneral *gen)
 {
@@ -835,11 +842,28 @@ populate_seats (GtkInspectorGeneral *gen)
   g_list_free (list);
 }
 
+static void
+seat_added (GdkDisplay          *display,
+            GdkSeat             *seat,
+            GtkInspectorGeneral *gen)
+{
+  populate_seats (gen);
+}
+
+static void
+seat_removed (GdkDisplay          *display,
+              GdkSeat             *seat,
+              GtkInspectorGeneral *gen)
+{
+  disconnect_seat (gen, seat);
+  populate_seats (gen);
+}
+
 static void
 init_device (GtkInspectorGeneral *gen)
 {
-  g_signal_connect_swapped (gen->display, "seat-added", G_CALLBACK (populate_seats), gen);
-  g_signal_connect_swapped (gen->display, "seat-removed", G_CALLBACK (populate_seats), gen);
+  g_signal_connect (gen->display, "seat-added", G_CALLBACK (seat_added), gen);
+  g_signal_connect (gen->display, "seat-removed", G_CALLBACK (seat_removed), gen);
 
   populate_seats (gen);
 }
@@ -911,9 +935,18 @@ static void
 gtk_inspector_general_dispose (GObject *object)
 {
   GtkInspectorGeneral *gen = GTK_INSPECTOR_GENERAL (object);
+  GList *list, *l;
 
   g_clear_pointer (&gen->swin, gtk_widget_unparent);
 
+  g_signal_handlers_disconnect_by_func (gen->display, G_CALLBACK (seat_added), gen);
+  g_signal_handlers_disconnect_by_func (gen->display, G_CALLBACK (seat_removed), gen);
+
+  list = gdk_display_list_seats (gen->display);
+  for (l = list; l; l = l->next)
+    disconnect_seat (gen, GDK_SEAT (l->data));
+  g_list_free (list);
+
   G_OBJECT_CLASS (gtk_inspector_general_parent_class)->dispose (object);
 }
 


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