Skip to content

Instantly share code, notes, and snippets.

@mhutch
Created March 30, 2012 17:27
Show Gist options
  • Save mhutch/2253141 to your computer and use it in GitHub Desktop.
Save mhutch/2253141 to your computer and use it in GitHub Desktop.
Possible fix for Gtk.Container resurrection bug
--- /c/Users/Michael/Desktop/Container.custom.txt Fri Mar 30 13:16:00 2012
+++ /c/Users/Michael/Desktop/Container.custom.txt-mod Fri Mar 30 13:26:24 2012
@@ -124,6 +124,7 @@
}
}
+//FIXME: fix this too
static void ForallOld_cb (IntPtr container, bool include_internals, IntPtr cb, IntPtr data)
{
try {
@@ -152,9 +153,24 @@
static void Forall_cb (IntPtr container, bool include_internals, IntPtr cb, IntPtr data)
{
try {
- Container obj = GLib.Object.GetObject (container, false) as Container;
- CallbackInvoker invoker = new CallbackInvoker (cb, data);
- obj.ForAll (include_internals, new Gtk.Callback (invoker.Invoke));
+ //FIXME: Objects hastable isn't accessible. Might be better as:
+ // Container obj = (Container) GLib.Objects.TryGetObject (container);
+
+ GLib.ToggleRef r = (GLib.ToggleRef) GLib.Object.Objects[container];
+
+ // gtk_container_destroy calls forall to destroy the children. This circumvents
+ // GTK#'s special handling of destroy calls, and causes the managed wrapper to
+ // be recreated. Since it doesn't have any of the managed state, this is
+ // pointless. It also causes an endless resurrection cycle. We work around this
+ // by ignoring forall callbacks when the managed peer has been collected.
+ if (r == null) {
+ //still call base, it might want to do cleanup
+ gtksharp_container_base_forall (container, include_internals, cb, data);
+ } else {
+ Container obj = (Container) r.Target;
+ CallbackInvoker invoker = new CallbackInvoker (cb, data);
+ obj.ForAll (include_internals, new Gtk.Callback (invoker.Invoke));
+ }
} catch (Exception e) {
GLib.ExceptionManager.RaiseUnhandledException (e, false);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment