Invoke Destroy in Dispose if the Widget IsToplevel and it is not already destroyed
If the Widget is a toplevel then we have not ref'ed the Object, so ref before destroying it, and let the freeing of the ToggleRef undo the ref.
This commit is contained in:
parent
c3364fd338
commit
470ce6cff7
1 changed files with 30 additions and 1 deletions
|
@ -370,6 +370,7 @@ namespace Gtk {
|
||||||
Gtk.Widget widget = o as Gtk.Widget;
|
Gtk.Widget widget = o as Gtk.Widget;
|
||||||
if (widget == null)
|
if (widget == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
widget.OnDestroyed ();
|
widget.OnDestroyed ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,11 +388,28 @@ namespace Gtk {
|
||||||
base.CreateNativeObject (names, vals);
|
base.CreateNativeObject (names, vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
delegate IntPtr d_g_object_ref(IntPtr raw);
|
||||||
|
static d_g_object_ref g_object_ref = FuncLoader.LoadFunction<d_g_object_ref>(FuncLoader.GetProcAddress(GLibrary.Load(Library.GObject), "g_object_ref"));
|
||||||
|
|
||||||
|
private bool destroyed;
|
||||||
protected override void Dispose (bool disposing)
|
protected override void Dispose (bool disposing)
|
||||||
{
|
{
|
||||||
if (Handle == IntPtr.Zero)
|
if (Handle == IntPtr.Zero)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (disposing && !destroyed && IsToplevel)
|
||||||
|
{
|
||||||
|
//If this is a TopLevel widget, then we do not hold a ref, only a toggle ref.
|
||||||
|
//Freeing our toggle ref expects a normal ref to exist, and therefore does not check if the object still exists.
|
||||||
|
//Take a ref here and let our toggle ref unref it.
|
||||||
|
g_object_ref (Handle);
|
||||||
|
gtk_widget_destroy (Handle);
|
||||||
|
destroyed = true;
|
||||||
|
}
|
||||||
|
|
||||||
InternalDestroyed -= NativeDestroyHandler;
|
InternalDestroyed -= NativeDestroyHandler;
|
||||||
|
|
||||||
base.Dispose (disposing);
|
base.Dispose (disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +418,11 @@ namespace Gtk {
|
||||||
return base.Raw;
|
return base.Raw;
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
|
if (Handle == value)
|
||||||
|
return;
|
||||||
|
|
||||||
base.Raw = value;
|
base.Raw = value;
|
||||||
|
|
||||||
if (value != IntPtr.Zero)
|
if (value != IntPtr.Zero)
|
||||||
InternalDestroyed += NativeDestroyHandler;
|
InternalDestroyed += NativeDestroyHandler;
|
||||||
}
|
}
|
||||||
|
@ -409,11 +431,18 @@ namespace Gtk {
|
||||||
delegate void d_gtk_widget_destroy(IntPtr raw);
|
delegate void d_gtk_widget_destroy(IntPtr raw);
|
||||||
static d_gtk_widget_destroy gtk_widget_destroy = FuncLoader.LoadFunction<d_gtk_widget_destroy>(FuncLoader.GetProcAddress(GLibrary.Load(Library.Gtk), "gtk_widget_destroy"));
|
static d_gtk_widget_destroy gtk_widget_destroy = FuncLoader.LoadFunction<d_gtk_widget_destroy>(FuncLoader.GetProcAddress(GLibrary.Load(Library.Gtk), "gtk_widget_destroy"));
|
||||||
|
|
||||||
|
|
||||||
public virtual void Destroy ()
|
public virtual void Destroy ()
|
||||||
{
|
{
|
||||||
if (Handle == IntPtr.Zero)
|
if (Handle == IntPtr.Zero)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (destroyed)
|
||||||
|
return;
|
||||||
|
|
||||||
gtk_widget_destroy (Handle);
|
gtk_widget_destroy (Handle);
|
||||||
|
destroyed = true;
|
||||||
|
|
||||||
InternalDestroyed -= NativeDestroyHandler;
|
InternalDestroyed -= NativeDestroyHandler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue