[gnome-applets/wip/segeiger/window-picker-in-process: 4/9] windowpicker/task-*.c: Fix segfault during object destruction



commit ce3e87d3d424c37ce72e6a74d8c473f48abe59c4
Author: Sebastian Geiger <sbastig gmx net>
Date:   Sun Jun 7 14:45:01 2015 +0200

    windowpicker/task-*.c: Fix segfault during object destruction
    
    When the object is destroyed the signal handlers
    need to be properly disconnected to avoid that they
    are called after the object has already been destroyed.

 windowpicker/src/task-item.c  |   15 +++++++++++++++
 windowpicker/src/task-list.c  |   30 +++++++++++++++++++++---------
 windowpicker/src/task-title.c |   13 ++++++++++++-
 3 files changed, 48 insertions(+), 10 deletions(-)
---
diff --git a/windowpicker/src/task-item.c b/windowpicker/src/task-item.c
index e8aed97..7a36026 100644
--- a/windowpicker/src/task-item.c
+++ b/windowpicker/src/task-item.c
@@ -719,6 +719,20 @@ static void task_item_setup_atk (TaskItem *item) {
     atk_object_set_role (atk, ATK_ROLE_PUSH_BUTTON);
 }
 
+static void task_item_dispose (GObject *object) {
+    TaskItem *task_item = TASK_ITEM (object);
+
+    g_signal_handlers_disconnect_by_func(task_item->priv->screen, on_screen_active_viewport_changed, 
task_item);
+    g_signal_handlers_disconnect_by_func(task_item->priv->screen, on_screen_active_window_changed, 
task_item);
+    g_signal_handlers_disconnect_by_func(task_item->priv->screen, on_screen_active_workspace_changed, 
task_item);
+    g_signal_handlers_disconnect_by_func(task_item->priv->screen, on_screen_window_closed, task_item);
+    g_signal_handlers_disconnect_by_func(task_item->priv->window, on_window_workspace_changed, task_item);
+    g_signal_handlers_disconnect_by_func(task_item->priv->window, on_window_state_changed, task_item);
+    g_signal_handlers_disconnect_by_func(task_item->priv->window, on_window_icon_changed, task_item);
+
+    G_OBJECT_CLASS (task_item_parent_class)->dispose (object);
+}
+
 static void task_item_finalize (GObject *object) {
     TaskItemPrivate *priv = TASK_ITEM (object)->priv;
     /* remove timer */
@@ -735,6 +749,7 @@ static void task_item_finalize (GObject *object) {
 static void task_item_class_init (TaskItemClass *klass) {
     GObjectClass *obj_class      = G_OBJECT_CLASS (klass);
     GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+    obj_class->dispose = task_item_dispose;
     obj_class->finalize = task_item_finalize;
     widget_class->get_preferred_width = task_item_get_preferred_width;
     widget_class->get_preferred_height = task_item_get_preferred_height;
diff --git a/windowpicker/src/task-list.c b/windowpicker/src/task-list.c
index 81c1408..489b640 100644
--- a/windowpicker/src/task-list.c
+++ b/windowpicker/src/task-list.c
@@ -67,15 +67,6 @@ static void on_window_opened (WnckScreen *screen,
     }
 }
 
-/* GObject stuff */
-static void task_list_finalize (GObject *object) {
-    TaskListPrivate *priv = TASK_LIST (object)->priv;
-    /* Remove the blink timer */
-    if (priv->timer) g_source_remove (priv->timer);
-
-    G_OBJECT_CLASS (task_list_parent_class)->finalize (object);
-}
-
 static void on_task_list_orient_changed(PanelApplet *applet,
                                         guint orient,
                                         GtkBox *box)
@@ -97,10 +88,31 @@ static void on_task_list_orient_changed(PanelApplet *applet,
     gtk_widget_queue_resize(GTK_WIDGET(box));
 }
 
+/* GObject stuff */
+static void task_list_dispose(GObject *object) {
+    g_return_if_fail(TASK_IS_LIST(object));
+    TaskList *task_list = TASK_LIST(object);
+    g_signal_handlers_disconnect_by_func(task_list->priv->screen, on_window_opened, task_list);
+
+    G_OBJECT_CLASS (task_list_parent_class)->dispose (object);
+}
+
+static void task_list_finalize (GObject *object) {
+    g_return_if_fail(TASK_IS_LIST(object));
+    TaskList *task_list = TASK_LIST(object);
+    TaskListPrivate *priv = task_list->priv;
+
+    /* Remove the blink timer */
+    if (priv->timer) g_source_remove (priv->timer);
+
+    G_OBJECT_CLASS (task_list_parent_class)->finalize (object);
+}
+
 static void
 task_list_class_init(TaskListClass *class) {
     GObjectClass *obj_class = G_OBJECT_CLASS (class);
 
+    obj_class->dispose = task_list_dispose;
     obj_class->finalize = task_list_finalize;
 }
 
diff --git a/windowpicker/src/task-title.c b/windowpicker/src/task-title.c
index 242fc01..db96416 100644
--- a/windowpicker/src/task-title.c
+++ b/windowpicker/src/task-title.c
@@ -185,6 +185,7 @@ static void hide_title(TaskTitle *title) {
     gtk_widget_set_tooltip_text (GTK_WIDGET (title), NULL);
     gtk_widget_hide (title->priv->grid);
 }
+
 static void
 on_active_window_changed (WnckScreen *screen,
                           WnckWindow *old_window,
@@ -405,11 +406,20 @@ task_title_setup (TaskTitle *title)
 }
 
 static void
+task_title_dispose (GObject *object) {
+    TaskTitle *title = TASK_TITLE (object);
+
+    g_signal_handlers_disconnect_by_func (title->priv->screen, on_active_window_changed, title);
+    disconnect_window (title);
+
+    G_OBJECT_CLASS (task_title_parent_class)->dispose (object);
+}
+
+static void
 task_title_finalize (GObject *object)
 {
     TaskTitle *title = TASK_TITLE (object);
 
-    disconnect_window (title);
     g_object_unref (title->priv->quit_icon);
 
     G_OBJECT_CLASS (task_title_parent_class)->finalize (object);
@@ -443,6 +453,7 @@ task_title_class_init (TaskTitleClass *klass)
     GObjectClass *obj_class = G_OBJECT_CLASS (klass);
 
     obj_class->constructor = task_title_constructor;
+    obj_class->dispose = task_title_dispose;
     obj_class->finalize = task_title_finalize;
 }
 


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