[gnome-initial-setup/shell/4765: 221/362] display, network: Disconnect handlers for objects surviving page destruction



commit dd94433da5558edaffe40694f3ee03256d401286
Author: Mario Sanchez Prada <mario endlessm com>
Date:   Tue Sep 16 15:49:15 2014 +0100

    display,network: Disconnect handlers for objects surviving page destruction
    
    GisAssistant is owned by GisDriver and as such it will survive
    destructions and re-constructions of the pages from where we connect to
    the 'next-page' signal, resulting in dangling pointers pointing to no
    longer existing pages when certain events happen (e.g. change locale).
    
    [endlessm/eos-shell#3639]

 .../pages/display/gis-display-page.c               |   15 ++++-
 .../pages/keyboard/gis-keyboard-page.c             |   63 +++++++++++++++-----
 2 files changed, 59 insertions(+), 19 deletions(-)
---
diff --git a/gnome-initial-setup/pages/display/gis-display-page.c 
b/gnome-initial-setup/pages/display/gis-display-page.c
index 87644ba..80bcefe 100644
--- a/gnome-initial-setup/pages/display/gis-display-page.c
+++ b/gnome-initial-setup/pages/display/gis-display-page.c
@@ -41,6 +41,7 @@ typedef struct {
   GnomeRROutputInfo *current_output;
 
   guint screen_changed_id;
+  guint next_page_id;
 } GisDisplayPagePrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (GisDisplayPage, gis_display_page, GIS_TYPE_PAGE);
@@ -203,6 +204,13 @@ gis_display_page_dispose (GObject *gobject)
       priv->screen_changed_id = 0;
     }
 
+  if (priv->next_page_id != 0)
+    {
+      g_signal_handler_disconnect (gis_driver_get_assistant (GIS_PAGE (page)->driver),
+                                   priv->next_page_id);
+      priv->next_page_id = 0;
+    }
+
   g_clear_object (&priv->current_config);
   g_clear_object (&priv->screen);
 
@@ -214,7 +222,6 @@ gis_display_page_constructed (GObject *object)
 {
   GisDisplayPage *page = GIS_DISPLAY_PAGE (object);
   GisDisplayPagePrivate *priv = gis_display_page_get_instance_private (page);
-  GisAssistant *assistant;
   GtkWidget *widget;
   GError *error = NULL;
   gboolean visible = FALSE;
@@ -251,8 +258,10 @@ gis_display_page_constructed (GObject *object)
                                                       G_CALLBACK (read_screen_config),
                                                       page);
 
-  assistant = gis_driver_get_assistant (GIS_PAGE (page)->driver);
-  g_signal_connect (assistant, "next-page", G_CALLBACK (next_page_cb), page);
+  priv->next_page_id = g_signal_connect (gis_driver_get_assistant (GIS_PAGE (page)->driver),
+                                         "next-page",
+                                         G_CALLBACK (next_page_cb),
+                                         page);
 
   widget = WID ("overscan_on");
   g_signal_connect (widget, "toggled",
diff --git a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c 
b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c
index 62c1f67..154c31d 100644
--- a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c
+++ b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c
@@ -82,6 +82,8 @@ struct _GisKeyboardPagePrivate {
         GHashTable *ibus_engines;
         GCancellable *ibus_cancellable;
 #endif
+
+        guint next_page_id;
 };
 typedef struct _GisKeyboardPagePrivate GisKeyboardPagePrivate;
 
@@ -91,25 +93,51 @@ typedef struct _GisKeyboardPagePrivate GisKeyboardPagePrivate;
 G_DEFINE_TYPE_WITH_PRIVATE (GisKeyboardPage, gis_keyboard_page, GIS_TYPE_PAGE);
 
 static void
+gis_keyboard_page_dispose (GObject *gobject)
+{
+  GisKeyboardPage *page = GIS_KEYBOARD_PAGE (gobject);
+  GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (page);
+
+  if (priv->cancellable)
+    {
+      g_cancellable_cancel (priv->cancellable);
+      g_clear_object (&priv->cancellable);
+    }
+
+  if (priv->input_settings)
+    {
+      g_signal_handlers_disconnect_by_data (priv->input_settings, page);
+      g_clear_object (&priv->input_settings);
+    }
+
+  if (priv->next_page_id != 0)
+    {
+      g_signal_handler_disconnect (gis_driver_get_assistant (GIS_PAGE (page)->driver),
+                                   priv->next_page_id);
+      priv->next_page_id = 0;
+    }
+
+  g_clear_object (&priv->permission);
+  g_clear_object (&priv->localed);
+  g_clear_object (&priv->xkb_info);
+
+#ifdef HAVE_IBUS
+  g_clear_object (&priv->ibus);
+  if (priv->ibus_cancellable)
+    g_cancellable_cancel (priv->ibus_cancellable);
+  g_clear_object (&priv->ibus_cancellable);
+#endif
+
+  G_OBJECT_CLASS (gis_keyboard_page_parent_class)->dispose (gobject);
+}
+
+static void
 gis_keyboard_page_finalize (GObject *object)
 {
        GisKeyboardPage *self = GIS_KEYBOARD_PAGE (object);
         GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
 
-        g_cancellable_cancel (priv->cancellable);
-        g_clear_object (&priv->cancellable);
-
-        g_signal_handlers_disconnect_by_data (priv->input_settings, self);
-        g_clear_object (&priv->input_settings);
-
-        g_clear_object (&priv->permission);
-        g_clear_object (&priv->localed);
-        g_clear_object (&priv->xkb_info);
 #ifdef HAVE_IBUS
-        g_clear_object (&priv->ibus);
-        if (priv->ibus_cancellable)
-                g_cancellable_cancel (priv->ibus_cancellable);
-        g_clear_object (&priv->ibus_cancellable);
         g_clear_pointer (&priv->ibus_engines, g_hash_table_destroy);
         g_clear_pointer (&priv->selected_input_sorted, g_list_free);
 #endif
@@ -135,7 +163,6 @@ gis_keyboard_page_constructed (GObject *object)
 {
         GisKeyboardPage *self = GIS_KEYBOARD_PAGE (object);
         GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
-        GisAssistant *assistant = gis_driver_get_assistant (GIS_PAGE (self)->driver);
 
         G_OBJECT_CLASS (gis_keyboard_page_parent_class)->constructed (object);
 
@@ -159,7 +186,10 @@ gis_keyboard_page_constructed (GObject *object)
         if (gis_driver_get_mode (GIS_PAGE (self)->driver) == GIS_DRIVER_MODE_NEW_USER)
                 priv->permission = polkit_permission_new_sync ("org.freedesktop.locale1.set-keyboard", NULL, 
NULL, NULL);
 
-        g_signal_connect (assistant, "next-page", G_CALLBACK (next_page_cb), self);
+        priv->next_page_id = g_signal_connect (gis_driver_get_assistant (GIS_PAGE (self)->driver),
+                                               "next-page",
+                                               G_CALLBACK (next_page_cb),
+                                               self);
 
         gis_page_set_complete (GIS_PAGE (self), TRUE);
         gtk_widget_show (GTK_WIDGET (self));
@@ -181,7 +211,8 @@ gis_keyboard_page_class_init (GisKeyboardPageClass * klass)
         page_class->locale_changed = gis_keyboard_page_locale_changed;
 
         object_class->constructed = gis_keyboard_page_constructed;
-       object_class->finalize = gis_keyboard_page_finalize;
+        object_class->dispose = gis_keyboard_page_dispose;
+        object_class->finalize = gis_keyboard_page_finalize;
 }
 
 static void


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