Index: gobject/pygobject.c
===================================================================
RCS file: /cvs/gnome/gnome-python/pygobject/gobject/pygobject.c,v
retrieving revision 1.64
diff -u -p -u -r1.64 pygobject.c
--- gobject/pygobject.c	15 Nov 2005 22:13:03 -0000	1.64
+++ gobject/pygobject.c	13 Jan 2006 17:07:19 -0000
@@ -511,6 +511,22 @@ pygobject_register_class(PyObject *dict,
     PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
 }
 
+static void
+pyg_toggle_notify (gpointer data, GObject *object, gboolean is_last_ref)
+{
+    PyGObject *self = (PyGObject*) data;
+    PyGILState_STATE state;
+
+    state = pyg_gil_state_ensure();
+
+    if (is_last_ref)
+	Py_DECREF(self);
+    else
+        Py_INCREF(self);
+
+    pyg_gil_state_release(state);
+}
+
 /**
  * pygobject_register_wrapper:
  * @self: the wrapper instance
@@ -521,15 +537,29 @@ pygobject_register_class(PyObject *dict,
  * always be used for this GObject instance.  It will also sink any
  * floating references on the GObject.
  */
-void
-pygobject_register_wrapper(PyObject *self)
+static void
+pygobject_register_wrapper_full(PyGObject *self, gboolean sink)
 {
-    GObject *obj = ((PyGObject *)self)->obj;
+    GObject *obj = self->obj;
 
+    if (sink)
     pygobject_sink(obj);
+
+    g_assert(obj->ref_count >= 1);
+    /* Note that add_toggle_ref will never immediately call back into 
+       pyg_toggle_notify */
+    g_object_add_toggle_ref(obj, pyg_toggle_notify, self);
     Py_INCREF(self);
-    g_object_set_qdata_full(obj, pygobject_wrapper_key, self,
-			    pyg_destroy_notify);
+    
+    g_object_unref(obj);
+    /* save wrapper pointer as a weak ref (pointer) so we can access it later */
+    g_object_set_qdata_full(obj, pygobject_wrapper_key, self, NULL);
+}
+
+void
+pygobject_register_wrapper(PyObject *self)
+{
+    pygobject_register_wrapper_full((PyGObject *)self, TRUE);
 }
 
 /**
@@ -727,17 +757,13 @@ pygobject_new_full(GObject *obj, gboolea
 	self = PyObject_GC_New(PyGObject, tp);
 	if (self == NULL)
 	    return NULL;
-	self->obj = g_object_ref(obj);
-        if (sink)
-            pygobject_sink(self->obj);
-
 	self->inst_dict = NULL;
 	self->weakreflist = NULL;
 	self->closures = NULL;
-	/* save wrapper pointer so we can access it later */
-	Py_INCREF(self);
-	g_object_set_qdata_full(obj, pygobject_wrapper_key, self,
-				pyg_destroy_notify);
+
+	self->obj = obj;
+	g_object_ref(obj);
+	pygobject_register_wrapper_full(self, sink);
 
 	PyObject_GC_Track((PyObject *)self);
     }
@@ -798,7 +824,7 @@ pygobject_dealloc(PyGObject *self)
     PyObject_GC_UnTrack((PyObject *)self);
 
     if (self->obj) {
-	g_object_unref(self->obj);
+	g_object_remove_toggle_ref(self->obj, pyg_toggle_notify, self);
     }
     self->obj = NULL;
 
@@ -874,8 +900,6 @@ pygobject_traverse(PyGObject *self, visi
 	if (ret != 0) return ret;
     }
 
-    if (self->obj && self->obj->ref_count == 1)
-	ret = visit((PyObject *)self, arg);
     if (ret != 0) return ret;
 
     return 0;
Index: tests/test_subtype.py
===================================================================
RCS file: /cvs/gnome/gnome-python/pygobject/tests/test_subtype.py,v
retrieving revision 1.9
diff -u -p -u -r1.9 test_subtype.py
--- tests/test_subtype.py	9 Jan 2006 12:26:46 -0000	1.9
+++ tests/test_subtype.py	13 Jan 2006 17:07:19 -0000
@@ -16,6 +16,22 @@ class TestSubType(unittest.TestCase):
         label = gobject.new(gobject.GObject)
         self.assertEqual(label.__grefcount__, 1)
 
+    def testSimpleDecref(self):
+        class CallInDel:
+            def __init__(self, callback):
+                self.callback = callback
+                
+            def __del__(self):
+                if callable(self.callback):
+                    self.callback()
+        disposed_calls = []
+        def on_dispose():
+            disposed_calls.append(None)
+        gobj = GObject()
+        gobj.set_data('tmp', CallInDel(on_dispose))
+        del gobj
+        assert len(disposed_calls) == 1
+
     def testPythonSubclass(self):
         label = testmodule.PyGObject()
         self.assertEqual(label.__grefcount__, 1)
