Hey all. As some of you know, I have been threatening to do this work for a while now, but other things keep bubbling to the top of my priority list. :-/ I'm really sorry about that. Rather than wait until I have everything done, I'm attaching some changes which greatly improve the accessibility of Anaconda for users who are blind and are, insofar as the code goes, pretty trivial. What the patches do is: 1. Set accessible relations between labels and the things being labeled. As a result, instead of Orca saying things like "text" and leaving the user to guess what text he/she should type, Orca now says "foo: text" and the user knows to type a value for foo. This was also done for labels associated with a group of widgets so that the user has some context when navigating. Note that there are a couple of ways you can tackle this: Add accessibility-specific code to set the relations or just set the mnemonic widget property and let Gtk do it for you automatically. I wound up doing the latter based on the suggestion of Benjamin Otte (Gtk+ developer). 2. Change initial focus for each* installer step to the likely widget of interest. As a result, instead of Orca merely saying "Next" and leaving the user to wonder what step he/she is on and what is required in order to proceed, Orca now automatically presents the widget and associated context for each new screen/step that appears ("Step foobar, you must enter a foo and a bar, foo text"). * Well, most steps. More work is needed here. 3. Because the change in step 2 in some cases broke the "Just press Return for the 'Next' button" functionality, make the 'Next' button the default. That brings back the "Just press Return" functionality so the end user experience for everyone else should still be the same as it currently is. If you have any questions, please let me know. Thanks, take care, and again my apologies for the delay. --joanie (Orca project lead)
>From e451c306dd3a6383226c7567bcf1151b24e4da1e Mon Sep 17 00:00:00 2001 From: Joanmarie Diggs <jdiggs@xxxxxxxxxx> Date: Sun, 22 Apr 2012 11:37:43 -0400 Subject: [PATCH 4/5] Establish ATK_RELATION_LABEL_FOR for accessibility --- data/ui/account.glade | 1 + data/ui/autopart.glade | 1 + data/ui/cleardisks.glade | 6 +++--- data/ui/filter.glade | 14 ++++++++++++++ data/ui/iscsi-dialogs.glade | 9 +++++++++ data/ui/network.glade | 2 ++ pyanaconda/iw/cleardisks_gui.py | 4 ++++ pyanaconda/iw/language_gui.py | 3 +++ pyanaconda/iw/network_gui.py | 1 + 9 files changed, 38 insertions(+), 3 deletions(-) diff --git a/data/ui/account.glade b/data/ui/account.glade index c93fcdd..d2048a9 100644 --- a/data/ui/account.glade +++ b/data/ui/account.glade @@ -89,6 +89,7 @@ <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">table1</property> </widget> <packing> <property name="padding">0</property> diff --git a/data/ui/autopart.glade b/data/ui/autopart.glade index b1346f6..5d8d586 100644 --- a/data/ui/autopart.glade +++ b/data/ui/autopart.glade @@ -47,6 +47,7 @@ <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">parttypeTable</property> </widget> <packing> <property name="left_attach">0</property> diff --git a/data/ui/cleardisks.glade b/data/ui/cleardisks.glade index 5fb86e5..8442686 100644 --- a/data/ui/cleardisks.glade +++ b/data/ui/cleardisks.glade @@ -44,6 +44,7 @@ <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">hbox2</property> </widget> <packing> <property name="padding">0</property> @@ -65,7 +66,7 @@ <property name="spacing">0</property> <child> - <widget class="GtkLabel" id="label4"> + <widget class="GtkLabel" id="leftScrollLabel"> <property name="visible">True</property> <property name="label" translatable="yes"><b>Data Storage Devices</b> (to be mounted only)</property> <property name="use_underline">False</property> @@ -151,7 +152,6 @@ <property name="can_focus">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> <property name="focus_on_click">True</property> - <child> <widget class="GtkImage" id="image2"> <property name="visible">True</property> @@ -180,7 +180,7 @@ <property name="spacing">0</property> <child> - <widget class="GtkLabel" id="label5"> + <widget class="GtkLabel" id="rightScrollLabel"> <property name="visible">True</property> <property name="label" translatable="yes"><b>Install Target Devices</b></property> <property name="use_underline">False</property> diff --git a/data/ui/filter.glade b/data/ui/filter.glade index c4b301f..a6e4e41 100644 --- a/data/ui/filter.glade +++ b/data/ui/filter.glade @@ -43,6 +43,7 @@ <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">vbox</property> </widget> <packing> <property name="padding">0</property> @@ -174,6 +175,7 @@ <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">mpathFilterBy</property> </widget> <packing> <property name="padding">0</property> @@ -231,6 +233,7 @@ Identifier</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">mpathInterconnectEntry</property> </widget> <packing> <property name="padding">0</property> @@ -305,6 +308,7 @@ Identifier</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">mpathVendorEntry</property> </widget> <packing> <property name="padding">0</property> @@ -379,6 +383,7 @@ Identifier</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">mpathIDEntry</property> </widget> <packing> <property name="padding">0</property> @@ -527,6 +532,7 @@ Identifier</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">otherFilterBy</property> </widget> <packing> <property name="padding">0</property> @@ -584,6 +590,7 @@ Identifier</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">otherInterconnectEntry</property> </widget> <packing> <property name="padding">0</property> @@ -658,6 +665,7 @@ Identifier</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">otherVendorEntry</property> </widget> <packing> <property name="padding">0</property> @@ -732,6 +740,7 @@ Identifier</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">otherIDEntry</property> </widget> <packing> <property name="padding">0</property> @@ -880,6 +889,7 @@ Identifier</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">searchFilterBy</property> </widget> <packing> <property name="padding">0</property> @@ -936,6 +946,7 @@ Target Identifier</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">searchPortEntry</property> </widget> <packing> <property name="padding">0</property> @@ -981,6 +992,7 @@ Target Identifier</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">searchTargetEntry</property> </widget> <packing> <property name="padding">0</property> @@ -1026,6 +1038,7 @@ Target Identifier</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">searchLUNEntry</property> </widget> <packing> <property name="padding">0</property> @@ -1106,6 +1119,7 @@ Target Identifier</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">searchIDEntry</property> </widget> <packing> <property name="padding">0</property> diff --git a/data/ui/iscsi-dialogs.glade b/data/ui/iscsi-dialogs.glade index 591cbf1..c88b711 100644 --- a/data/ui/iscsi-dialogs.glade +++ b/data/ui/iscsi-dialogs.glade @@ -18,6 +18,7 @@ <property name="visible">True</property> <property name="label" translatable="yes">To use iSCSI disks, you must provide the address of your iSCSI target and the iSCSI initiator name you've configured for your host.</property> <property name="wrap">True</property> + <property name="mnemonic_widget">table1</property> </widget> <packing> <property name="expand">False</property> @@ -34,6 +35,7 @@ <property name="visible">True</property> <property name="xalign">0</property> <property name="label" translatable="yes">Target IP Address:</property> + <property name="mnemonic_widget">target_ip</property> </widget> <packing> <property name="x_options">GTK_FILL</property> @@ -44,6 +46,7 @@ <property name="visible">True</property> <property name="xalign">0</property> <property name="label" translatable="yes">iSCSI Initiator Name:</property> + <property name="mnemonic_widget">initiator</property> </widget> <packing> <property name="top_attach">1</property> @@ -111,6 +114,7 @@ <widget class="GtkLabel" id="username_label"> <property name="xalign">0</property> <property name="label" translatable="yes">CHAP Username:</property> + <property name="mnemonic_widget">username_entry</property> </widget> <packing> <property name="x_options">GTK_FILL</property> @@ -120,6 +124,7 @@ <widget class="GtkLabel" id="password_label"> <property name="xalign">0</property> <property name="label" translatable="yes">CHAP Password:</property> + <property name="mnemonic_widget">password_entry</property> </widget> <packing> <property name="top_attach">1</property> @@ -154,6 +159,7 @@ <widget class="GtkLabel" id="r_username_label"> <property name="xalign">0</property> <property name="label" translatable="yes">Reverse CHAP Username:</property> + <property name="mnemonic_widget">r_username_entry</property> </widget> <packing> <property name="top_attach">2</property> @@ -165,6 +171,7 @@ <widget class="GtkLabel" id="r_password_label"> <property name="xalign">0</property> <property name="label" translatable="yes">Reverse CHAP Password:</property> + <property name="mnemonic_widget">r_password_entry</property> </widget> <packing> <property name="top_attach">3</property> @@ -442,6 +449,7 @@ <widget class="GtkLabel" id="label_success"> <property name="xalign">0</property> <property name="label" translatable="yes">Successfully logged in and attached the following nodes:</property> + <property name="mnemonic_widget">text_success</property> </widget> <packing> <property name="position">1</property> @@ -477,6 +485,7 @@ <widget class="GtkLabel" id="label_fail"> <property name="xalign">0</property> <property name="label" translatable="yes">iSCSI login has failed for the following nodes:</property> + <property name="mnemonic_widget">text_fail</property> </widget> <packing> <property name="position">4</property> diff --git a/data/ui/network.glade b/data/ui/network.glade index fc4c86b..0ee711d 100644 --- a/data/ui/network.glade +++ b/data/ui/network.glade @@ -89,6 +89,7 @@ <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">table1</property> </widget> <packing> <property name="padding">0</property> @@ -145,6 +146,7 @@ <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">hostnameEntry</property> </widget> <packing> <property name="left_attach">0</property> diff --git a/pyanaconda/iw/cleardisks_gui.py b/pyanaconda/iw/cleardisks_gui.py index 9ab4799..3e58ce4 100644 --- a/pyanaconda/iw/cleardisks_gui.py +++ b/pyanaconda/iw/cleardisks_gui.py @@ -89,6 +89,8 @@ class ClearDisksWindow (InstallWindow): (xml, self.vbox) = gui.getGladeWidget("cleardisks.glade", "vbox") self.leftScroll = xml.get_widget("leftScroll") self.rightScroll = xml.get_widget("rightScroll") + self.leftScrollLabel = xml.get_widget("leftScrollLabel") + self.rightScrollLabel = xml.get_widget("rightScrollLabel") self.addButton = xml.get_widget("addButton") self.removeButton = xml.get_widget("removeButton") self.installTargetImage = xml.get_widget("installTargetImage") @@ -124,6 +126,7 @@ class ClearDisksWindow (InstallWindow): self.leftFilteredModel.set_visible_func(lambda model, iter, view: model.get_value(iter, self.leftVisible), self.leftTreeView) self.leftScroll.add(self.leftTreeView) + self.leftScrollLabel.set_mnemonic_widget(self.leftTreeView) self.leftDS = DeviceSelector(self.store, self.leftSortedModel, self.leftTreeView, visible=self.leftVisible, @@ -143,6 +146,7 @@ class ClearDisksWindow (InstallWindow): self.rightFilteredModel.set_visible_func(lambda model, iter, view: model.get_value(iter, self.rightVisible), self.rightTreeView) self.rightScroll.add(self.rightTreeView) + self.rightScrollLabel.set_mnemonic_widget(self.rightTreeView) self.rightDS = DeviceSelector(self.store, self.rightSortedModel, self.rightTreeView, visible=self.rightVisible, diff --git a/pyanaconda/iw/language_gui.py b/pyanaconda/iw/language_gui.py index 75fa66b..64e5f24 100644 --- a/pyanaconda/iw/language_gui.py +++ b/pyanaconda/iw/language_gui.py @@ -108,6 +108,9 @@ class LanguageWindow (InstallWindow): self.listView.append_column(col) self.listView.set_property("headers-visible", False) + # Establishes ATK_RELATION_LABEL_FOR for accessibility. + label.set_mnemonic_widget(self.listView) + current = self.instLang.getLangName(self.instLang.instLang) iter = self.listStore.get_iter_first() while iter: diff --git a/pyanaconda/iw/network_gui.py b/pyanaconda/iw/network_gui.py index a7bf321..ada8cd9 100644 --- a/pyanaconda/iw/network_gui.py +++ b/pyanaconda/iw/network_gui.py @@ -230,6 +230,7 @@ def selectSSIDsDialog(devssids): combo = gtk.combo_box_new_text() for ssid in ssids: combo.append_text(ssid) + label.set_mnemonic_widget(combo) table.attach(combo, 1, 2, i, i+1, gtk.FILL, gtk.FILL) combo.set_active(0) combos[dev] = combo -- 1.7.10.4
>From 17f8a45b02e7b4c64a7ac8acbacc2cf9a24f8abd Mon Sep 17 00:00:00 2001 From: Joanmarie Diggs <jdiggs@xxxxxxxxxx> Date: Sun, 22 Apr 2012 19:10:59 -0400 Subject: [PATCH 5/5] Move focus to the widget of interest; make Next default button --- pyanaconda/iw/filter_type.py | 3 +++ pyanaconda/iw/kbd_gui.py | 5 ++++- pyanaconda/iw/language_gui.py | 6 ++++++ pyanaconda/iw/pixmapRadioButtonGroup_gui.py | 8 +++++++- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/pyanaconda/iw/filter_type.py b/pyanaconda/iw/filter_type.py index 9f82079..83ab593 100644 --- a/pyanaconda/iw/filter_type.py +++ b/pyanaconda/iw/filter_type.py @@ -83,3 +83,6 @@ class FilterTypeWindow(InstallWindow): self.buttonGroup.setCurrent("complex") return vbox + + def focus(self): + self.buttonGroup.grabFocus() diff --git a/pyanaconda/iw/kbd_gui.py b/pyanaconda/iw/kbd_gui.py index a73588d..91d9de4 100644 --- a/pyanaconda/iw/kbd_gui.py +++ b/pyanaconda/iw/kbd_gui.py @@ -31,7 +31,7 @@ class KeyboardWindow(InstallWindow, installKeyboardWindow): InstallWindow.__init__(self, ics) installKeyboardWindow.__init__(self) - ics.cw.mainxml.get_widget("nextButton").grab_focus() + ics.cw.mainxml.get_widget("nextButton").grab_default() def getNext(self): installKeyboardWindow.getNext(self) @@ -43,3 +43,6 @@ class KeyboardWindow(InstallWindow, installKeyboardWindow): self.modelView.connect("select-cursor-row", lambda widget, vbox=vbox: self.ics.setGrabNext(1)) return vbox + + def focus(self): + self.modelView.grab_focus() diff --git a/pyanaconda/iw/language_gui.py b/pyanaconda/iw/language_gui.py index 64e5f24..7274e06 100644 --- a/pyanaconda/iw/language_gui.py +++ b/pyanaconda/iw/language_gui.py @@ -35,6 +35,8 @@ class LanguageWindow (InstallWindow): def __init__ (self, ics): InstallWindow.__init__ (self, ics) + ics.cw.mainxml.get_widget("nextButton").grab_default() + def getNext (self): anaconda = self.ics.getICW().anaconda @@ -121,6 +123,7 @@ class LanguageWindow (InstallWindow): break iter = self.listStore.iter_next(iter) self.listView.connect("size-allocate", self.listScroll) + self.listView.connect("select-cursor-row", lambda widget, vbox=mainBox: self.ics.setGrabNext(1)) sw = gtk.ScrolledWindow () sw.set_border_width (5) @@ -136,3 +139,6 @@ class LanguageWindow (InstallWindow): self.running = 1 return mainBox + + def focus(self): + self.listView.grab_focus() diff --git a/pyanaconda/iw/pixmapRadioButtonGroup_gui.py b/pyanaconda/iw/pixmapRadioButtonGroup_gui.py index 308a13f..4eeafdf 100644 --- a/pyanaconda/iw/pixmapRadioButtonGroup_gui.py +++ b/pyanaconda/iw/pixmapRadioButtonGroup_gui.py @@ -118,7 +118,13 @@ class pixmapRadioButtonGroup: def setToggleCallback(self, cb): self.togglecb = cb - + + def grabFocus(self): + for b in self.buttonToEntry.keys(): + if b.get_active(): + b.grab_focus() + return + # render resulting list, returns a box you can pack # # call this after adding all parents and nodes -- 1.7.10.4
>From 46567fa20340610b4182129885c8e293feffa8dd Mon Sep 17 00:00:00 2001 From: Joanmarie Diggs <jdiggs@xxxxxxxxxx> Date: Thu, 19 Apr 2012 14:23:28 -0400 Subject: [PATCH] Establish ATK_RELATION_LABEL_FOR for accessibility Uses the mnemonic_widget property to establish a needed AtkRelation for screen reader accessibility. --- src/system-config-date.glade | 1 + 1 file changed, 1 insertion(+) diff --git a/src/system-config-date.glade b/src/system-config-date.glade index f49eaf5..e7991bb 100644 --- a/src/system-config-date.glade +++ b/src/system-config-date.glade @@ -850,6 +850,7 @@ <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> + <property name="mnemonic_widget">tz</property> </widget> <packing> <property name="padding">0</property> -- 1.7.10.4
Index: src/keyboard_gui.py =================================================================== --- src/keyboard_gui.py (revision 652) +++ src/keyboard_gui.py (working copy) @@ -178,6 +178,9 @@ self.modelView.set_enable_search(True) self.modelView.set_search_column(1) + # Establishes ATK_RELATION_LABEL_FOR for accessibility. + msgLabel.set_mnemonic_widget(self.modelView) + selection = self.modelView.get_selection() selection.connect("changed", self.select_row)
_______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list