Patch for ephy-node



Hello,

I've attached a small patch for ephy-node. It changes three completely
unrelated things. If required I'll split it up into smaller bits and
submit under bug/wishlist entries.

      * Fixes a (possible? unconfirmed?) bug when the object of a signal
        handler is destroyed after the signal handler is removed from an
        ephy-node. I noticed that the object of a signal handler is not
        g_object_weak_unref'ed when the signal_data is destroyed.
      * Adds a new signal EPHY_NODE_CHANGED which is emitted whenever
        the node itself is changed (similar to EPHY_CHILD_NODE_CHANGED).
      * Adds a function ephy_node_signal_disconnect_object which allows
        you to remove a signal handler from an ephy-node by identifying
        it's type, callback and data elements (rather than using the
        signal_id).

Note that the attached bug fix will weak_unref the objects of a signal
handler in the ephy_node_finalize function instead of the
ephy_node_dispose function. This may be incorrect as I haven't dealt
with the fine details of object destruction in C before.

Regards,
Peter.

Index: ephy-node.c
===================================================================
RCS file: /cvs/gnome/epiphany/lib/ephy-node.c,v
retrieving revision 1.32
diff -u -r1.32 ephy-node.c
--- ephy-node.c	24 Jun 2004 10:03:31 -0000	1.32
+++ ephy-node.c	13 Sep 2004 05:18:11 -0000
@@ -111,6 +111,16 @@
 			data->callback (data->node, data->data);
 		break;
 
+		case EPHY_NODE_CHANGED:
+		{
+			guint property_id;
+
+			property_id = va_arg (valist, guint);
+		
+			data->callback (data->node, property_id, data->data);
+		}
+		break;
+
 		case EPHY_NODE_CHILD_ADDED:
 		{
 			EphyNode *node;
@@ -250,13 +260,12 @@
 signal_object_weak_notify (EphyNodeSignalData *signal_data,
                            GObject *where_the_object_was)
 {
+        signal_data->data = 0;
 	ephy_node_signal_disconnect (signal_data->node, signal_data->id);
 }
 
 static void
-unref_signal_objects (long id,
-	              EphyNodeSignalData *signal_data,
-	              EphyNode *node)
+destroy_signal_data (EphyNodeSignalData *signal_data)
 {
 	if (signal_data->data)
 	{
@@ -264,6 +273,8 @@
 				     (GWeakNotify)signal_object_weak_notify,
 				     signal_data);
 	}
+        
+        g_free (signal_data);
 }
 
 static void
@@ -286,10 +297,6 @@
 		real_remove_child (node, child, FALSE, TRUE);
 	}
 
-	g_hash_table_foreach (node->signals,
-			      (GHFunc) unref_signal_objects,
-			      node);
-
 	_ephy_node_db_remove_id (node->db, node->id);
 }
 
@@ -328,15 +335,13 @@
 
 	node->children = g_ptr_array_new ();
 
-	node->parents = g_hash_table_new_full (int_hash,
-					       int_equal,
-					       NULL,
-					       g_free);
-
-	node->signals = g_hash_table_new_full (int_hash,
-					       int_equal,
-					       NULL,
-					       g_free);
+	node->parents = g_hash_table_new_full
+          (int_hash, int_equal, NULL, g_free);
+
+	node->signals = g_hash_table_new_full
+          (int_hash, int_equal, NULL,
+           (GDestroyNotify)destroy_signal_data);
+
 	node->signal_id = 0;
 
 	_ephy_node_db_add_id (db, reserved_id, node);
@@ -439,6 +444,8 @@
 	g_hash_table_foreach (node->parents,
 			      (GHFunc) child_changed,
 			      &change);
+    
+	ephy_node_emit_signal (node, EPHY_NODE_CHANGED, property_id);
 }
 
 gboolean
@@ -1160,6 +1167,35 @@
 	node->signal_id++;
 
 	return ret;
+}
+
+static gboolean
+match_signal_data (gpointer key, EphyNodeSignalData *signal_data,
+                   EphyNodeSignalData *user_data)
+{
+        return (user_data->data == signal_data->data &&
+                user_data->type == signal_data->type &&
+                user_data->callback == signal_data->callback);
+                
+}
+
+guint
+ephy_node_signal_disconnect_object (EphyNode *node,
+                                    EphyNodeSignalType type,
+                                    EphyNodeCallback callback,
+                                    GObject *object)
+{
+        EphyNodeSignalData user_data;
+        
+	g_return_val_if_fail (node->signals, 0);
+
+        user_data.callback = callback;
+        user_data.type = type;
+        user_data.data = object;
+        
+        return g_hash_table_foreach_remove (node->signals,
+                                            (GHRFunc)match_signal_data,
+                                            &user_data);
 }
 
 void
Index: ephy-node.h
===================================================================
RCS file: /cvs/gnome/epiphany/lib/ephy-node.h,v
retrieving revision 1.17
diff -u -r1.17 ephy-node.h
--- ephy-node.h	24 Jun 2004 10:03:31 -0000	1.17
+++ ephy-node.h	13 Sep 2004 05:18:11 -0000
@@ -38,6 +38,7 @@
 {
 	EPHY_NODE_DESTROY,           /* EphyNode *node */
 	EPHY_NODE_RESTORED,          /* EphyNode *node */
+	EPHY_NODE_CHANGED,           /* EphyNode *node, guint property_id */
 	EPHY_NODE_CHILD_ADDED,       /* EphyNode *node, EphyNode *child */
 	EPHY_NODE_CHILD_CHANGED,     /* EphyNode *node, EphyNode *child, guint property_id */
 	EPHY_NODE_CHILD_REMOVED,     /* EphyNode *node, EphyNode *child, guint old_index */
@@ -64,6 +65,11 @@
 
 /* signals */
 int         ephy_node_signal_connect_object (EphyNode *node,
+					     EphyNodeSignalType type,
+					     EphyNodeCallback callback,
+					     GObject *object);
+
+guint       ephy_node_signal_disconnect_object (EphyNode *node,
 					     EphyNodeSignalType type,
 					     EphyNodeCallback callback,
 					     GObject *object);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]