Fix crash on running old plugins destructor after widget itself was destroyed.
authorAndriy Grytsenko <andrej@rep.kiev.ua>
Sat, 15 Feb 2014 21:27:16 +0000 (23:27 +0200)
committerAndriy Grytsenko <andrej@rep.kiev.ua>
Sat, 15 Feb 2014 21:27:16 +0000 (23:27 +0200)
Removing "taskbar" from panel leads to crash. Adding handler to the widget
"destroy" signal which runs [class]->destructor() solves the issue.

src/plugin.c

index 1cb76f8..74ff6f1 100644 (file)
@@ -486,14 +486,21 @@ static void _old_plugin_destroy(gpointer data)
 {
     Plugin *pl = data;
 
-    /* Run the destructor. */
-    pl->class->destructor(pl);
     plugin_class_unref(pl->class);
 
     /* Free the Plugin structure. */
     g_free(pl);
 }
 
+static void _on_old_widget_destroy(GtkWidget *widget, Plugin *pl)
+{
+    /* Never let run it again. */
+    g_signal_handlers_disconnect_by_func(widget, _on_old_widget_destroy, pl);
+    /* Run the destructor before destroying the top level widget.
+     * This prevents problems with the plugin destroying child widgets. */
+    pl->class->destructor(pl);
+}
+
 //static void on_size_allocate(GtkWidget *widget, GdkRectangle *allocation, Panel *p)
 //{
 //    _queue_panel_calculate_size(p);
@@ -571,6 +578,7 @@ GtkWidget *lxpanel_add_plugin(Panel *p, const char *name, config_setting_t *cfg,
         }
 
         pc->count += 1;
+        g_signal_connect(widget, "destroy", G_CALLBACK(_on_old_widget_destroy), pl);
         config_setting_set_save_hook(pconf, _old_plugin_save_hook, pl);
         lxpanel_plugin_set_data(widget, pl, _old_plugin_destroy);
     }