James, > When doe s the error occur? > 0. When program starts > 1. When shutting down > 2. When creating the text_view the first time > 3. When creating the text_view the Nth time > > I will assume it happens durin shutdown (#1).
Yes you are correct. In the "real" application, the application doesn't exit. It destroys the canvas and re-uses it with new controls. Rather than debug that [monster], I reduced the application to something more manageable that exhibit the same behavior. > Yes, it should be handled like any other widget. The only special thing is > its text_buffer! Consider gtk_text_view_new_with_buffer(), one is created > automatically for when using the gtk_text_view_new() api. I don't think > creating the GtkTextBuffer first would make any difference -- however, that > where you are now. So try creating the GtkTextBuffer first, then use the > ...with_buffer() api to create the view. This may produce a different > result. Interesting. I tried a few different things today and was able to get the application to work as expected without crashing, but I don't like the solution as now it appears I'm leaking memory. Any thoughts on why if g_object_unref is called the application complains about the double free? I modified the code as follows (mainly the button_click_event handler was changed to handle the text buffer and to require clicking the 'Quit' button twice for exiting the app - this was just done for visibility reasons). [code] GtkWidget *main_window, *text_view, *box, *button; GtkTextBuffer* buffer; static void destroy_event(GtkWidget* widget, void* data) { gtk_main_quit(); } static void button_click_event(void) { if (text_view != NULL) { gtk_container_remove(GTK_CONTAINER(box), text_view); text_view = NULL; // leaking memory??? // g_object_unref(G_OBJECT(buffer)); buffer = NULL; } else { gtk_widget_destroy(main_window); main_window = NULL; } } int main(int argc, char* argv[]) { // initialize multi-threading within GLib g_thread_init(NULL); // initialize multi-threading within GDK gdk_threads_init(); // acquire thread lock gdk_threads_enter(); gtk_init(&argc, &argv); // create main window main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); if (main_window == NULL) abort(); g_signal_connect(G_OBJECT(main_window), "destroy", G_CALLBACK(destroy_event), NULL); gtk_widget_show(main_window); box = gtk_vbox_new(FALSE, 5); if (box == NULL) abort(); gtk_widget_show(box); gtk_container_add(GTK_CONTAINER(main_window), box); buffer = gtk_text_buffer_new(NULL); if (buffer == NULL) abort(); text_view = gtk_text_view_new_with_buffer(buffer); if (text_view == NULL) abort(); gtk_widget_show(text_view); gtk_box_pack_start(GTK_BOX(box), text_view, TRUE, TRUE, 5); button = gtk_button_new_with_label("Quit"); if (button == NULL) abort(); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_click_event), NULL); gtk_widget_show(button); gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 5); // run the main loop gtk_main(); // release thread lock gdk_threads_leave(); return 0; } [/code] -- Mark _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list