? gail-zip
? gailnotebook-patch.diff
? patch
? stamp-h1
? docs/reference/libgail-util/gail-libgail-util.interfaces
? docs/reference/libgail-util/gail-libgail-util.prerequisites
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gail/ChangeLog,v
retrieving revision 1.843
diff -u -r1.843 ChangeLog
--- ChangeLog	13 Sep 2006 10:38:54 -0000	1.843
+++ ChangeLog	13 Sep 2006 11:21:30 -0000
@@ -1,5 +1,16 @@
 2006-09-13  Bill Haneman <bill.haneman@sun.com>
 
+	* gail/gailtreeview.c:
+	(garbage_collect_cell_data): Split into old method and
+	new idle wrapper below.  Remove any pending idle handler 
+	via g_source_remove, when garbage_collect_cell_data is called
+	synchronously.
+	(idle_garbage_collect_cell_data): use GDK_THREADS_ENTER and
+	GDK_THREADS_LEAVE.
+	Always return FALSE from the idle handler (since if the job needs
+	re-doing, a separate idle handler will be queued). 
+	Fix based on analysis/suggestions from Damon Chaplin, bug #325759.
+	
 	* gail/gailnotebook.c:
 	(gail_notebook_page_added): New, creates notebook page
 	atk peer on receipt of page-added signal from gtk+
Index: gail/gailtreeview.c
===================================================================
RCS file: /cvs/gnome/gail/gail/gailtreeview.c,v
retrieving revision 1.188
diff -u -r1.188 gailtreeview.c
--- gail/gailtreeview.c	13 Mar 2006 15:08:03 -0000	1.188
+++ gail/gailtreeview.c	13 Sep 2006 11:21:34 -0000
@@ -336,6 +336,7 @@
                                                           GList**                list,
 							 gboolean                live_only);
 static AtkObject *       get_header_from_column         (GtkTreeViewColumn      *tv_col);
+static gboolean          idle_garbage_collect_cell_data (gpointer data);
 static gboolean          garbage_collect_cell_data      (gpointer data);
 
 static GailWidgetClass *parent_class = NULL;
@@ -3489,7 +3490,7 @@
       if (!gailview->garbage_collection_pending) {
 	  gailview->garbage_collection_pending = TRUE;
 	  gailview->idle_garbage_collect_id = 
-	      g_idle_add (garbage_collect_cell_data, gailview);
+	      g_idle_add (idle_garbage_collect_cell_data, gailview);
       }
   }
 }
@@ -3594,6 +3595,33 @@
     }
 }
 
+
+static gboolean
+idle_garbage_collect_cell_data (gpointer data)
+{
+      GailTreeView *tree_view;
+
+      GDK_THREADS_ENTER ();
+      g_assert (GAIL_IS_TREE_VIEW (data));
+      tree_view = (GailTreeView *)data;
+
+      /* this is the idle handler (only one instance allowed), so
+       * we can safely delete it.
+       */
+      tree_view->garbage_collection_pending = FALSE;
+      tree_view->idle_garbage_collect_id = 0;
+
+      tree_view->garbage_collection_pending = garbage_collect_cell_data (data);
+
+      GDK_THREADS_LEAVE ();
+
+      /* N.B.: if for some reason another handler has re-enterantly been queued 
+       * while this handler was being serviced, it has its own gsource, therefore this handler
+       * should always return FALSE.
+       */
+      return FALSE; 
+}
+
 static gboolean
 garbage_collect_cell_data (gpointer data)
 {
@@ -3606,7 +3634,11 @@
       temp_list = g_list_copy (tree_view->cell_data);
 
       tree_view->garbage_collection_pending = FALSE;
-      tree_view->idle_garbage_collect_id = 0;
+      if (tree_view->idle_garbage_collect_id != 0) 
+      {
+	  g_source_remove (tree_view->idle_garbage_collect_id);
+	  tree_view->idle_garbage_collect_id = 0;
+      }
 
       /* Must loop through them all */
       while (temp_list != NULL)
@@ -3624,7 +3656,7 @@
           temp_list = temp_list->next;
       }
       g_list_free (temp_list);
-      
+
       return tree_view->garbage_collection_pending;
 }
 
@@ -4020,7 +4052,7 @@
       if (!cell_info->view->garbage_collection_pending) {
 	  cell_info->view->garbage_collection_pending = TRUE;
 	  cell_info->view->idle_garbage_collect_id =
-	    g_idle_add (garbage_collect_cell_data, cell_info->view);
+	    g_idle_add (idle_garbage_collect_cell_data, cell_info->view);
       }
   }
 }
