Commit f84ff639 authored by eric@webkit.org's avatar eric@webkit.org

2009-10-29 Joanmarie Diggs <joanmarie.diggs@gmail.com>

        Reviewed by Xan Lopez.

        https://bugs.webkit.org/show_bug.cgi?id=25679
        [Gtk] Improve accessibility of focusable lists

        Implements the AtkSelection interface and enables the corresponding
        (and expected) object:selection-changed event.

        * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp:
        (optionFromList):
        (optionFromSelection):
        (atk_selection_interface_init):
        (webkit_accessible_selection_add_selection):
        (webkit_accessible_selection_clear_selection):
        (webkit_accessible_selection_ref_selection):
        (webkit_accessible_selection_get_selection_count):
        (webkit_accessible_selection_is_child_selected):
        (webkit_accessible_selection_remove_selection):
        (webkit_accessible_selection_select_all_selection):
        (GetAtkInterfaceTypeFromWAIType):
        * accessibility/gtk/AXObjectCacheAtk.cpp:
        (AXObjectCache::postPlatformNotification):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@50282 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent f4196d04
2009-10-29 Joanmarie Diggs <joanmarie.diggs@gmail.com>
Reviewed by Xan Lopez.
https://bugs.webkit.org/show_bug.cgi?id=25679
[Gtk] Improve accessibility of focusable lists
Implements the AtkSelection interface and enables the corresponding
(and expected) object:selection-changed event.
* accessibility/gtk/AccessibilityObjectWrapperAtk.cpp:
(optionFromList):
(optionFromSelection):
(atk_selection_interface_init):
(webkit_accessible_selection_add_selection):
(webkit_accessible_selection_clear_selection):
(webkit_accessible_selection_ref_selection):
(webkit_accessible_selection_get_selection_count):
(webkit_accessible_selection_is_child_selected):
(webkit_accessible_selection_remove_selection):
(webkit_accessible_selection_select_all_selection):
(GetAtkInterfaceTypeFromWAIType):
* accessibility/gtk/AXObjectCacheAtk.cpp:
(AXObjectCache::postPlatformNotification):
2009-10-29 Jian Li <jianli@chromium.org>
Reviewed by Darin Adler.
......@@ -43,6 +43,10 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* coreObject, AX
if (!coreObject->isCheckboxOrRadio())
return;
g_signal_emit_by_name(coreObject->wrapper(), "state-change", "checked", coreObject->isChecked());
} else if (notification == AXSelectedChildrenChanged) {
if (!coreObject->isListBox())
return;
g_signal_emit_by_name(coreObject->wrapper(), "selection-changed");
}
}
......
......@@ -35,6 +35,7 @@
#include "AXObjectCache.h"
#include "AccessibilityListBox.h"
#include "AccessibilityListBoxOption.h"
#include "AccessibilityRenderObject.h"
#include "AccessibilityTable.h"
#include "AccessibilityTableCell.h"
......@@ -106,6 +107,11 @@ static AccessibilityObject* core(AtkAction* action)
return core(ATK_OBJECT(action));
}
static AccessibilityObject* core(AtkSelection* selection)
{
return core(ATK_OBJECT(selection));
}
static AccessibilityObject* core(AtkText* text)
{
return core(ATK_OBJECT(text));
......@@ -609,6 +615,145 @@ static void atk_action_interface_init(AtkActionIface* iface)
iface->get_name = webkit_accessible_action_get_name;
}
// Selection (for controls)
static AccessibilityObject* optionFromList(AtkSelection* selection, gint i)
{
AccessibilityObject* coreSelection = core(selection);
if (!coreSelection || i < 0)
return 0;
AccessibilityRenderObject::AccessibilityChildrenVector options = core(selection)->children();
if (i < static_cast<gint>(options.size()))
return options.at(i).get();
return 0;
}
static AccessibilityObject* optionFromSelection(AtkSelection* selection, gint i)
{
// i is the ith selection as opposed to the ith child.
AccessibilityObject* coreSelection = core(selection);
if (!coreSelection || i < 0)
return 0;
AccessibilityRenderObject::AccessibilityChildrenVector selectedItems;
if (coreSelection->isListBox())
static_cast<AccessibilityListBox*>(coreSelection)->selectedChildren(selectedItems);
// TODO: Combo boxes
if (i < static_cast<gint>(selectedItems.size()))
return selectedItems.at(i).get();
return 0;
}
static gboolean webkit_accessible_selection_add_selection(AtkSelection* selection, gint i)
{
AccessibilityObject* option = optionFromList(selection, i);
if (option && core(selection)->isListBox()) {
AccessibilityListBoxOption* listBoxOption = static_cast<AccessibilityListBoxOption*>(option);
listBoxOption->setSelected(true);
return listBoxOption->isSelected();
}
return false;
}
static gboolean webkit_accessible_selection_clear_selection(AtkSelection* selection)
{
AccessibilityObject* coreSelection = core(selection);
if (!coreSelection)
return false;
AccessibilityRenderObject::AccessibilityChildrenVector selectedItems;
if (coreSelection->isListBox()) {
// Set the list of selected items to an empty list; then verify that it worked.
AccessibilityListBox* listBox = static_cast<AccessibilityListBox*>(coreSelection);
listBox->setSelectedChildren(selectedItems);
listBox->selectedChildren(selectedItems);
return selectedItems.size() == 0;
}
return false;
}
static AtkObject* webkit_accessible_selection_ref_selection(AtkSelection* selection, gint i)
{
AccessibilityObject* option = optionFromSelection(selection, i);
if (option) {
AtkObject* child = option->wrapper();
g_object_ref(child);
return child;
}
return 0;
}
static gint webkit_accessible_selection_get_selection_count(AtkSelection* selection)
{
AccessibilityObject* coreSelection = core(selection);
if (coreSelection && coreSelection->isListBox()) {
AccessibilityRenderObject::AccessibilityChildrenVector selectedItems;
static_cast<AccessibilityListBox*>(coreSelection)->selectedChildren(selectedItems);
return static_cast<gint>(selectedItems.size());
}
return 0;
}
static gboolean webkit_accessible_selection_is_child_selected(AtkSelection* selection, gint i)
{
AccessibilityObject* option = optionFromList(selection, i);
if (option && core(selection)->isListBox())
return static_cast<AccessibilityListBoxOption*>(option)->isSelected();
return false;
}
static gboolean webkit_accessible_selection_remove_selection(AtkSelection* selection, gint i)
{
// TODO: This is only getting called if i == 0. What is preventing the rest?
AccessibilityObject* option = optionFromSelection(selection, i);
if (option && core(selection)->isListBox()) {
AccessibilityListBoxOption* listBoxOption = static_cast<AccessibilityListBoxOption*>(option);
listBoxOption->setSelected(false);
return !listBoxOption->isSelected();
}
return false;
}
static gboolean webkit_accessible_selection_select_all_selection(AtkSelection* selection)
{
AccessibilityObject* coreSelection = core(selection);
if (!coreSelection || !coreSelection->isMultiSelect())
return false;
AccessibilityRenderObject::AccessibilityChildrenVector children = coreSelection->children();
if (coreSelection->isListBox()) {
AccessibilityListBox* listBox = static_cast<AccessibilityListBox*>(coreSelection);
listBox->setSelectedChildren(children);
AccessibilityRenderObject::AccessibilityChildrenVector selectedItems;
listBox->selectedChildren(selectedItems);
return selectedItems.size() == children.size();
}
return false;
}
static void atk_selection_interface_init(AtkSelectionIface* iface)
{
iface->add_selection = webkit_accessible_selection_add_selection;
iface->clear_selection = webkit_accessible_selection_clear_selection;
iface->ref_selection = webkit_accessible_selection_ref_selection;
iface->get_selection_count = webkit_accessible_selection_get_selection_count;
iface->is_child_selected = webkit_accessible_selection_is_child_selected;
iface->remove_selection = webkit_accessible_selection_remove_selection;
iface->select_all_selection = webkit_accessible_selection_select_all_selection;
}
// Text
static gchar* webkit_accessible_text_get_text(AtkText* text, gint startOffset, gint endOffset)
......@@ -1177,6 +1322,8 @@ static void atk_table_interface_init(AtkTableIface* iface)
static const GInterfaceInfo AtkInterfacesInitFunctions[] = {
{(GInterfaceInitFunc)atk_action_interface_init,
(GInterfaceFinalizeFunc) NULL, NULL},
{(GInterfaceInitFunc)atk_selection_interface_init,
(GInterfaceFinalizeFunc) NULL, NULL},
{(GInterfaceInitFunc)atk_editable_text_interface_init,
(GInterfaceFinalizeFunc) NULL, NULL},
{(GInterfaceInitFunc)atk_text_interface_init,
......@@ -1191,6 +1338,7 @@ static const GInterfaceInfo AtkInterfacesInitFunctions[] = {
enum WAIType {
WAI_ACTION,
WAI_SELECTION,
WAI_EDITABLE_TEXT,
WAI_TEXT,
WAI_COMPONENT,
......@@ -1203,6 +1351,8 @@ static GType GetAtkInterfaceTypeFromWAIType(WAIType type)
switch (type) {
case WAI_ACTION:
return ATK_TYPE_ACTION;
case WAI_SELECTION:
return ATK_TYPE_SELECTION;
case WAI_EDITABLE_TEXT:
return ATK_TYPE_EDITABLE_TEXT;
case WAI_TEXT:
......@@ -1229,6 +1379,10 @@ static guint16 getInterfaceMaskFromObject(AccessibilityObject* coreObject)
if (!coreObject->actionVerb().isEmpty())
interfaceMask |= 1 << WAI_ACTION;
// Selection
if (coreObject->isListBox())
interfaceMask |= 1 << WAI_SELECTION;
// Text & Editable Text
AccessibilityRole role = coreObject->roleValue();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment