Re: Can I use gtk_widget_unref() to releasetthe object created by gtk_invisible_new()?
- From: markku vire iki fi
- To: Brian Lu Sun COM
- Cc: gtk-devel-list gnome org
- Subject: Re: Can I use gtk_widget_unref() to releasetthe object created by gtk_invisible_new()?
- Date: Wed, 30 Jan 2008 10:54:43 +0200
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 Brian Lu Sun COM:
> 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
> >>
> >
> >
>
>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]