From ffa112d586c7ba44d9e60076be94d75b5cbe41e5 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 16 Jul 2011 10:03:20 -0400 Subject: [PATCH] Add an initial focus testbed This is an attempt to explore differences in GTK+'s and gails notions of which widget currently has the focus. Since gail does all its focus updates in an idle, we cannot do the comparisons synchronously, so just check ever so often in a timeout. --- tests/a11y/Makefile.am | 1 + tests/a11y/testfocus.c | 117 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 tests/a11y/testfocus.c diff --git a/tests/a11y/Makefile.am b/tests/a11y/Makefile.am index 1fcd5eb4ce..83f4d19b16 100644 --- a/tests/a11y/Makefile.am +++ b/tests/a11y/Makefile.am @@ -26,6 +26,7 @@ TEST_PROGS += text TEST_PROGS += children TEST_PROGS += focus +TEST_PROGS += testfocus TEST_PROGS += util diff --git a/tests/a11y/testfocus.c b/tests/a11y/testfocus.c new file mode 100644 index 0000000000..131a82ae60 --- /dev/null +++ b/tests/a11y/testfocus.c @@ -0,0 +1,117 @@ +#include + +static const gchar * +get_name (gpointer obj) +{ + GtkWidget *widget; + if (obj == NULL) + return "(nil)"; + else if (GTK_IS_WIDGET (obj)) + widget = GTK_WIDGET (obj); + else if (GTK_IS_ACCESSIBLE (obj)) + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); + else + return "OOPS"; + if (GTK_IS_BUILDABLE (widget)) + return gtk_buildable_get_name (GTK_BUILDABLE (widget)); + else + return G_OBJECT_TYPE_NAME (widget); +} + +static gboolean +compare_focus (gpointer data) +{ + AtkObject *atk_focus; + AtkObject *gtk_focus; + GtkWidget *focus_widget; + GList *list, *l; + + atk_focus = atk_get_focus_object (); + + focus_widget = NULL; + list = gtk_window_list_toplevels (); + for (l = list; l; l = l->next) + { + GtkWindow *w = l->data; + if (gtk_window_is_active (w)) + { + focus_widget = gtk_window_get_focus (w); + break; + } + } + g_list_free (list); + + if (GTK_IS_WIDGET (focus_widget)) + gtk_focus = gtk_widget_get_accessible (focus_widget); + else + gtk_focus = NULL; + + if (gtk_focus != atk_focus) + g_print ("gtk focus: %s != atk focus: %s\n", + get_name (gtk_focus), get_name (atk_focus)); + + return TRUE; +} + +static void +notify_cb (GObject *obj, GParamSpec *pspec, gpointer data) +{ + gboolean value; + + if (g_strcmp0 (pspec->name, "has-focus") != 0) + return; + + g_object_get (obj, "has-focus", &value, NULL); + g_print ("widget %s %p has-focus -> %d\n", get_name (obj), obj, value); +} + +static void +state_change_cb (AtkObject *obj, const gchar *name, gboolean state_set) +{ + AtkStateSet *set; + + set = atk_object_ref_state_set (obj); + g_print ("accessible %s %p focused -> %d\n", get_name (obj), obj, + atk_state_set_contains_state (set, ATK_STATE_FOCUSED)); + g_object_unref (set); +} + +int +main (int argc, char *argv[]) +{ + GtkBuilder *builder; + GtkWidget *window; + GSList *o, *l; + GtkWidget *widget; + AtkObject *accessible; + + gtk_init (&argc, &argv); + + builder = gtk_builder_new (); + gtk_builder_add_from_file (builder, argv[1], NULL); + + window = (GtkWidget *)gtk_builder_get_object (builder, "window1"); + + o = gtk_builder_get_objects (builder); + for (l = o; l;l = l->next) + { + if (!GTK_IS_WIDGET (l->data)) + continue; + + widget = l->data; + g_signal_connect (widget, "notify::has-focus", G_CALLBACK (notify_cb), NULL); + accessible = gtk_widget_get_accessible (widget); + g_signal_connect (accessible, "state-change::focused", G_CALLBACK (state_change_cb), NULL); + + } + g_slist_free (o); + + g_timeout_add (100, compare_focus, NULL); + + gtk_widget_show_all (window); + + gtk_main (); + + return 0; +} +