[gtk: 1/2] gtkbuilder: add accessibility role declaration



commit bd986f95342ebf9c98ce87760c13d1bbafb26a7d
Author: Samuel Thibault <samuel thibault ens-lyon org>
Date:   Mon Mar 19 14:11:16 2018 +0100

    gtkbuilder: add accessibility role declaration
    
    This allows to override the role declared to the atk stack.  For
    instance,
    
    <accessibility>
      <role type="static"/>
    </accessibility>
    
    allows to tell the accessibility stack that a label is just a message in
    a message box.
    
    Fixes #109

 demos/gtk-demo/listbox.ui              |  3 ++
 demos/widget-factory/widget-factory.ui |  6 +++
 gtk/gtkwidget.c                        | 46 +++++++++++++++++++++
 testsuite/a11y/label-static.txt        | 75 ++++++++++++++++++++++++++++++++++
 testsuite/a11y/label-static.ui         | 17 ++++++++
 testsuite/gtk/builder.c                | 22 ++++++++++
 6 files changed, 169 insertions(+)
---
diff --git a/demos/gtk-demo/listbox.ui b/demos/gtk-demo/listbox.ui
index 76b49b285d..606a520224 100644
--- a/demos/gtk-demo/listbox.ui
+++ b/demos/gtk-demo/listbox.ui
@@ -98,6 +98,9 @@
             <property name="yalign">0</property>
             <property name="label" translatable="0">Message</property>
             <property name="wrap">1</property>
+            <accessibility>
+              <role type="static"/>
+            </accessibility>
           </object>
           <packing>
             <property name="left-attach">1</property>
diff --git a/demos/widget-factory/widget-factory.ui b/demos/widget-factory/widget-factory.ui
index 8474d08d76..f8ab748010 100644
--- a/demos/widget-factory/widget-factory.ui
+++ b/demos/widget-factory/widget-factory.ui
@@ -3274,6 +3274,9 @@ bad things might happen.</property>
           <object class="GtkLabel">
             <property name="margin">20</property>
             <property name="label" translatable="yes">To free the princess, you have to slay the 
dragon.</property>
+            <accessibility>
+              <role type="static"/>
+            </accessibility>
           </object>
         </child>
       </object>
@@ -3551,6 +3554,9 @@ bad things might happen.</property>
     <child>
       <object class="GtkLabel" id="notebook_info_label">
         <property name="label">No updates at this time</property>
+        <accessibility>
+          <role type="static"/>
+        </accessibility>
       </object>
     </child>
   </object>
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 902894bec8..f78add8c09 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 0000000000..cfffa4c8ed
--- /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
+  <AtkComponent>
+  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
+    <AtkComponent>
+    layer: widget
+    alpha: 1
+    <AtkText>
+    text: Go to the GTK+ website or >google it
+    character count: 36
+    caret offset: 0
+    default attributes: bg-color: <omitted>
+                        bg-full-height: 0
+                        direction: <omitted>
+                        editable: false
+                        family-name: <omitted>
+                        fg-color: <omitted>
+                        indent: 0
+                        invisible: false
+                        justification: left
+                        language: <omitted>
+                        left-margin: 0
+                        pixels-above-lines: 0
+                        pixels-below-lines: 0
+                        pixels-inside-wrap: 0
+                        right-margin: 0
+                        rise: 0
+                        scale: 1
+                        size: <omitted>
+                        stretch: <omitted>
+                        strikethrough: false
+                        style: <omitted>
+                        underline: none
+                        variant: <omitted>
+                        weight: <omitted>
+                        wrap-mode: word
+    <AtkHypertext>
+      <AtkHyperlink>
+      start index: 10
+      end index: 22
+      anchors: http://www.gtk.org
+      <AtkHyperlink>
+      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
+      <AtkHyperlinkImpl>
+        <AtkHyperlink>
+        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
+      <AtkHyperlinkImpl>
+        <AtkHyperlink>
+        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 0000000000..1e478c0b63
--- /dev/null
+++ b/testsuite/a11y/label-static.ui
@@ -0,0 +1,17 @@
+
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkWindow" id="window1">
+    <property name="can_focus">False</property>
+    <property name="type">popup</property>
+    <child>
+      <object class="GtkLabel" id="label1">
+        <property name="label">Go to the &lt;a href="http://www.gtk.org"; title="&lt;i&gt;Our&lt;/i&gt; 
website"&gt;GTK+ website&lt;/a&gt; or &lt;small&gt;&gt;&lt;a href="http://www.google.com"&gt;google 
it&lt;/a&gt;&lt;/small&gt;</property>
+        <property name="use-markup">True</property>
+        <accessibility>
+          <role type="static"/>
+        </accessibility>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/testsuite/gtk/builder.c b/testsuite/gtk/builder.c
index 9d5fb822f3..e662570a26 100644
--- a/testsuite/gtk/builder.c
+++ b/testsuite/gtk/builder.c
@@ -1520,6 +1520,20 @@ test_widget (void)
     "    </child>"
     "  </object>"
     "</interface>";
+  const gchar *buffer4 =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkLabel\" id=\"label1\">"
+    "         <property name=\"label\">Thelabel</property>"
+    "         <property name=\"can_focus\">False</property>"
+    "         <accessibility>"
+    "            <role type=\"static\"/>"
+    "         </accessibility>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+   "</interface>";
   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


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