Hi, Answers to your questions:
1) Yes, the GtkInvisible is *not* floating (see the my description earlier in this thread to find out why). Note that any toplevel widget (GtkWindow, GtkDialog) is *not floating* either, for the same reason. 2) Yes, you need to use gtk_widget_destroy in this case, not g_object_unref. (the reason is mentioned earlier in this thread). The floating references in GTK make the whole reference counting a bit messy. The following points make life easier: * Always have a matching g_object_unref for each g_object_ref you have * Always have a g_object_unref for each function that returns new GObject that *doesn't use* floating references (GtkTreeModels, GtkSizeGroups) * When creating new objects that *may be floating* (all GtkWidget based ones, GtkInvisible being one example), don't try to use g_object_unref (if not adding extra reference trough g_object_ref earlier). Pack them to containers and use gtk_widget_destroy when you are done with them. Usually you need to use g_object_ref/unref with widgets only if you are implementing a custom container. Hope this helps, -Markku- Lainaus [EMAIL PROTECTED]: > Hi, Markku, > > Thanks a lot for your help. > > I did some further investigation on this issue. I have two questions on > this issue: > > 1. The object created by gtk_invisible_new() is not "floating". > > Here is a snippet from gtk+-2.12.5/tests/testselection.c > > init_atoms(); > selection_widget = gtk_invisible_new (); > * m = GTK_OBJECT_FLOATING(selection_widget); //*** > dialog = gtk_dialog_new (); > gtk_widget_set_name (dialog, "Test Input"); > > The black line (marked with "**") is added by me. > When I run testselection, "m" is set to 0 instead of 1. Which means the > selection_widget is not "floating". > right or I used a wrong macro? > > 2. How to release an object created by gtk_invisible_new()? > Look at following snippets: > > void InitWidget() { > mWidget = gtk_invisible_new(); > *gtk_object_ref(GTK_OBJECT(mWidget)); //*** > gtk_object_sink(GTK_OBJECT(mWidget)); > gtk_widget_ensure_style(mWidget); > mStyle = gtk_widget_get_style(mWidget); > } > > nsLookAndFeel::~nsLookAndFeel() > { > // gtk_widget_destroy(mWidget); > gtk_widget_unref(mWidget); > } > > If I comment out the black line (marked with "**"), the mWidget > reference count is 1 as expected, > but when unref it in nsLookAndFeel::~nsLookAndFeel, thunderbird will > crash. > It looks like that I can't us gtk_widget_unref() on the object returned > by gkt_invisible_new(). > > So my question is how to "free" an object returned by gtk_invisible_new()? > > Thanks a lot > > Brian > > > Markku Vire wrote: > > Hi, > > > > The reference that is returned by gtk_invisible_new is not owned by the > > caller. If one tries to unref it, it's an immediate memory corruption. > > > > When a toplevel widget is concerned, the things go like the following: > > * New floating GtkWidget is created (not owned by anyone). > > * GTK library takes ownership of the toplevel (calling > > g_object_ref_sink). Floating reference is converted to normal one. > > * Widget pointer is returned (refcount = 1, owner = gtk). > > > > So, in the code you attached gtk_object_ref increases the reference > > count to 2, gtk_object_sink does nothing (since it not floating any > > more). > > > > Later gtk_widget_unref decreases refcount back to 1, but there is still > > one reference left (owned by gtk). Trying to remove it by g_object_unref > > is a bug (as you noticed). The way to ask GTK to release the last > > reference is to call gtk_widget_destroy. > > > > If you are just interested about the GtkStyle object, you could try > > using gtk_rc_get_style_by_paths for example? > > > > Cheers, > > > > -Markku- > > > > On Fri, 2008-01-11 at 16:53 +0800, Brian Lu wrote: > > > >> Thanks a lot for your explanation. But look at following snippet from > >> firefox latest code base: > >> void InitWidget() { > >> mWidget = gtk_invisible_new(); > >> gtk_object_ref(GTK_OBJECT(mWidget)); > >> gtk_object_sink(GTK_OBJECT(mWidget)); > >> gtk_widget_ensure_style(mWidget); > >> mStyle = gtk_widget_get_style(mWidget); > >> } > >> see > >> > http://lxr.mozilla.org/seamonkey/source/widget/src/gtk2/nsLookAndFeel.h#77 > >> and > >> nsLookAndFeel::~nsLookAndFeel() > >> { > >> // gtk_widget_destroy(mWidget); > >> gtk_widget_unref(mWidget); > >> } > >> see > >> > http://lxr.mozilla.org/seamonkey/source/widget/src/gtk2/nsLookAndFeel.cpp#78 > >> > >> I find mWidget is leaked (detected by using libumem.so provided by > solaris). > >> > >> I don't understand why calling gtk_object_ref() to increase mWidget > >> reference count. > >> This causes mWidget's reference count to be 2 and gtk_widget_unref() in > >> deconstructor decreases it to 1. > >> > >> Thanks > >> > >> Brian > >> > >> > >> > >> Markku Vire wrote: > >> > >>> Hi, > >>> > >>> The caller doesn't own the returned reference in case of any gtk_*_new > >>> functions, but the results are floating references (they are removed > >>> once somebody calls gtk_object_sink). This is different from normal > >>> GObjects. So, unreffing the returned value causes practically a double > >>> free. > >>> > >>> gtk_widget_destroy in turn runs dispose, ie. asks widget to drop > >>> references to other widgets. Dropping external references usually > causes > >>> somebody else to drop the last reference to your widget, so it > >>> efectively gets destroyed. In case of toplevels some global window list > >>> is holding the reference. > >>> > >>> Calling gtk_widget_destroy without taking ownership a a widget is > >>> usually a bug that causes a memory leak, but this is not the case here, > >>> since we are talking about a toplevel. > >>> > >>> Cheers, > >>> > >>> -Markku- > >>> > >>> On Wed, 2008-01-09 at 17:39 +0800, Brian Lu wrote: > >>> > >>> > >>>> Hi, experts, > >>>> > >>>> I found following codes will crash in gnome 2.21 environment: > >>>> > >>>> ... > >>>> GtkWidget *foo = gtk_invisible_new(); > >>>> gtk_widget_unref(foo); > >>>> ... > >>>> > >>>> But it works well if gtk_widget_unref() is replaced with > >>>> gtk_widget_destroy(). > >>>> > >>>> Does that mean that we can't use gtk_widget_unref() on such object and > > >>>> we can only > >>>> use gtk_widget_destroy() to release it? > >>>> > >>>> Thanks > >>>> > >>>> Brian > >>>> _______________________________________________ > >>>> gtk-devel-list mailing list > >>>> gtk-devel-list@gnome.org > >>>> http://mail.gnome.org/mailman/listinfo/gtk-devel-list > >>>> > >>>> > >>> > >>> > >> _______________________________________________ > >> gtk-devel-list mailing list > >> gtk-devel-list@gnome.org > >> http://mail.gnome.org/mailman/listinfo/gtk-devel-list > >> > > > > > > _______________________________________________ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list