GNOME Bugzilla – Bug 731126
Gtk::Application destructor never called
Last modified: 2014-06-09 08:23:47 UTC
The destructor of a Gtk::Application is never called. Any of your examples demonstrate this behavior. I realize that the Gtk::Application object (wrapped in a RefPtr) will exist for the lifetime of the application, and you are probably assuming that the garbage collector will take care of cleaning it up. However, that is a flaw. The destructor should be able to take care of things that need to be done when the app is closed. For example releasing hardware that has opened by the app. In general it is bad practice to rely on a garbage collector to clean things up in any case.
I made some tests with the gdb debugger, and set breakpoints at Gtk::Application::~Application() and gtk_application_finalize(). I tested some of the example programs in the Gtkmm tutorial, https://git.gnome.org/browse/gtkmm-documentation/tree/examples book/application/app_and_win_menus Neither the destructor nor the finalize function is called. book/application/command_line_handling book/application/simple Only the finalize function is called. book/box book/progressbar Both the destructor and the finalize function are called. I'll try to find out what's wrong with the book/application examples. Do you know other example programs where the Gtk::Application destructor is not called?
Those are the examples that I observed the problem on, and I haven't tested any others. However, I originally observed it in an application that I develop. It seems to at least occur anytime you derive from the Gtk::Application class.
I want to modify my statements in comment 1. When I tested more carefully I noticed: book/application/app_and_win_menus Neither the destructor nor the finalize function is called, if the program is stopped with the menu item Gtk::Application->Quit. Both the destructor and the finalize function are called, if the program is stopped with the close button in the title bar. book/application/command_line_handling book/application/simple book/box book/progressbar Both the destructor and the finalize function are called. It looks like gdb sometimes misses a breakpoint in the empty Gtk::Application::~Application(). I got more reliable results when I set the breakpoint in Gio::Application::~Application(). The problem with the book/application/app_and_win_menus example is that it uses Gio::Application::quit(). I've pushed commit https://git.gnome.org/browse/gtkmm-documentation/commit/?id=ada1f833c11d89200fe75cea4217f5150b4098c8 which adds the following explanation: // Gio::Application::quit() will make Gio::Application::run() return, // but it's a crude way of ending the program. The window is not removed // from the application. Neither the window's nor the application's // destructors will be called, because there will be remaining reference // counts in both of them. If we want the destructors to be called, we // must remove the window from the application. One way of doing this // is to hide the window. Is this enough of a fix for this bug? The implications of using Gio::Application::quit() are not well documented. A better documentation should start in glib or gtk+. Most of the documentation in glibmm and gtkmm is copied from there. It's not obvious where to add such clarifying documentation. It does not fit in the documentation of g_application_quit(). Glib is not supposed to know anything about windows. Windows belong to gtk+.
I suppose. It seems like a bit of workaround, and not much of a fix, but I guess it will do.
I agree that it's more like a workaround than a real fix. I have updated the documentation of Gtk::Application::add_window() and the run() methods that take a Window& argument. https://git.gnome.org/browse/gtkmm/commit/?id=feedeed8c45cca9c19f18300c84328579aa69c4c I think this is all we can reasonably do. It's not reasonable to add anything concerning windows to Gio::Application:: quit(). How about letting Gtk::Application::run() add a 'shutdown' signal handler? And letting that handler remove all windows that are still connected to the application? There are two problems with such a solution: 1. I think it would count as an API break. 2. The shutdown signal is emitted only in the primary application instance. I close this bug with these documentation fixes. Feel free to reopen it, if you think more can and should be done.
I jumped to conclusions when I tested book/application/app_and_win_menus. Only the application's destructor is affected by remove_window(). To have a dynamically allocated window's destructor called, the window must be explicitly deleted. I've pushed a patch with corrected Gtk::Application documentation. The updated documentation only tells what happens to the application's dtor. https://git.gnome.org/browse/gtkmm/commit/?id=c5a9f7883580af9314a6f450c0ed7e80f788b912