Setting accessible description on an image?

I’m trying to make a GTK application more accessible. I’ve managed to set accessible names/descriptions for list boxes and Orca reads them, but I can’t get it to read out the description of an image.

The .ui file has a Gtk.Grid that contains the following XML:

        …
        <child>
          <object class="GtkImage" id="conversation_image">
            <property name="no-show-all">1</property>
            <property name="halign">end</property>
            <property name="valign">center</property>
            <property name="margin-end">6</property>
            <property name="pixel-size">12</property>
            <property name="icon-name">cawbird-conversation-symbolic</property>
            <child internal-child="accessible">
              <object class="AtkObject" id="conversation_image-atkobject">
                <property name="AtkObject::accessible-name" translatable="yes">Reply</property>
                <property name="AtkObject::accessible-description" translatable="yes">Reply</property>
              </object>
            </child>
            <style>
              <class name="dim-label"/>
            </style>
          </object>
          <packing>
            <property name="left-attach">4</property>
            <property name="top-attach">0</property>
          </packing>
        </child>
        …

Accerciser and the GTK inspector can see the description, but Accerciser says there’s no description under the “Image” section.

What am I missing? How do I make Orca read out the description for an image?

Thanks.

1 Like

Basically by default Orca will read what’s currently focused, and what’s related to it (e.g. I’ll read the labelled-by or description-for widget as well, if there’s such a relation); but it won’t read just everything around, that would most likely just be noise and way too much information.

Actually, what you have should be just fine; but if you can’t focus that image, and that image isn’t a label/description for the focus, it won’t present it. Try to make your image focusable, and then it should be spoken. But only do so if it makes sense, not for the sheer thrill of Orca speaking.

Also, note that Orca does not always speak the description of a widget, if it has something else to present. This depends on configuration, and situation. E.g., in several cases if you have an a11y name and an a11y description, only the name might be read out. There’s quite some involved reasons and heuristics, but basically it does what users want (or tries to at any rate).

Finally, note that you might want to try out your UI with “speak object under the mouse” enabled, which allows you to get Orca to announce the object under the mouse when you move it around. Then, you’ll likely see that your image has the right info available to Orca, and that if you need it to be announced in some other situation the problem lies somewhere else.

As an example, a dummy app.

a11yimg.ui:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <child type="titlebar">
      <placeholder/>
    </child>
    <child>
      <object class="GtkBox">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="spacing">6</property>
        <child>
          <object class="GtkButton">
            <property name="label" translatable="yes">Action</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="can_default">True</property>
            <property name="has_default">True</property>
            <property name="receives_default">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkImage">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="can_default">True</property>
            <property name="icon_name">dialog-ok</property>
            <property name="icon_size">6</property>
            <child internal-child="accessible">
              <object class="AtkObject">
                <property name="AtkObject::accessible-name" translatable="yes">All's good</property>
                <property name="AtkObject::accessible-description" translatable="yes">This image should be readily described by Orca</property>
              </object>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkImage">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="icon_name">dialog-error</property>
            <property name="icon_size">6</property>
            <child internal-child="accessible">
              <object class="AtkObject">
                <property name="AtkObject::accessible-name" translatable="yes">Error image</property>
                <property name="AtkObject::accessible-description" translatable="yes">This image shuold work as well, but cannot get keyboard focus</property>
              </object>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

a11yimg.py:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk


builder = Gtk.Builder()
builder.add_from_file('a11yimg.ui')
win = builder.get_object('window1')
win.connect('destroy', Gtk.main_quit)
win.show_all()

Gtk.main()

You should have 3 widgets: 1 button, and 2 images. You can Tab through the button and the first image, and you should get nice feedback. But the third isn’t, because you can’t reach it with the

Also note that while it’s wonderful you try and get your application accessible, you should probably avoid making involved changes (e.g. anything past proper labeling, description, relations and keyboard navigation) without actually consulting with real a11y users. Often enough some “improvements” made with the best intentions make the app less usable, because it interacts badly with how users actually do interact with applications through ATs like Orca. One of such misguided “improvements” is trying to get the screen reader to speak a lot so it feels well covered for the casual tryout, but which leads to mostly noise to the hears of regular users, lowering productivity and augmenting stress. In this instance, usually it’s best for the screen reader to say the least possible amount of things that still carry the relevant information.
It’s similar to UX: a (possibly not well chosen) example could be not to try and rework how a button works because you think you had a good idea. You might have, but in the end you need to weigh a lot of things, and think on how people use the UI. Maybe changing the button semantics would be problematic just because it’d be different, in which case maybe it warrants a break in habits, or maybe it doesn’t.

Anyway, with such a11y questions (and all of them) you might want to hit the Orca mailing list as well, as it might host most of the people that might have knowledge about these questions.

Thanks for the info. I’ll try it out and see what I can integrate. And I’ll try the “speak under mouse” setting as well.

I have been considering the “over-speaking” issue, and I’ve been asking the screen-reader using part of my community what works best. In this case, the icons are status indicators, so it’s between it being more helpful to know the status (liked, part of a thread, etc) and having to do a lot more clicking around (for this specific message, bring up the actions list and tab through each toggle button to see the status from there - which covers most cases, and the others just need more clicks).