Index: content/browser/accessibility/browser_accessibility_manager.cc |
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc |
index 84c2ec0ef056f5e4416e8332ae710f787aa7e28c..a6963b55e8f0fd3415368e4cfc77d40f01bd300a 100644 |
--- a/content/browser/accessibility/browser_accessibility_manager.cc |
+++ b/content/browser/accessibility/browser_accessibility_manager.cc |
@@ -387,18 +387,12 @@ |
if (event_type == ui::AX_EVENT_FOCUS || |
event_type == ui::AX_EVENT_BLUR) { |
if (osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_HIDDEN && |
- osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED) |
+ osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED) { |
osk_state_ = OSK_ALLOWED; |
- |
- bool is_menu_list_option = |
- node->data().role == ui::AX_ROLE_MENU_LIST_OPTION; |
- |
- // Skip all focus events other than ones on menu list options; |
- // we've already handled them, above. Menu list options are a weird |
- // exception because the menu list itself has focus but we need to fire |
- // focus events on the individual options. |
- if (!is_menu_list_option) |
- continue; |
+ } |
+ |
+ // We already handled all focus events above. |
+ continue; |
} |
// Fire the native event. |
@@ -489,19 +483,35 @@ |
node); |
} |
-BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendantFocus( |
+BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendant( |
BrowserAccessibility* focus) { |
if (!focus) |
- return NULL; |
- |
- int active_descendant_id; |
+ return nullptr; |
+ |
+ int32_t active_descendant_id; |
+ BrowserAccessibility* active_descendant = nullptr; |
if (focus->GetIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID, |
&active_descendant_id)) { |
- BrowserAccessibility* active_descendant = |
- focus->manager()->GetFromID(active_descendant_id); |
- if (active_descendant) |
- return active_descendant; |
- } |
+ active_descendant = focus->manager()->GetFromID(active_descendant_id); |
+ } |
+ |
+ if (focus->GetRole() == ui::AX_ROLE_POP_UP_BUTTON) { |
+ BrowserAccessibility* child = focus->InternalGetChild(0); |
+ if (child && child->GetRole() == ui::AX_ROLE_MENU_LIST_POPUP) { |
+ // The active descendant is found on the menu list popup, i.e. on the |
+ // actual list and not on the button that opens it. |
+ // If there is no active descendant, focus should stay on the button so |
+ // that Windows screen readers would enable their virtual cursor. |
+ if (child->GetIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID, |
+ &active_descendant_id)) { |
+ active_descendant = child->manager()->GetFromID(active_descendant_id); |
+ } |
+ } |
+ } |
+ |
+ if (active_descendant) |
+ return active_descendant; |
+ |
return focus; |
} |
@@ -521,6 +531,9 @@ |
BrowserAccessibilityManager* focused_manager = nullptr; |
if (focused_tree_id) |
focused_manager =BrowserAccessibilityManager::FromID(focused_tree_id); |
+ |
+ // BrowserAccessibilityManager::FromID(focused_tree_id) may return nullptr |
+ // if the tree is not created or has been destroyed. |
if (!focused_manager) |
focused_manager = root_manager; |