Re: Problem with references



On Mon, 2008-03-17 at 10:16 +0100, Gabriele Greco wrote:
[snip]
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.

You cannot get rid of a top level window using g_object_unref() because
a reference is owned by GTK+.  It is not that it is "not enough", it is
that it is generally not the way to do it - you cannot generally get rid
of a widget that way, because other containers may own references.  It
is only really for use where you have yourself called g_object_ref() or
g_object_ref_sink() on it for your own purposes.

There is an explanation of this at:
http://library.gnome.org/devel/gtk/stable/GtkObject.html

If you want some light-weight lifetime wrappers for using GTK+ in a
program written in C++, this might give you some ideas, but gtkmm is
also a good choice:
http://efax-gtk.cvs.sourceforge.net/*checkout*/efax-gtk/efax-gtk/src/utils/gobj_handle.h
http://efax-gtk.cvs.sourceforge.net/*checkout*/efax-gtk/efax-gtk/src/utils/window.h
http://efax-gtk.cvs.sourceforge.net/*checkout*/efax-gtk/efax-gtk/src/utils/window.cpp
http://efax-gtk.cvs.sourceforge.net/*checkout*/efax-gtk/efax-gtk/src/utils/widget.h
http://efax-gtk.cvs.sourceforge.net/*checkout*/efax-gtk/efax-gtk/src/utils/widget.cpp

Chris





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