Re: Problem with references



After some headache with my gtk C++ classes I've found  with a small
test program this fact about the gobject references:
Sorry, not sure what you're trying to do.  Are you trying to do
something with gtkmm?  Or are you creating your own bindings?


I'm doing some experimental header only bindings for an application I'm
writing, maybe I'll publish the binding once the app is finished if I find
they provide some REAL advantages over gtkmm, and IF I have the time to
cover at least a good part of the GTK api.

Actually I cover only the widgets I use in this app. I'm not using gtkmm
mostly to avoid extra dependencies.

Anyway let's talk about the problem.

Gtk owns all toplevel windows.  It already does _ref_sink() on
GtkWindows on creation (see gtk_window_init() in gtk/gtkwindow.c).  In
this case, if you want to keep an extra reference to 'w', you'd just
call g_object_ref() on it.


Ok, the problem is that I expected to be able to delete those top level
windows with g_object_unref(), but it seems it's not enough, here is an
example:

int main()
{
    gtk_init(NULL, NULL);

    GtkWidget *w = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    gtk_widget_show(w);

    GtkWidget *d = gtk_message_dialog_new(NULL,
            GTK_DIALOG_MODAL,
            GTK_MESSAGE_INFO,
            GTK_BUTTONS_CLOSE,
            "Hello!");
    gtk_dialog_run(GTK_DIALOG(d));
    fprintf(stderr, "After run!\n");
    g_object_unref(d);
    fprintf(stderr, "After unref\n");

    gtk_main();
}

The message dialog is still opened after the unref, if I want to get rid of
it I have to use gtk_widget_destroy() that is not what I want cause I may
not be the owner of the object.

This should be ok as well, IFF you've previously called g_object_ref()
and thus own a reference to it.  As I said, Gtk owns the initial
(non-floating) reference GtkWindow that you get back with
gtk_window_new().


Adding an additional reference to the dialog don't help me close it with
g_object_unref()...

This more or less works (because non-window GtkObjects are created
floating), but that's usually not what you'd want to do.  Again you'd
probably want to just take a normal reference on the widget and then
unref it when you don't need it anymore.  When you add a widget to a
container, it will take care of ditching the floating reference and
taking a real reference.


This is what I want and it works perfectly except for top level windows :)
With toplevel windows I'm unable to get rid of them  with the same method I
use with the other objects (g_object_unref), I can superclass it to do
gtk_widget_destroy() if I see that the object count is 2 or less (since my
reference is added to the initial one of GTK), but I'd like a cleaner way.

It's strange that if you call twice g_object_unref() the top level window
closes but you also get this kind of error:
(<unknown>:6412): GLib-GObject-WARNING **: instance with invalid (NULL)
class pointer

(<unknown>:6412): GLib-GObject-CRITICAL **: g_signal_handlers_destroy:
assertion `G_TYPE_CHECK_INSTANCE (instance)' failed

Seems like GTK wants to do something more on the dialog after I remove his
last reference!


-- 
Bye,
 Gabry



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