[g-a-devel]Changes for at-poke



The attached changes for at-poke do the following:

1) Close the poke window for an application when the application terminates (bug 
 93213).
2) Terminate at-poke application when its main window is closed, whether or not 
poke window is open or poked application is running.
3) Fix leaks so that at-poke does not report leaks of accessibles as it 
terminates.

Comments requested.

Padraig
? config.h.in
? icons/Makefile
? icons/Makefile.in
? src/child-listener.c.NEW
cvs server: Diffing .
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/at-poke/ChangeLog,v
retrieving revision 1.34
diff -u -p -r1.34 ChangeLog
--- ChangeLog	13 Sep 2002 07:09:01 -0000	1.34
+++ ChangeLog	17 Sep 2002 12:27:48 -0000
@@ -1,3 +1,56 @@
+2002-09-17  Padraig O'Briain   <padraig obriain sun com>
+
+	* accessible-tree-model.c
+	(model_node_destroy): Remove call to Accessible_unref() as it is
+	called in mnode_destroy().
+	(model_node_sync_children): Add call to Accessible_unref() to
+	correspond to the call to Accessible_ref() made by call to 
+	Accessible_getChildAtIndex() when the accedssible was added to the list.
+	(accessible_tree_model_unref_node): Add call to mnode_destroy() to
+	fix leak.
+	(accessible_tree_model_dispose): Call model_node_destroy() on root
+	node to avoid leaks.
+
+	* child-listener.[ch]
+	(child_listener_global_event): This function is the event handler for 
+	children-changed event. If it is for the desktop check whether it is a
+	remove and if so, emit a "root_died" signal and remove the application
+	from the list.
+	(child_listener_add_root): Add index argument so that the 
+	ChildListener maintains the list of applications in the correct order.
+
+	* main.c
+	Add GtkTreeRowReference of selected application to AppWindow structure.
+	(app_list_selection_changed): When selection changes get row
+	reference of new selection.
+	(validate_up_down_linkage): Call Accessible_unref() on return from
+	Accessible_queryInterface() and Accessible_getChildAt_index() to avoid
+	leaking accessible objects.
+	(get_index): New function which calculates index corresponding to a 
+	GtkTreeRowReference.
+	(app_list_row_reference): Pass index argument to poke().
+	(applisation_clicked): Pass index argument to poke().
+	(list_store_clear): New function which calls Accessible_unref() for
+	Accessible objects in the list store and calls gtk_list_store_clear().
+	(populate-app_list): Call list_store_clear() instead of 
+	gtk_list_store_clear().
+	(window_destroyed): New function which is defined as signal handler for
+	destroy signal on window for application.
+	(create_app_list): Free data structures on exit and 
+	call gtk_widget_destroy() for window, if it still exists.
+
+	* poke.c
+	Add poker_died variable to Poker structure. It is used to determine
+	whether the poke window or the main window was closed.
+	(root_died_cb): Set poker_died to TRUE.
+	(window_destroyed): New function which is defined as signal handler for
+	destroy signal on the poke window.
+	(poke): Add index argument to poke(). Use index argument in call to
+	child_listener_add_root().
+	Call gtk_widget_destroy() for window, if it still exists.
+	Call gtk_main_quit() if poker_died is not set so poke can close
+	if main window is closed.
+
 2002-09-13  Padraig O'Briain   <padraig obriain sun com>
 
 	* src/poke.c 
cvs server: Diffing glade
cvs server: Diffing icons
cvs server: Diffing src
Index: src/accessible-tree-model.c
===================================================================
RCS file: /cvs/gnome/at-poke/src/accessible-tree-model.c,v
retrieving revision 1.19
diff -u -p -r1.19 accessible-tree-model.c
--- src/accessible-tree-model.c	30 Aug 2002 09:57:40 -0000	1.19
+++ src/accessible-tree-model.c	17 Sep 2002 12:27:48 -0000
@@ -144,7 +144,6 @@ model_node_destroy (GtkTreeModel *model,
 
 	make_iter (model, node, &iter);
 	path = gtk_tree_model_get_path (model, &iter);
- 	Accessible_unref (MODEL_NODE (node)->accessible);
 
 	mnode_destroy (ACCESSIBLE_TREE_MODEL (model), node->data);
 	g_node_destroy (node);
@@ -227,6 +226,7 @@ model_node_sync_children (GtkTreeModel *
 			GNode *child;
 
 			child = model_node_new (model, l->data);
+			Accessible_unref (l->data);
 
 			g_node_insert_before (node, lnode, child);
 			model_node_inserted (tree_model, child);
@@ -528,8 +528,9 @@ accessible_tree_model_unref_node (GtkTre
 		return;
 
 	mnode->ref--;
-	if (mnode->ref == 0)
-		/* FIXME: leak here ? */ ;
+	if (mnode->ref == 0) {
+		mnode_destroy (ACCESSIBLE_TREE_MODEL (tree_model), mnode);
+	}
 }
 
 gboolean
@@ -614,6 +615,8 @@ accessible_tree_model_dispose (GObject *
 	AccessibleTreeModel *model;
 
 	model = ACCESSIBLE_TREE_MODEL (object);
+	if (model->root)
+		model_node_destroy (GTK_TREE_MODEL (model), model->root);
 
 	if (model->event_listener != NULL) {
 		SPI_deregisterGlobalEventListenerAll (
Index: src/child-listener.c
===================================================================
RCS file: /cvs/gnome/at-poke/src/child-listener.c,v
retrieving revision 1.3
diff -u -p -r1.3 child-listener.c
--- src/child-listener.c	21 Mar 2002 21:46:59 -0000	1.3
+++ src/child-listener.c	17 Sep 2002 12:27:48 -0000
@@ -35,28 +35,23 @@ child_listener_global_event (const Acces
 
 	if (event->source == cl->desktop) {
 		GSList *l;
-		GSList *copy = NULL;
+		int i;
+		gboolean is_remove;
 
+		is_remove = (g_strstr_len (event->type, -1,  "remove") != NULL);
 		g_signal_emit (
 			cl, signals [APP_LIST_CHANGED], 0);
 
-		for (l = cl->roots; l; l = l->next) {
-			copy = g_slist_prepend (copy, l->data);
-			Accessible_ref (l->data);
+		i = 0;
+		if (is_remove) {
+			for (l = cl->roots; l; l = l->next) {
+				if (i == event->detail1) {
+					g_signal_emit (cl, signals [ROOT_DIED], 0, l->data);
+					Accessible_unref (l->data);
+					g_slist_remove_link (cl->roots, l);
+				}
+			}
 		}
-
-		for (l = copy; l; l = l->next) {
-			char *txt;
-
-			if (!(txt = Accessible_getName (l->data)))
-				g_signal_emit (cl, signals [ROOT_DIED], 0, l->data);
-			else
-				SPI_freeString (txt);
-		}
-
-		for (l = cl->roots; l; l = l->next)
-			Accessible_unref (l->data);
-		g_slist_free (copy);
 	} else
 		g_signal_emit (cl, signals [CHILDREN_CHANGED], 0, event->source);
 }
@@ -144,9 +139,9 @@ child_listener_get (void)
 }
 
 void
-child_listener_add_root (ChildListener *listener, Accessible *root)
+child_listener_add_root (ChildListener *listener, Accessible *root, int index)
 {
-	listener->roots = g_slist_prepend (listener->roots, root);
+	listener->roots = g_slist_insert (listener->roots, root, index);
 }
 
 void
Index: src/child-listener.h
===================================================================
RCS file: /cvs/gnome/at-poke/src/child-listener.h,v
retrieving revision 1.3
diff -u -p -r1.3 child-listener.h
--- src/child-listener.h	21 Mar 2002 21:46:59 -0000	1.3
+++ src/child-listener.h	17 Sep 2002 12:27:48 -0000
@@ -34,7 +34,8 @@ typedef struct {
 
 ChildListener *child_listener_get         (void);
 void           child_listener_add_root    (ChildListener *listener,
-					   Accessible    *root);
+					   Accessible    *root,
+					   int		  index);
 void           child_listener_remove_root (ChildListener *listener,
 					   Accessible    *root);
 
Index: src/main.c
===================================================================
RCS file: /cvs/gnome/at-poke/src/main.c,v
retrieving revision 1.13
diff -u -p -r1.13 main.c
--- src/main.c	12 Sep 2002 08:52:13 -0000	1.13
+++ src/main.c	17 Sep 2002 12:27:48 -0000
@@ -26,7 +26,7 @@
 #include "graphics.h"
 #include "child-listener.h"
 
-extern void poke (Accessible *accessible);
+extern void poke (Accessible *accessible, int index);
 
 #define APP_COL_NAME   0
 #define APP_COL_DESCR  1
@@ -46,6 +46,7 @@ typedef struct {
 	GtkLabel     *app_id;
 
 	Accessible   *selected;
+	GtkTreeRowReference *row_reference;
 } AppWindow;
 
 static void
@@ -85,16 +86,18 @@ app_list_selection_changed (GtkTreeSelec
 	GtkTreeIter iter;
 	Accessible *accessible;
 	GtkTreeModel *model;
+	GtkTreePath *path;
 	
 	if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
 		return;
 	}
 
-	gtk_tree_model_get (model, &iter,
-			    APP_COL_HANDLE, &accessible,
-			    -1);
+	gtk_tree_model_get (model, &iter, APP_COL_HANDLE, &accessible, -1);
 	update_app_display (app_window, accessible);
-
+	path = gtk_tree_model_get_path (model, &iter);
+	if (app_window->row_reference)
+		gtk_tree_row_reference_free (app_window->row_reference);
+	app_window->row_reference = gtk_tree_row_reference_new (model, path);
 	app_window->selected = accessible;
 }
 
@@ -107,6 +110,7 @@ validate_up_down_linkage (Accessible *ac
 	aa = Accessible_queryInterface (accessible, "IDL:Accessibility/Accessible:1.0");
 
 	g_assert (aa == accessible);
+	Accessible_unref (aa);
 
 	child = Accessible_getChildAtIndex (accessible, 0);
 	if (!child)
@@ -115,8 +119,22 @@ validate_up_down_linkage (Accessible *ac
 	parent = Accessible_getParent (child);
 
 	g_assert (parent == accessible);
+	Accessible_unref (child);
+}
+
+static int
+get_index (GtkTreeRowReference *ref)
+{
+	GtkTreePath *path;
+	int index;
+
+	path = gtk_tree_row_reference_get_path (ref);
+	index = gtk_tree_path_get_indices (path) [0];
+	gtk_tree_path_free (path);
+	return index;
 }
 
+
 static void
 app_list_row_activated (GtkTreeView       *tree_view,
 			GtkTreePath       *path,
@@ -124,7 +142,7 @@ app_list_row_activated (GtkTreeView     
 			AppWindow         *app_window)
 {
 	validate_up_down_linkage (app_window->selected);
-	poke (app_window->selected);
+	poke (app_window->selected, get_index (app_window->row_reference));
 }
 
 static void
@@ -135,8 +153,28 @@ application_clicked (GtkButton *button,
 		gdk_beep ();
 	else {
 		validate_up_down_linkage (app_window->selected);
-		poke (app_window->selected);
+		poke (app_window->selected, get_index (app_window->row_reference));
+	}
+}
+
+static void
+list_store_clear (GtkListStore *list_store)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model = GTK_TREE_MODEL (list_store);
+	Accessible *accessible;
+	gboolean ret;
+
+	ret = gtk_tree_model_get_iter_first (model, &iter);
+
+	while (ret) {
+		gtk_tree_model_get (model, &iter,
+				    APP_COL_HANDLE, &accessible,
+				    -1);
+		Accessible_unref (accessible);
+		ret = gtk_tree_model_iter_next (model, &iter);
 	}
+	gtk_list_store_clear (list_store);
 }
 
 static void
@@ -150,7 +188,7 @@ populate_app_list (AppWindow *app_window
 
 	apps = Accessible_getChildCount (desktop);
 
-	gtk_list_store_clear (app_window->list_store);
+	list_store_clear (app_window->list_store);
 	for (i = 0; i < apps; i++) {
 		char *name, *descr;
 		Accessible *child;
@@ -190,6 +228,12 @@ app_list_changed_cb (ChildListener *list
 }
 
 static void
+window_destroyed (GtkObject *obj)
+{
+	gtk_main_quit ();
+}
+
+static void
 create_app_list (AppWindow *app_window)
 {
 	app_window->list_store = 
@@ -243,6 +287,7 @@ application_window (void)
 	GClosure  *closure;
 	GladeXML  *app_xml;
 	AppWindow *app_window = g_new0 (AppWindow, 1);
+	ChildListener *cl;
 
 	app_xml = get_glade_xml ();
 	app_window->app_xml = app_xml;
@@ -289,17 +334,28 @@ application_window (void)
 	g_object_watch_closure (
 		G_OBJECT (app_window->window),
 		closure);
+	cl = child_listener_get ();
 	g_signal_connect_closure (
-		child_listener_get (),
+		cl,
 		"app_list_changed",
 		closure, FALSE);
 
+	g_signal_connect (app_window->window,
+			  "destroy",
+			  G_CALLBACK (window_destroyed),
+			  NULL);
+			  
 	gtk_main ();
 
-	gtk_widget_destroy (app_window->window);
+	if (GTK_IS_WIDGET (app_window->window))
+		gtk_widget_destroy (app_window->window);
 
+	list_store_clear (app_window->list_store);
 	g_object_unref (app_xml);
+	if (app_window->row_reference)
+		gtk_tree_row_reference_free (app_window->row_reference);
 	g_free (app_window);
+	g_object_unref (cl);
 }
 
 static gboolean
Index: src/poke.c
===================================================================
RCS file: /cvs/gnome/at-poke/src/poke.c,v
retrieving revision 1.24
diff -u -p -r1.24 poke.c
--- src/poke.c	13 Sep 2002 07:09:02 -0000	1.24
+++ src/poke.c	17 Sep 2002 12:27:48 -0000
@@ -35,7 +35,7 @@
 #include "accessible-listener.h"
 #include "accessible-tree-model.h"
 
-extern void poke (Accessible *accessible);
+extern void poke (Accessible *accessible, int index);
 
 typedef struct {
 	GladeXML     *xml;
@@ -87,6 +87,7 @@ typedef struct {
 	Accessible   *selected;
 
 	AccessibleCoordType ctype;
+	gboolean      poker_died;
 } Poker;
 
 enum {
@@ -102,6 +103,7 @@ enum {
 	RELATION_PATH
 };
 
+
 static void
 relation_row_activated_cb (GtkTreeView       *tree_view,
 			   GtkTreePath       *path,
@@ -1111,15 +1113,26 @@ init_accessible_tree (Poker *poker, Acce
 static void
 root_died_cb (ChildListener *listener, Accessible *root, Poker *poker)
 {
+	poker->poker_died = TRUE;
 	if (root == poker->root_node)
 		gtk_main_quit ();
 }
 
+static void
+window_destroyed (GtkObject *obj, Poker *poker)
+{
+	if (!poker->poker_died) {
+		poker->poker_died = TRUE;
+ 		gtk_main_quit ();
+	}
+}
+
 void
-poke (Accessible *accessible)
+poke (Accessible *accessible, int index)
 {
 	Poker *poker;
 	GtkWidget *widget;
+	gboolean poker_died;
 
 	poker = g_new0 (Poker, 1);
 	
@@ -1358,7 +1371,7 @@ poke (Accessible *accessible)
 		g_signal_connect_closure (
 			child_listener_get (), "root_died", closure, FALSE);
 
-		child_listener_add_root (child_listener_get (), poker->root_node);
+		child_listener_add_root (child_listener_get (), poker->root_node, index);
 		poker->update_id = g_signal_connect (
 			accessible_listener_get (),
 			"object-update",
@@ -1382,6 +1395,12 @@ poke (Accessible *accessible)
 			"focus_out_event",
 			G_CALLBACK (poker_window_activate_cb),
 			poker);
+
+		g_signal_connect (
+			poker->window,
+			"destroy",
+			G_CALLBACK (window_destroyed),
+			poker);
 	}
 
 	init_accessible_tree (poker, accessible);
@@ -1391,8 +1410,12 @@ poke (Accessible *accessible)
 
 	child_listener_remove_root (child_listener_get (), poker->root_node);
 
-	gtk_widget_destroy (poker->window);
-	
+	if (GTK_IS_WIDGET (poker->window))
+		gtk_widget_destroy (poker->window);
+	g_object_unref (poker->tree_model);	
 	g_object_unref (poker->xml);
+	poker_died = poker->poker_died;
 	g_free (poker);
+	if (!poker_died)
+		gtk_main_quit();
 }


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