[g-a-devel]at-poke patch for interactive refresh and Java compat



Hi:

Attached is a patch to at-poke. 
What it does:

* adds listeners to common at-spi events, so that events that change the
state of the currently selected accessible object cause the at-poke
object display to be updated;

* makes sure that the callbacks on the object display don't collide with
the update handler (above); at the moment the approach is to block the
handlers for the at-poke UI unless the poke window is active, and
conversely to block the event notification callbacks when the at-poke UI
has focus.

* corrects the spelling of the work "caret" ;)

* somewhat distressingly, provides conditional compilation guard
"JAVA_ENABLED" to removes some sanity checks which objects from the
java-access-bridge fail.  This is intended as a temporary measure until
we can figure out why certain sanity checks fail, and allows at-poke to
successfully query accessible Java applications (if compiled with
#define JAVA_ENABLED).

I am a little unsure of how to include the new files in the diff, so I
am attaching them separately.

comments please ? (such as, "ok to commit" ;-)

-Bill

? config.h.in
? at-poke.diff
? at-poke.patch
? icons/Makefile.in
? icons/Makefile
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/at-poke/ChangeLog,v
retrieving revision 1.20
diff -u -r1.20 ChangeLog
--- ChangeLog	22 Apr 2002 16:08:40 -0000	1.20
+++ ChangeLog	14 May 2002 12:29:07 -0000
@@ -1,3 +1,49 @@
+2002-05-14  Bill Haneman <bill haneman sun com>
+
+	* glade/at-poke.glade2:
+	* src/poke.c:
+	Changed spelling of "carret" to "caret".
+
+	* src/accessible-tree-model.c:
+	Added a compile-time guard, JAVA_ENABLED.
+	Disable runtime assertions for
+	g_assert (accessible_is_base_accessible (root))
+
+	* src/main.c:
+	Put #ifdef JAVA_ENABLED guards around assertion
+	(aa == accessible), instead we use g_message in that
+	case to print a warning.
+	
+	* src/poke.c:
+	Create an AccessibleListener (See added files below) and connect
+	to its "object-update" signal; keep the listener informed of
+	changes to the selected object in the tree view.
+	When fired we update the object-specific data.
+	Block the text caret signal handler 
+	(as well as the text change handler) for the duration of a text 
+	update.
+	Added method "poker_selection_object_update() and 
+	poker_window_activate_cb()".  This second function is a callback
+	which we use to block the "object-update" signal handler 
+	when the at-poke UI is active, to help avoid collisions
+	between the poke UI (which changes the Accessible) and the
+	listener which notifies at-poke of those changes.	
+
+	* src/graphics.c:
+	Associated role types LAYERED_PANE and 
+	ROOT_PANE with existing graphics "viewport_xpm".
+
+	* src/poke.c:
+	Changed the default coordinate type in poker-ctype to
+	SPI_COORD_TYPE_SCREEN.
+
+	* src/accessible-listener.c:
+	* src/accessible-listener.h:
+	New files.
+
+	* src/Makefile.am:
+	Include above new files in SOURCES.
+	
 2002-04-22  jacob berkman  <jacob ximian com>
 
 	* configure.in: fix some confusion between make and m4
Index: glade/at-poke.glade2
===================================================================
RCS file: /cvs/gnome/at-poke/glade/at-poke.glade2,v
retrieving revision 1.10
diff -u -r1.10 at-poke.glade2
--- glade/at-poke.glade2	21 Mar 2002 20:16:04 -0000	1.10
+++ glade/at-poke.glade2	14 May 2002 12:29:10 -0000
@@ -1083,7 +1083,7 @@
 			  <child>
 			    <widget class="GtkLabel" id="label2795">
 			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Carret Offset</property>
+			      <property name="label" translatable="yes">Caret Offset</property>
 			      <property name="use_underline">False</property>
 			      <property name="use_markup">False</property>
 			      <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -1102,7 +1102,7 @@
 			  </child>
 
 			  <child>
-			    <widget class="GtkSpinButton" id="text_if_carret">
+			    <widget class="GtkSpinButton" id="text_if_caret">
 			      <property name="visible">True</property>
 			      <property name="can_focus">True</property>
 			      <property name="climb_rate">1</property>
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gnome/at-poke/src/Makefile.am,v
retrieving revision 1.3
diff -u -r1.3 Makefile.am
--- src/Makefile.am	21 Mar 2002 20:16:04 -0000	1.3
+++ src/Makefile.am	14 May 2002 12:29:10 -0000
@@ -7,6 +7,8 @@
 at_poke_SOURCES =		\
 	child-listener.c	\
 	child-listener.h	\
+	accessible-listener.c	\
+	accessible-listener.h	\
 	main.c			\
 	poke.c			\
 	graphics.c		\
Index: src/accessible-tree-model.c
===================================================================
RCS file: /cvs/gnome/at-poke/src/accessible-tree-model.c,v
retrieving revision 1.11
diff -u -r1.11 accessible-tree-model.c
--- src/accessible-tree-model.c	17 Apr 2002 23:55:22 -0000	1.11
+++ src/accessible-tree-model.c	14 May 2002 12:29:11 -0000
@@ -16,6 +16,9 @@
 
 #undef DEBUG_TREE
 
+/* Java requires disabling lots of sanity checks :-( */
+#define JAVA_ENABLED
+
 /* FIXME: leaks references like a sieve ! */
 
 static GObjectClass *parent_class;
@@ -132,6 +135,8 @@
 		 tree_model->root_node,
 		 Accessible_getRoleName (tree_model->root_node),
 		 Accessible_getName (tree_model->root_node));
+	if (node == tree_model->root_node) 
+		fprintf (stderr, "node is root node\n");
 #endif
 
 	while (node != tree_model->root_node && node != NULL) {
@@ -367,9 +372,9 @@
 	g_return_val_if_fail (root != NULL, NULL);
 	
 	model = g_object_new (ACCESSIBLE_TYPE_TREE_MODEL, NULL);
-
-	g_assert (accessible_is_base_accessible (root));
-
+#ifndef JAVA_ENABLED
+	g_assert (accessible_is_base_accessible (root)); 
+#endif
 	ACCESSIBLE_TREE_MODEL (model)->root_node = root;
 
 	make_root_path_iter (
Index: src/graphics.c
===================================================================
RCS file: /cvs/gnome/at-poke/src/graphics.c,v
retrieving revision 1.4
diff -u -r1.4 graphics.c
--- src/graphics.c	28 Mar 2002 20:45:35 -0000	1.4
+++ src/graphics.c	14 May 2002 12:29:11 -0000
@@ -69,7 +69,7 @@
 	{ SPI_ROLE_IMAGE, image_xpm },
 	{ SPI_ROLE_INTERNAL_FRAME, NULL },
 	{ SPI_ROLE_LABEL, label_xpm },
-	{ SPI_ROLE_LAYERED_PANE, NULL },
+	{ SPI_ROLE_LAYERED_PANE, viewport_xpm },
 	{ SPI_ROLE_LIST, NULL },
 	{ SPI_ROLE_LIST_ITEM, NULL },
 	{ SPI_ROLE_MENU, menuitem_xpm },
@@ -85,7 +85,7 @@
 	{ SPI_ROLE_PUSH_BUTTON, button_xpm },
 	{ SPI_ROLE_RADIO_BUTTON, NULL },
 	{ SPI_ROLE_RADIO_MENU_ITEM, NULL },
-	{ SPI_ROLE_ROOT_PANE, NULL },
+	{ SPI_ROLE_ROOT_PANE, viewport_xpm },
 	{ SPI_ROLE_ROW_HEADER, NULL },
 	{ SPI_ROLE_SCROLL_BAR, vscrollbar_xpm },
 	{ SPI_ROLE_SCROLL_PANE, scrolledwindow_xpm },
@@ -107,7 +107,7 @@
 	{ SPI_ROLE_TREE, tree_xpm },
 	{ SPI_ROLE_TREE_TABLE, tree_xpm },
 	{ SPI_ROLE_UNKNOWN, unknown_xpm },
-	{ SPI_ROLE_VIEWPORT, NULL },
+	{ SPI_ROLE_VIEWPORT, viewport_xpm },
 	{ SPI_ROLE_WINDOW, window_xpm },
 	{ SPI_ROLE_EXTENDED, NULL },
 	{ 0xffffff, NULL}
Index: src/main.c
===================================================================
RCS file: /cvs/gnome/at-poke/src/main.c,v
retrieving revision 1.9
diff -u -r1.9 main.c
--- src/main.c	21 Mar 2002 21:08:47 -0000	1.9
+++ src/main.c	14 May 2002 12:29:11 -0000
@@ -26,6 +26,9 @@
 #include "graphics.h"
 #include "child-listener.h"
 
+/* Java requires disabling lots of sanity checks :-( */
+#define JAVA_ENABLED
+
 extern void poke (Accessible *accessible);
 
 #define APP_COL_NAME   0
@@ -105,15 +108,22 @@
 	Accessible *parent;
 
 	aa = Accessible_queryInterface (accessible, "IDL:Accessibility/Accessible:1.0");
+#ifndef JAVA_ENABLED	
 	g_assert (aa == accessible);
-
+#else
+        if (aa != accessible) {
+		g_message ("aa == accessible failed");
+		fprintf (stderr,"cmp %p %p\n", aa, accessible);
+	}
+#endif
 	child = Accessible_getChildAtIndex (accessible, 0);
 	if (!child)
 		return;
 
 	parent = Accessible_getParent (child);
-
+#ifndef JAVA_ENABLED
 	g_assert (parent == accessible);
+#endif
 }
 
 static void
Index: src/poke.c
===================================================================
RCS file: /cvs/gnome/at-poke/src/poke.c,v
retrieving revision 1.19
diff -u -r1.19 poke.c
--- src/poke.c	17 Apr 2002 23:55:22 -0000	1.19
+++ src/poke.c	14 May 2002 12:29:13 -0000
@@ -18,6 +18,8 @@
  *    + AccessibleHypertext
  *    + AccessibleHyperlink
  *    + editable text
+ *    + sync text caret spinbutton with text entry field, and changes to
+ *      length of text string.
  */
 
 #include <config.h>
@@ -31,6 +33,7 @@
 
 #include "graphics.h"
 #include "child-listener.h"
+#include "accessible-listener.h"
 #include "accessible-tree-model.h"
 
 extern void poke (Accessible *accessible);
@@ -57,8 +60,9 @@
 	GtkWidget    *action_take;
 
 	GtkWidget    *text;
-	GtkWidget    *text_carret;
+	GtkWidget    *text_caret;
 	gulong        text_changed_id;
+	gulong        caret_changed_id;
 
 	GtkWidget    *value_minimum;
 	GtkWidget    *value_current;
@@ -74,6 +78,8 @@
 	GtkWidget    *selection_clear;
 	gulong        selection_changed_id;
 
+	gulong        update_id;
+
 	Accessible   *selected;
 
 	AccessibleCoordType ctype;
@@ -424,6 +430,7 @@
 	char *txt;
 
 	g_signal_handler_block (poker->text, poker->text_changed_id);
+	g_signal_handler_block (poker->text_caret, poker->caret_changed_id);
 
 	txt = AccessibleText_getText (text, 0, -1);
 	gtk_entry_set_text (GTK_ENTRY (poker->text), txt);
@@ -435,11 +442,13 @@
 	g_signal_handler_unblock (poker->text, poker->text_changed_id);
 
 	gtk_spin_button_set_value (
-		GTK_SPIN_BUTTON (poker->text_carret),
+		GTK_SPIN_BUTTON (poker->text_caret),
 		AccessibleText_getCaretOffset (text));
 	gtk_spin_button_set_range (
-		GTK_SPIN_BUTTON (poker->text_carret),
+		GTK_SPIN_BUTTON (poker->text_caret),
 		0, AccessibleText_getCharacterCount (text));
+
+	g_signal_handler_unblock (poker->text_caret, poker->caret_changed_id);
 }
 
 static void
@@ -462,7 +471,7 @@
 }
 
 static void
-text_carret_changed_cb (GtkSpinButton *spin_button,
+text_caret_changed_cb (GtkSpinButton *spin_button,
 			Poker         *poker)
 {
 	AccessibleText *text;
@@ -803,7 +812,7 @@
 update_frame_visibility (Poker *poker, Accessible *accessible)
 {
 	int i;
-
+	
 	for (i = 0; poker_widget_names [i].interface_name; i++) {
 		GtkWidget *frame;
 		AccessibleUnknown *unknown;
@@ -832,6 +841,13 @@
 }
 
 static void
+poker_selected_object_update (AccessibleListener *listener,
+			      Poker              *poker)
+{
+	update_frame_visibility (poker, poker->selected);
+}
+
+
 poker_tree_selection_changed (GtkTreeSelection *selection,
 			      Poker            *poker)
 {
@@ -847,6 +863,9 @@
 
 	poker->selected = accessible;
 
+	accessible_listener_set_target (
+	accessible_listener_get(), accessible);
+	
 	update_frame_visibility (poker, accessible);
 }
 
@@ -877,6 +896,36 @@
 }
 
 static void
+poker_window_activate_cb (GtkWindow     *window,
+			  GdkEventFocus *event,
+			  Poker         *poker)
+{
+	static gint local_changes_blocked = 0;
+	if (event->in)
+	{
+		g_signal_handler_block (accessible_listener_get(),
+					poker->update_id);
+		if (local_changes_blocked) {
+			g_signal_handler_unblock (poker->text,
+						  poker->text_changed_id);
+			g_signal_handler_unblock (poker->text_caret,
+						  poker->caret_changed_id);
+			--local_changes_blocked;
+		}
+	}
+	else
+	{
+		++local_changes_blocked;
+		g_signal_handler_block (poker->text,
+					poker->text_changed_id);
+		g_signal_handler_block (poker->text_caret,
+					poker->caret_changed_id);
+		g_signal_handler_unblock (accessible_listener_get(),
+					  poker->update_id);
+	}
+}
+
+static void
 add_pix_name_column (GtkTreeView *tree_view,
 		     int          icon_col,
 		     int          name_col)
@@ -971,9 +1020,9 @@
 	GtkWidget *widget;
 
 	poker = g_new0 (Poker, 1);
-
+	
 	/* FIXME: need a toggle for this */
-	poker->ctype = SPI_COORD_TYPE_WINDOW;
+	poker->ctype = SPI_COORD_TYPE_SCREEN;
 
 	poker->root_node = accessible;
 	poker->xml = get_glade_xml ();
@@ -1059,11 +1108,13 @@
 			g_signal_connect (poker->text, "changed",
 					  G_CALLBACK (editable_text_changed_cb),
 					  poker);
-		poker->text_carret = glade_xml_get_widget (
-			poker->xml, "text_if_carret");
-		g_signal_connect (poker->text_carret,
+
+		poker->text_caret = glade_xml_get_widget (
+			poker->xml, "text_if_caret");
+		poker->caret_changed_id =
+			g_signal_connect (poker->text_caret,
 				  "value_changed",
-				  G_CALLBACK (text_carret_changed_cb),
+				  G_CALLBACK (text_caret_changed_cb),
 				  poker);
 	}
 
@@ -1180,6 +1231,23 @@
 			child_listener_get (), "root_died", closure, FALSE);
 
 		child_listener_add_root (child_listener_get (), poker->root_node);
+		poker->update_id = g_signal_connect (
+			accessible_listener_get (),
+			"object-update",
+			G_CALLBACK (poker_selected_object_update),
+			poker);
+
+		g_signal_connect (
+			poker->window,
+			"focus_in_event",
+			G_CALLBACK (poker_window_activate_cb),
+			poker);
+
+		g_signal_connect (
+			poker->window,
+			"focus_out_event",
+			G_CALLBACK (poker_window_activate_cb),
+			poker);
 	}
 
 	init_accessible_tree (poker, accessible);
@@ -1190,7 +1258,7 @@
 	child_listener_remove_root (child_listener_get (), poker->root_node);
 
 	gtk_widget_destroy (poker->window);
-
+	
 	g_object_unref (poker->xml);
 	g_free (poker);
 }
/*
 * accessible-listener.h: listens to at-spi events and
 *                       emits a signal if their source matches
 *                       the currently selected target.
 *
 * Author:
 *    Bill Haneman
 *
 * Copyright 2002 Sun Microsystems, Inc.
 */
#ifndef ACCESSIBLE_LISTENER_H
#define ACCESSIBLE_LISTENER_H

#include <cspi/spi.h>
#include <glib-object.h>

typedef struct {
	GObject parent;
	Accessible *target;
	AccessibleEventListener *el;
} AccessibleListener;

typedef struct {
	GObjectClass parent_class;

	/* signals */
	void (*update) (AccessibleListener *listener, void *user_data);
} AccessibleListenerClass;

AccessibleListener *accessible_listener_get         (void);
void accessible_listener_set_target (AccessibleListener *al,
				     Accessible *accessible);

#endif /* ACCESSIBLE_LISTENER_H */
/*
 * selection-listener.c: listens to selected at-spi events
 *                       and calls into the at-poke API.
 *
 * Author:
 *    Bill Haneman
 *
 * Copyright 2002 Sun Microsystems, Inc.
 */
#include "accessible-listener.h"
#include <libgnome/gnome-macros.h>

enum {
	UPDATE,
	LAST_SIGNAL
};

static guint signals [LAST_SIGNAL];
static GObjectClass *parent_class;
static gchar *event_names[8] = {
	"object:text-changed",
	"object:text-caret-moved",
	"object:text-selection-changed",
	"object:selection-changed",
	"object:property-change",
	"object:visible-data-changed",
	"object:state-changed",
	NULL
};

GType accessible_listener_get_type (void);

GNOME_CLASS_BOILERPLATE (AccessibleListener,
			 accessible_listener,
			 GObject,
			 G_TYPE_OBJECT);

static void
accessible_listener_global_event (const AccessibleEvent *event,
				  void                  *user_data)
{
	AccessibleListener *al = user_data;
	if (event->source == al->target) {
		g_signal_emit (
			al, signals [UPDATE], 0);
	}
}

static void
accessible_listener_instance_init (AccessibleListener *al)
{
	gint i;
	al->el = SPI_createAccessibleEventListener (
		accessible_listener_global_event, al);
	
	for (i = 0; event_names [i] != NULL; ++i )
	{
		SPI_registerGlobalEventListener (al->el, event_names[i]);
	}
	/* TODO: listen to various table events also */
}

static void
accessible_listener_dispose (GObject *object)
{
	AccessibleListener *al = (AccessibleListener *) object;

	if (al->el) {
		SPI_deregisterGlobalEventListenerAll (al->el);
		AccessibleEventListener_unref (al->el);
		al->el = NULL;
	}

	parent_class->dispose (object);
}

static void
accessible_listener_class_init (AccessibleListenerClass *klass)
{
	GObjectClass *gobject_class = (GObjectClass *) klass;

	parent_class = g_type_class_peek_parent (klass);

	gobject_class->dispose = accessible_listener_dispose;
	
	signals [UPDATE] =
		g_signal_new ("object-update",
			      G_TYPE_FROM_CLASS (gobject_class),
			      G_SIGNAL_RUN_LAST,
			      0,
			      NULL, NULL,
			      g_cclosure_marshal_VOID__VOID,
			      G_TYPE_NONE, 0);
}

AccessibleListener *
accessible_listener_get (void)
{
	static AccessibleListener *listener = NULL;

	if (!listener)
		listener = g_object_new (
			accessible_listener_get_type (), NULL);

	return listener;
}

void
accessible_listener_set_target (AccessibleListener *al,
				Accessible *accessible)
{
	al->target = accessible;
}


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