diff options
Diffstat (limited to 'Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp')
-rw-r--r-- | Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp | 72 |
1 files changed, 53 insertions, 19 deletions
diff --git a/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp b/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp index c341a2d..0701ece 100644 --- a/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp +++ b/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp @@ -42,34 +42,67 @@ void AXObjectCache::attachWrapper(AccessibilityObject* obj) g_object_unref(atkObj); } -static void notifyChildrenSelectionChange(AccessibilityObject* object) +static AccessibilityObject* getListObject(AccessibilityObject* object) { - // This static variable is needed to keep track of the old focused - // object as per previous calls to this function, in order to - // properly decide whether to emit some signals or not. - static RefPtr<AccessibilityObject> oldFocusedObject = 0; + // Only list boxes and menu lists supported so far. + if (!object->isListBox() && !object->isMenuList()) + return 0; + + // For list boxes the list object is just itself. + if (object->isListBox()) + return object; + + // For menu lists we need to return the first accessible child, + // with role MenuListPopupRole, since that's the one holding the list + // of items with role MenuListOptionRole. + AccessibilityObject::AccessibilityChildrenVector children = object->children(); + if (!children.size()) + return 0; + + AccessibilityObject* listObject = children.at(0).get(); + if (!listObject->isMenuListPopup()) + return 0; + + return listObject; +} - // Only list boxes supported so far. - if (!object || !object->isListBox()) +static void notifyChildrenSelectionChange(AccessibilityObject* object) +{ + // This static variables are needed to keep track of the old + // focused object and its associated list object, as per previous + // calls to this function, in order to properly decide whether to + // emit some signals or not. + DEFINE_STATIC_LOCAL(RefPtr<AccessibilityObject>, oldListObject, ()); + DEFINE_STATIC_LOCAL(RefPtr<AccessibilityObject>, oldFocusedObject, ()); + + // Only list boxes and menu lists supported so far. + if (!object || !(object->isListBox() || object->isMenuList())) return; // Emit signal from the listbox's point of view first. g_signal_emit_by_name(object->wrapper(), "selection-changed"); // Find the item where the selection change was triggered from. - AccessibilityObject::AccessibilityChildrenVector items = object->children(); SelectElement* select = toSelectElement(static_cast<Element*>(object->node())); if (!select) return; int changedItemIndex = select->activeSelectionStartListIndex(); + + AccessibilityObject* listObject = getListObject(object); + if (!listObject) { + oldListObject = 0; + return; + } + + AccessibilityObject::AccessibilityChildrenVector items = listObject->children(); if (changedItemIndex < 0 || changedItemIndex >= static_cast<int>(items.size())) return; AccessibilityObject* item = items.at(changedItemIndex).get(); - // Ensure the oldFocusedObject belongs to the same document that - // the current item so further comparisons make sense. Otherwise, - // just reset oldFocusedObject so it won't be taken into account. - if (item && oldFocusedObject && item->document() != oldFocusedObject->document()) + // Ensure the current list object is the same than the old one so + // further comparisons make sense. Otherwise, just reset + // oldFocusedObject so it won't be taken into account. + if (oldListObject != listObject) oldFocusedObject = 0; AtkObject* axItem = item ? item->wrapper() : 0; @@ -89,7 +122,8 @@ static void notifyChildrenSelectionChange(AccessibilityObject* object) g_signal_emit_by_name(axItem, "state-change", "focused", isSelected); } - // Update pointer to the previously focused object. + // Update pointers to the previously involved objects. + oldListObject = listObject; oldFocusedObject = item; } @@ -103,13 +137,13 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* coreObject, AX if (!coreObject->isCheckboxOrRadio()) return; g_signal_emit_by_name(axObject, "state-change", "checked", coreObject->isChecked()); - } else if (notification == AXMenuListValueChanged) { - if (!coreObject->isMenuList()) - return; - g_signal_emit_by_name(axObject, "focus-event", true); - g_signal_emit_by_name(axObject, "state-change", "focused", true); - } else if (notification == AXSelectedChildrenChanged) + } else if (notification == AXSelectedChildrenChanged || notification == AXMenuListValueChanged) { + if (notification == AXMenuListValueChanged && coreObject->isMenuList()) { + g_signal_emit_by_name(axObject, "focus-event", true); + g_signal_emit_by_name(axObject, "state-change", "focused", true); + } notifyChildrenSelectionChange(coreObject); + } } static void emitTextChanged(AccessibilityRenderObject* object, AXObjectCache::AXTextChange textChange, unsigned offset, unsigned count) |