diff --git a/demos/gtk-demo/listbox.ui b/demos/gtk-demo/listbox.ui
index 76b49b285d4bf99e73dd523f027e786efa0d39de..606a5202246cbd5a23f936238068989b9574ca9a 100644
--- a/demos/gtk-demo/listbox.ui
+++ b/demos/gtk-demo/listbox.ui
@@ -98,6 +98,9 @@
0
Message
1
+
+
+
1
diff --git a/demos/widget-factory/widget-factory.ui b/demos/widget-factory/widget-factory.ui
index 8474d08d76bcba73e313b868e924ea1962d9d8e3..f8ab748010096f15ad45ca5df960f992f5223918 100644
--- a/demos/widget-factory/widget-factory.ui
+++ b/demos/widget-factory/widget-factory.ui
@@ -3274,6 +3274,9 @@ bad things might happen.
@@ -3551,6 +3554,9 @@ bad things might happen.
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 902894bec8a19b7ebc7a2273a018a00b416a28b9..f78add8c09111243e5153d7e4897907a0f4222b2 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -10685,6 +10685,7 @@ typedef struct
GtkBuilder *builder;
GSList *actions;
GSList *relations;
+ AtkRole role;
} AccessibilitySubParserData;
static void
@@ -10764,6 +10765,45 @@ accessibility_start_element (GMarkupParseContext *context,
data->actions = g_slist_prepend (data->actions, action);
}
+ else if (strcmp (element_name, "role") == 0)
+ {
+ const gchar *type;
+ AtkRole role;
+
+ if (!_gtk_builder_check_parent (data->builder, context, "accessibility", error))
+ return;
+
+ if (data->role != ATK_ROLE_INVALID)
+ {
+ g_set_error (error,
+ GTK_BUILDER_ERROR,
+ GTK_BUILDER_ERROR_INVALID_VALUE,
+ "Duplicate accessibility role definition");
+ _gtk_builder_prefix_error (data->builder, context, error);
+ return;
+ }
+
+ if (!g_markup_collect_attributes (element_name, names, values, error,
+ G_MARKUP_COLLECT_STRING, "type", &type,
+ G_MARKUP_COLLECT_INVALID))
+ {
+ _gtk_builder_prefix_error (data->builder, context, error);
+ return;
+ }
+
+ role = atk_role_for_name (type);
+ if (role == ATK_ROLE_INVALID)
+ {
+ g_set_error (error,
+ GTK_BUILDER_ERROR,
+ GTK_BUILDER_ERROR_INVALID_VALUE,
+ "No such role type: '%s'", type);
+ _gtk_builder_prefix_error (data->builder, context, error);
+ return;
+ }
+
+ data->role = role;
+ }
else if (strcmp (element_name, "accessibility") == 0)
{
if (!_gtk_builder_check_parent (data->builder, context, "object", error))
@@ -11108,6 +11148,12 @@ gtk_widget_buildable_custom_finished (GtkBuildable *buildable,
g_object_set_qdata (G_OBJECT (buildable), quark_builder_atk_relations,
a11y_data->relations);
+ if (a11y_data->role != ATK_ROLE_INVALID)
+ {
+ AtkObject *accessible = gtk_widget_get_accessible (GTK_WIDGET (buildable));
+ atk_object_set_role (accessible, a11y_data->role);
+ }
+
g_slice_free (AccessibilitySubParserData, a11y_data);
}
else if (strcmp (tagname, "style") == 0)
diff --git a/testsuite/a11y/label-static.txt b/testsuite/a11y/label-static.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cfffa4c8edb985bcf3b82706802ddf2f6d23f654
--- /dev/null
+++ b/testsuite/a11y/label-static.txt
@@ -0,0 +1,75 @@
+window1
+ "window"
+ index: 0
+ state: enabled resizable sensitive showing visible
+ toolkit: gtk
+ window-type: normal
+
+ layer: window
+ alpha: 1
+ label1
+ "static"
+ parent: window1
+ index: 0
+ name: Go to the GTK+ website or >google it
+ state: enabled focusable multi-line sensitive has-tooltip
+ toolkit: gtk
+
+ layer: widget
+ alpha: 1
+
+ text: Go to the GTK+ website or >google it
+ character count: 36
+ caret offset: 0
+ default attributes: bg-color:
+ bg-full-height: 0
+ direction:
+ editable: false
+ family-name:
+ fg-color:
+ indent: 0
+ invisible: false
+ justification: left
+ language:
+ left-margin: 0
+ pixels-above-lines: 0
+ pixels-below-lines: 0
+ pixels-inside-wrap: 0
+ right-margin: 0
+ rise: 0
+ scale: 1
+ size:
+ stretch:
+ strikethrough: false
+ style:
+ underline: none
+ variant:
+ weight:
+ wrap-mode: word
+
+
+ start index: 10
+ end index: 22
+ anchors: http://www.gtk.org
+
+ start index: 27
+ end index: 36
+ anchors: http://www.google.com
+ unnamed-GtkLabelAccessibleLinkImpl-0
+ "link"
+ parent: label1
+ state: enabled focusable multi-line sensitive has-tooltip
+
+
+ start index: 10
+ end index: 22
+ anchors: http://www.gtk.org
+ unnamed-GtkLabelAccessibleLinkImpl-1
+ "link"
+ parent: label1
+ state: enabled focusable multi-line sensitive has-tooltip
+
+
+ start index: 27
+ end index: 36
+ anchors: http://www.google.com
diff --git a/testsuite/a11y/label-static.ui b/testsuite/a11y/label-static.ui
new file mode 100644
index 0000000000000000000000000000000000000000..1e478c0b637dccfea73ce97645adfe00bc78ed43
--- /dev/null
+++ b/testsuite/a11y/label-static.ui
@@ -0,0 +1,17 @@
+
+
+
+
+
diff --git a/testsuite/gtk/builder.c b/testsuite/gtk/builder.c
index 9d5fb822f363bb16a78ed87371401ff8ecda9d98..e662570a2672fb66229dafe87be1cbc5a6a2a564 100644
--- a/testsuite/gtk/builder.c
+++ b/testsuite/gtk/builder.c
@@ -1520,6 +1520,20 @@ test_widget (void)
" "
" "
"";
+ const gchar *buffer4 =
+ ""
+ " "
+ " "
+ " "
+ " Thelabel"
+ " False"
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ "";
GtkBuilder *builder;
GObject *window1, *button1, *label1;
AtkObject *accessible;
@@ -1565,6 +1579,14 @@ test_widget (void)
gtk_widget_destroy (GTK_WIDGET (window1));
g_object_unref (builder);
+
+ builder = builder_new_from_string (buffer4, -1, NULL);
+ label1 = gtk_builder_get_object (builder, "label1");
+
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (label1));
+ g_assert (atk_object_get_role (accessible) == ATK_ROLE_STATIC);
+
+ g_object_unref (builder);
}
static void