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. 20 To free the princess, you have to slay the dragon. + + + @@ -3551,6 +3554,9 @@ bad things might happen. No updates at this time + + + 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 @@ + + + + + False + popup + + + Go to the <a href="http://www.gtk.org" title="<i>Our</i> website">GTK+ website</a> or <small>><a href="http://www.google.com">google it</a></small> + True + + + + + + + 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