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

Reply via email to