summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--docs/reference/ChangeLog5
-rw-r--r--docs/reference/gtk/tmpl/gtkwidget.sgml25
-rwxr-xr-xgtk/gtk-builder-convert82
-rw-r--r--gtk/gtktestutils.c1
-rw-r--r--gtk/gtkwidget.c316
-rw-r--r--tests/buildertest.c94
7 files changed, 465 insertions, 75 deletions
diff --git a/ChangeLog b/ChangeLog
index 3c0fbc3059..f0afbf53e5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2008-01-25 Johan Dahlin <johan@gnome.org>
+
+ * gtk/gtkwidget.c: (gtk_widget_buildable_interface_init),
+ (gtk_widget_buildable_get_internal_child), (free_action),
+ (free_relation), (gtk_widget_buildable_parser_finished),
+ (accessibility_start_element),
+ (gtk_widget_buildable_custom_tag_start),
+ (gtk_widget_buildable_custom_finished):
+ Implement accessible support, fixes #454653.
+
+ * gtk/gtk-builder-convert:
+ Add support for migrating old glade files
+
+ * tests/buildertest.c: (test_widget), (test_file):
+ Add accessible tests and imprve the test_file function to display
+ toplevels and run dialogs.
+
2008-01-25 Richard Hult <richard@imendio.com>
* gdk/quartz/GdkQuartzView.c: Don't recreate a tracking rect if it
diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog
index f84a3e6d81..b30db862a9 100644
--- a/docs/reference/ChangeLog
+++ b/docs/reference/ChangeLog
@@ -1,3 +1,8 @@
+2008-01-24 Johan Dahlin <johan@gnome.org>
+
+ * gtk/tmpl/gtkwidget.sgml:
+ Add documentation for <accessible> buildable tag.
+
2008-01-14 Matthias Clasen <mclasen@redhat.com>
* gtk/gtk-docs.sgml:
diff --git a/docs/reference/gtk/tmpl/gtkwidget.sgml b/docs/reference/gtk/tmpl/gtkwidget.sgml
index 11f7d4ccfc..b03ee0b9f5 100644
--- a/docs/reference/gtk/tmpl/gtkwidget.sgml
+++ b/docs/reference/gtk/tmpl/gtkwidget.sgml
@@ -37,6 +37,31 @@ modifiers and signal and allows to specify accelerators.
</object>
]]></programlisting>
</example>
+In addition to accelerators, <structname>GtkWidget</structname> also support a
+custom &lt;accessible&gt; element, which supports actions and relations.
+Properties on the accessible implementation of an object can be set by accessing the
+internal child "accessible" of a <structname>GtkWidget</structname>.
+<example>
+<title>A UI definition fragment specifying an accessible</title>
+<programlisting><![CDATA[
+<object class="GtkButton" id="label1"/>
+ <property name="label">I am a Label for a Button</property>
+</object>
+<object class="GtkButton" id="button1">
+ <accessibility>
+ <action action_name="click" description="Click the button."/>
+ <relation target="label1" type="labelled-by"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="a11y-button1">
+ <property name="AtkObject::name">Clickable Button</property>
+ </object>
+ </child>
+</object>
+]]></programlisting>
+</example>
+
+
</refsect2>
<!-- ##### SECTION See_Also ##### -->
diff --git a/gtk/gtk-builder-convert b/gtk/gtk-builder-convert
index 3544e221ac..9840ad957a 100755
--- a/gtk/gtk-builder-convert
+++ b/gtk/gtk-builder-convert
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright (C) 2006-2007 Async Open Source
+# Copyright (C) 2006-2008 Async Open Source
# Henrique Romano <henrique@async.com.br>
# Johan Dahlin <jdahlin@async.com.br>
#
@@ -124,7 +124,7 @@ def get_accelerator_nodes(node):
return accelerators
def get_object_node(child_node):
- assert child_node.tagName == 'child'
+ assert child_node.tagName == 'child', child_node
nodes = []
for node in child_node.childNodes:
if node.nodeType == Node.TEXT_NODE:
@@ -178,7 +178,7 @@ class GtkBuilderConverter(object):
return [w for w in self._dom.getElementsByTagName("object")
if w.getAttribute(attribute) == value]
- def _create_object(self, obj_class, obj_id, template=None, **properties):
+ def _create_object(self, obj_class, obj_id, template=None, properties=None):
"""
Creates a new <object> tag.
Optionally a name template can be provided which will be used
@@ -207,22 +207,23 @@ class GtkBuilderConverter(object):
obj = self._dom.createElement('object')
obj.setAttribute('class', obj_class)
obj.setAttribute('id', obj_id)
- for name, value in properties.items():
- if isinstance(value, Node):
- # Reuse the node, so translatable and context still will be
- # set when converting nodes. See also #509153
- prop = value
- else:
- prop = self._dom.createElement('property')
- prop.appendChild(self._dom.createTextNode(value))
-
- prop.setAttribute('name', name)
- obj.appendChild(prop)
+ if properties:
+ for name, value in properties.items():
+ if isinstance(value, Node):
+ # Reuse the node, so translatable and context still will be
+ # set when converting nodes. See also #509153
+ prop = value
+ else:
+ prop = self._dom.createElement('property')
+ prop.appendChild(self._dom.createTextNode(value))
+
+ prop.setAttribute('name', str(name))
+ obj.appendChild(prop)
self.objects[obj_id] = obj
return obj
- def _create_root_object(self, obj_class, template, **properties):
- obj = self._create_object(obj_class, None, template, **properties)
+ def _create_root_object(self, obj_class, template, properties=None):
+ obj = self._create_object(obj_class, None, template, properties)
self.root_objects.append(obj)
return obj
@@ -261,6 +262,10 @@ class GtkBuilderConverter(object):
for node in self._dom.getElementsByTagName("ui"):
self._convert_ui(node)
+ # Convert accessibility tag
+ for node in self._dom.getElementsByTagName("accessibility"):
+ self._convert_accessibility(node)
+
# Output the newly created root objects and sort them
# by attribute id
for obj in sorted(self.root_objects,
@@ -421,7 +426,7 @@ class GtkBuilderConverter(object):
properties['name'] = object_id
action = self._create_object(name,
object_id,
- **properties)
+ properties=properties)
for signal in get_signal_nodes(node):
signal_name = signal.getAttribute('name')
@@ -514,12 +519,12 @@ class GtkBuilderConverter(object):
value, lower, upper, step, page, page_size = data.split(' ')
adj = self._create_root_object("GtkAdjustment",
template='adjustment',
- value=value,
- lower=lower,
- upper=upper,
- step_increment=step,
- page_increment=page,
- page_size=page_size)
+ properties=dict(value=value,
+ lower=lower,
+ upper=upper,
+ step_increment=step,
+ page_increment=page,
+ page_size=page_size))
prop.childNodes[0].data = adj.getAttribute('id')
def _convert_combobox_items(self, node, prop):
@@ -581,7 +586,7 @@ class GtkBuilderConverter(object):
prop.removeAttribute('translatable')
tbuffer = self._create_root_object("GtkTextBuffer",
template='textbuffer',
- text=data)
+ properties=dict(text=data))
prop.childNodes[0].data = tbuffer.getAttribute('id')
def _packing_prop_to_child_attr(self, node, prop_name, prop_val,
@@ -623,6 +628,35 @@ class GtkBuilderConverter(object):
widget.getAttributeNode("constructor").value = parent_id
node.removeAttribute("id")
+ def _convert_accessibility(self, node):
+ objectNode = node.parentNode
+ parent_id = objectNode.getAttribute("id")
+
+ properties = {}
+ for node in node.childNodes:
+ if node.nodeName == 'atkproperty':
+ node.tagName = 'property'
+ properties[node.getAttribute('name')] = node
+ node.parentNode.removeChild(node)
+ elif node.nodeName == 'atkrelation':
+ node.tagName = 'relation'
+ relation_type = node.getAttribute('type')
+ relation_type = relation_type.replace('_', '-')
+ node.setAttribute('type', relation_type)
+ elif node.nodeName == 'atkaction':
+ node.tagName = 'action'
+
+ if properties:
+ child = self._dom.createElement('child')
+ child.setAttribute("internal-child", "accessible")
+
+ atkobject = self._create_object(
+ "AtkObject", None,
+ template='a11y-%s' % (parent_id,),
+ properties=properties)
+ child.appendChild(atkobject)
+ objectNode.appendChild(child)
+
def _strip_root(self, root_name):
for widget in self._dom.getElementsByTagName("widget"):
if widget.getAttribute('id') == root_name:
diff --git a/gtk/gtktestutils.c b/gtk/gtktestutils.c
index dfafa7bfbe..cd9d6abf67 100644
--- a/gtk/gtktestutils.c
+++ b/gtk/gtktestutils.c
@@ -60,7 +60,6 @@ gtk_test_init (int *argcp,
* FUTURE TODO:
* - this function could install a mock object around GtkSettings
*/
- g_setenv ("GTK_MODULES", "", TRUE);
g_setenv ("GTK2_RC_FILES", "/dev/null", TRUE);
gtk_disable_setlocale();
setlocale (LC_ALL, "C");
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index e3d824e823..fec929f6e5 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -251,6 +251,9 @@ static void gtk_widget_buildable_interface_init (GtkBuildableIfa
static void gtk_widget_buildable_set_name (GtkBuildable *buildable,
const gchar *name);
static const gchar * gtk_widget_buildable_get_name (GtkBuildable *buildable);
+static GObject * gtk_widget_buildable_get_internal_child (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ const gchar *childname);
static void gtk_widget_buildable_set_buildable_property (GtkBuildable *buildable,
GtkBuilder *builder,
const gchar *name,
@@ -8786,17 +8789,20 @@ gtk_widget_ref_accessible (AtkImplementor *implementor)
/*
* GtkBuildable implementation
*/
-static GQuark quark_builder_has_default = 0;
-static GQuark quark_builder_has_focus = 0;
+static GQuark quark_builder_has_default = 0;
+static GQuark quark_builder_has_focus = 0;
+static GQuark quark_builder_atk_relations = 0;
static void
gtk_widget_buildable_interface_init (GtkBuildableIface *iface)
{
quark_builder_has_default = g_quark_from_static_string ("gtk-builder-has-default");
quark_builder_has_focus = g_quark_from_static_string ("gtk-builder-has-focus");
+ quark_builder_atk_relations = g_quark_from_static_string ("gtk-builder-atk-relations");
iface->set_name = gtk_widget_buildable_set_name;
iface->get_name = gtk_widget_buildable_get_name;
+ iface->get_internal_child = gtk_widget_buildable_get_internal_child;
iface->set_buildable_property = gtk_widget_buildable_set_buildable_property;
iface->parser_finished = gtk_widget_buildable_parser_finished;
iface->custom_tag_start = gtk_widget_buildable_custom_tag_start;
@@ -8816,6 +8822,17 @@ gtk_widget_buildable_get_name (GtkBuildable *buildable)
return gtk_widget_get_name (GTK_WIDGET (buildable));
}
+static GObject *
+gtk_widget_buildable_get_internal_child (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ const gchar *childname)
+{
+ if (strcmp (childname, "accessible") == 0)
+ return G_OBJECT (gtk_widget_get_accessible (GTK_WIDGET (buildable)));
+
+ return NULL;
+}
+
static void
gtk_widget_buildable_set_buildable_property (GtkBuildable *buildable,
GtkBuilder *builder,
@@ -8832,17 +8849,224 @@ gtk_widget_buildable_set_buildable_property (GtkBuildable *buildable,
g_object_set_property (G_OBJECT (buildable), name, value);
}
+typedef struct {
+ gchar *action_name;
+ gchar *description;
+} AtkActionData;
+
+typedef struct {
+ gchar *target;
+ gchar *type;
+} AtkRelationData;
+
+static void
+free_action (AtkActionData *data, gpointer user_data)
+{
+ g_free (data->action_name);
+ g_free (data->description);
+ g_slice_free (AtkActionData, data);
+}
+
+static void
+free_relation (AtkRelationData *data, gpointer user_data)
+{
+ g_free (data->target);
+ g_free (data->type);
+ g_slice_free (AtkRelationData, data);
+}
+
static void
gtk_widget_buildable_parser_finished (GtkBuildable *buildable,
GtkBuilder *builder)
{
+ GSList *atk_relations;
+
if (g_object_get_qdata (G_OBJECT (buildable), quark_builder_has_default))
gtk_widget_grab_default (GTK_WIDGET (buildable));
if (g_object_get_qdata (G_OBJECT (buildable), quark_builder_has_focus))
gtk_widget_grab_focus (GTK_WIDGET (buildable));
+
+ atk_relations = g_object_get_qdata (G_OBJECT (buildable),
+ quark_builder_atk_relations);
+ if (atk_relations)
+ {
+ AtkObject *accessible;
+ AtkRelationSet *relation_set;
+ GSList *l;
+ GObject *target;
+ AtkRelationType relation_type;
+ AtkObject *target_accessible;
+
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (buildable));
+ relation_set = atk_object_ref_relation_set (accessible);
+
+ for (l = atk_relations; l; l = l->next)
+ {
+ AtkRelationData *relation = (AtkRelationData*)l->data;
+
+ target = gtk_builder_get_object (builder, relation->target);
+ if (!target)
+ {
+ g_warning ("Target object %s in <relation> does not exist",
+ relation->target);
+ continue;
+ }
+ target_accessible = gtk_widget_get_accessible (GTK_WIDGET (target));
+ g_assert (target_accessible != NULL);
+
+ relation_type = atk_relation_type_for_name (relation->type);
+ if (relation_type == ATK_RELATION_NULL)
+ {
+ g_warning ("<relation> type %s not found",
+ relation->type);
+ continue;
+ }
+ atk_relation_set_add_relation_by_type (relation_set, relation_type,
+ target_accessible);
+ }
+ g_object_unref (relation_set);
+
+ g_slist_foreach (atk_relations, (GFunc)free_relation, NULL);
+ g_slist_free (atk_relations);
+ g_object_set_qdata (G_OBJECT (buildable), quark_builder_atk_relations,
+ NULL);
+ }
+
}
typedef struct {
+ GSList *actions;
+ GSList *relations;
+} AccessibilitySubParserData;
+
+static void
+accessibility_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **names,
+ const gchar **values,
+ gpointer user_data,
+ GError **error)
+{
+ AccessibilitySubParserData *data = (AccessibilitySubParserData*)user_data;
+ guint i;
+ gint line_number, char_number;
+
+ if (strcmp (element_name, "relation") == 0)
+ {
+ gchar *target = NULL;
+ gchar *type = NULL;
+ AtkRelationData *relation;
+
+ for (i = 0; names[i]; i++)
+ {
+ if (strcmp (names[i], "target") == 0)
+ target = g_strdup (values[i]);
+ else if (strcmp (names[i], "type") == 0)
+ type = g_strdup (values[i]);
+ else
+ {
+ g_markup_parse_context_get_position (context,
+ &line_number,
+ &char_number);
+ g_set_error (error,
+ GTK_BUILDER_ERROR,
+ GTK_BUILDER_ERROR_INVALID_ATTRIBUTE,
+ "%s:%d:%d '%s' is not a valid attribute of <%s>",
+ "<input>",
+ line_number, char_number, names[i], "relation");
+ g_free (target);
+ g_free (type);
+ return;
+ }
+ }
+
+ if (!target || !type)
+ {
+ g_markup_parse_context_get_position (context,
+ &line_number,
+ &char_number);
+ g_set_error (error,
+ GTK_BUILDER_ERROR,
+ GTK_BUILDER_ERROR_MISSING_ATTRIBUTE,
+ "%s:%d:%d <%s> requires attribute \"%s\"",
+ "<input>",
+ line_number, char_number, "relation",
+ type ? "target" : "type");
+ g_free (target);
+ g_free (type);
+ return;
+ }
+
+ relation = g_slice_new (AtkRelationData);
+ relation->target = target;
+ relation->type = type;
+
+ data->relations = g_slist_prepend (data->relations, relation);
+ }
+ else if (strcmp (element_name, "action") == 0)
+ {
+ gchar *action_name = NULL;
+ gchar *description = NULL;
+ AtkActionData *action;
+
+ for (i = 0; names[i]; i++)
+ {
+ if (strcmp (names[i], "action_name") == 0)
+ action_name = g_strdup (values[i]);
+ else if (strcmp (names[i], "description") == 0)
+ description = g_strdup (values[i]);
+ else
+ {
+ g_markup_parse_context_get_position (context,
+ &line_number,
+ &char_number);
+ g_set_error (error,
+ GTK_BUILDER_ERROR,
+ GTK_BUILDER_ERROR_INVALID_ATTRIBUTE,
+ "%s:%d:%d '%s' is not a valid attribute of <%s>",
+ "<input>",
+ line_number, char_number, names[i], "action");
+ g_free (action_name);
+ g_free (description);
+ return;
+ }
+ }
+
+ if (!action_name || !description)
+ {
+ g_markup_parse_context_get_position (context,
+ &line_number,
+ &char_number);
+ g_set_error (error,
+ GTK_BUILDER_ERROR,
+ GTK_BUILDER_ERROR_MISSING_ATTRIBUTE,
+ "%s:%d:%d <%s> requires attribute \"%s\"",
+ "<input>",
+ line_number, char_number, "action",
+ description ? "action_name" : "description");
+ g_free (action_name);
+ g_free (description);
+ return;
+ }
+
+ action = g_slice_new (AtkActionData);
+ action->action_name = action_name;
+ action->description = description;
+
+ data->actions = g_slist_prepend (data->actions, action);
+ }
+ else if (strcmp (element_name, "accessibility") == 0)
+ ;
+ else
+ g_warning ("Unsupported tag for GtkWidget: %s\n", element_name);
+}
+
+static const GMarkupParser accessibility_parser =
+ {
+ accessibility_start_element,
+ };
+
+typedef struct {
GObject *object;
guint key;
guint modifiers;
@@ -8894,12 +9118,6 @@ static const GMarkupParser accel_group_parser =
accel_group_start_element,
};
-static const GMarkupParser accessibility_parser =
- {
- NULL,
- };
-
-
static gboolean
gtk_widget_buildable_custom_tag_start (GtkBuildable *buildable,
GtkBuilder *builder,
@@ -8908,31 +9126,25 @@ gtk_widget_buildable_custom_tag_start (GtkBuildable *buildable,
GMarkupParser *parser,
gpointer *data)
{
- AccelGroupParserData *parser_data;
-
g_assert (buildable);
if (strcmp (tagname, "accelerator") == 0)
{
+ AccelGroupParserData *parser_data;
+
parser_data = g_slice_new0 (AccelGroupParserData);
parser_data->object = g_object_ref (buildable);
*parser = accel_group_parser;
*data = parser_data;
return TRUE;
}
- else if (strcmp (tagname, "accessibility") == 0)
+ if (strcmp (tagname, "accessibility") == 0)
{
- static gboolean warning_showed = FALSE;
-
- if (!warning_showed)
- {
- g_warning ("<accessibility> is being ignored,\n"
- "see http://bugzilla.gnome.org/show_bug.cgi?id=454653\n");
- warning_showed = TRUE;
- }
+ AccessibilitySubParserData *parser_data;
+ parser_data = g_slice_new0 (AccessibilitySubParserData);
*parser = accessibility_parser;
- *data = NULL;
+ *data = parser_data;
return TRUE;
}
return FALSE;
@@ -8945,17 +9157,18 @@ gtk_widget_buildable_custom_finished (GtkBuildable *buildable,
const gchar *tagname,
gpointer user_data)
{
- AccelGroupParserData *data;
+ AccelGroupParserData *accel_data;
+ AccessibilitySubParserData *a11y_data;
GtkWidget *toplevel;
GSList *accel_groups;
GtkAccelGroup *accel_group;
if (strcmp (tagname, "accelerator") == 0)
{
- data = (AccelGroupParserData*)user_data;
- g_assert (data->object);
+ accel_data = (AccelGroupParserData*)user_data;
+ g_assert (accel_data->object);
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (data->object));
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (accel_data->object));
accel_groups = gtk_accel_groups_from_object (G_OBJECT (toplevel));
if (g_slist_length (accel_groups) == 0)
{
@@ -8967,15 +9180,56 @@ gtk_widget_buildable_custom_finished (GtkBuildable *buildable,
g_assert (g_slist_length (accel_groups) == 1);
accel_group = g_slist_nth_data (accel_groups, 0);
}
- gtk_widget_add_accelerator (GTK_WIDGET(data->object),
- data->signal,
+ gtk_widget_add_accelerator (GTK_WIDGET (accel_data->object),
+ accel_data->signal,
accel_group,
- data->key,
- data->modifiers,
+ accel_data->key,
+ accel_data->modifiers,
GTK_ACCEL_VISIBLE);
- g_object_unref (data->object);
- g_free (data->signal);
- g_slice_free (AccelGroupParserData, data);
+ g_object_unref (accel_data->object);
+ g_free (accel_data->signal);
+ g_slice_free (AccelGroupParserData, accel_data);
+ }
+ else if (strcmp (tagname, "accessibility") == 0)
+ {
+ a11y_data = (AccessibilitySubParserData*)user_data;
+
+ if (a11y_data->actions)
+ {
+ AtkObject *accessible;
+ AtkAction *action;
+ gint i, n_actions;
+ GSList *l;
+
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (buildable));
+
+ action = ATK_ACTION (accessible);
+ n_actions = atk_action_get_n_actions (action);
+
+ for (l = a11y_data->actions; l; l = l->next)
+ {
+ AtkActionData *action_data = (AtkActionData*)l->data;
+
+ for (i = 0; i < n_actions; i++)
+ if (strcmp (atk_action_get_name (action, i),
+ action_data->action_name) == 0)
+ break;
+
+ if (i < n_actions)
+ atk_action_set_description (action, i,
+ action_data->description);
+ }
+
+ g_slist_foreach (a11y_data->actions, (GFunc)free_action, NULL);
+ g_slist_free (a11y_data->actions);
+ }
+
+ if (a11y_data->relations)
+ g_object_set_qdata (G_OBJECT (buildable), quark_builder_atk_relations,
+ a11y_data->relations);
+
+ g_slice_free (AccessibilitySubParserData, a11y_data);
+
}
}
diff --git a/tests/buildertest.c b/tests/buildertest.c
index 175f273521..98b74b521f 100644
--- a/tests/buildertest.c
+++ b/tests/buildertest.c
@@ -1468,14 +1468,37 @@ test_widget (void)
gchar *buffer3 =
"<interface>"
" <object class=\"GtkWindow\" id=\"window1\">"
- " <accessibility>"
- " <atkproperty name=\"AtkObject::accessible_name\" translatable=\"yes\">Contacts</atkproperty>"
- " <atkrelation target=\"button1\" type=\"labelled-by\"/>"
- " </accessibility>"
+ " <child>"
+ " <object class=\"GtkVBox\" id=\"vbox1\">"
+ " <child>"
+ " <object class=\"GtkLabel\" id=\"label1\">"
+ " <child internal-child=\"accessible\">"
+ " <object class=\"AtkObject\" id=\"a11y-label1\">"
+ " <property name=\"AtkObject::accessible-name\">A Label</property>"
+ " </object>"
+ " </child>"
+ " <accessibility>"
+ " <relation target=\"button1\" type=\"label-for\"/>"
+ " </accessibility>"
+ " </object>"
+ " </child>"
+ " <child>"
+ " <object class=\"GtkButton\" id=\"button1\">"
+ " <accessibility>"
+ " <action action_name=\"click\" description=\"Sliff\"/>"
+ " </accessibility>"
+ " </object>"
+ " </child>"
+ " </object>"
+ " </child>"
" </object>"
- "</interface>";
+ "</interface>";
GtkBuilder *builder;
- GObject *window1, *button1;
+ GObject *window1, *button1, *label1;
+ AtkObject *accessible;
+ AtkRelationSet *relation_set;
+ AtkRelation *relation;
+ char *name;
builder = builder_new_from_string (buffer, -1, NULL);
button1 = gtk_builder_get_object (builder, "button1");
@@ -1493,20 +1516,28 @@ test_widget (void)
g_assert (GTK_WIDGET_RECEIVES_DEFAULT (GTK_WIDGET (button1)));
+ g_object_unref (builder);
+
+ builder = builder_new_from_string (buffer3, -1, NULL);
+
window1 = gtk_builder_get_object (builder, "window1");
+ label1 = gtk_builder_get_object (builder, "label1");
+
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (label1));
+ relation_set = atk_object_ref_relation_set (accessible);
+ g_return_if_fail (atk_relation_set_get_n_relations (relation_set) == 1);
+ relation = atk_relation_set_get_relation (relation_set, 0);
+ g_return_if_fail (relation != NULL);
+ g_return_if_fail (ATK_IS_RELATION (relation));
+ g_return_if_fail (atk_relation_get_relation_type (relation) != ATK_RELATION_LABELLED_BY);
+ g_object_unref (relation_set);
+
+ g_object_get (G_OBJECT (accessible), "accessible-name", &name, NULL);
+ g_return_if_fail (strcmp (name, "A Label") == 0);
+ g_free (name);
+
gtk_widget_destroy (GTK_WIDGET (window1));
g_object_unref (builder);
-
- if (g_test_thorough())
- {
- /* this test currently triggers:
- * "Gtk-WARNING **: <accessibility> is being ignored, see http://bugzilla.gnome.org/show_bug.cgi?id=454653"
- */
- builder = builder_new_from_string (buffer3, -1, NULL);
- window1 = gtk_builder_get_object (builder, "window1");
- gtk_widget_destroy (GTK_WIDGET (window1));
- g_object_unref (builder);
- }
}
static void
@@ -1746,18 +1777,43 @@ test_file (const gchar *filename)
{
GtkBuilder *builder;
GError *error = NULL;
+ GSList *l, *objects;
builder = gtk_builder_new ();
if (!gtk_builder_add_from_file (builder, filename, &error))
{
- g_print ("%s\n", error->message);
+ g_error (error->message);
g_error_free (error);
+ return;
+ }
+
+ objects = gtk_builder_get_objects (builder);
+ for (l = objects; l; l = l->next)
+ {
+ GObject *obj = (GObject*)l->data;
+
+ if (GTK_IS_DIALOG (obj))
+ {
+ int response;
+
+ g_print ("Running dialog %s.\n",
+ gtk_widget_get_name (GTK_WIDGET (obj)));
+ response = gtk_dialog_run (GTK_DIALOG (obj));
+ }
+ else if (GTK_IS_WINDOW (obj))
+ {
+ g_signal_connect (obj, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+ g_print ("Showing %s.\n",
+ gtk_widget_get_name (GTK_WIDGET (obj)));
+ gtk_widget_show_all (GTK_WIDGET (obj));
+ }
}
+ gtk_main ();
+
g_object_unref (builder);
builder = NULL;
-
}
int