Index: chrome/browser/ui/views/accessibility/accessibility_event_router_views.cc |
diff --git a/chrome/browser/ui/views/accessibility/accessibility_event_router_views.cc b/chrome/browser/ui/views/accessibility/accessibility_event_router_views.cc |
index bab270e451dbfd7a048f84fac5164b7dbeadcdb0..5317d74a5521099eafdae3decf00e4867cb5347c 100644 |
--- a/chrome/browser/ui/views/accessibility/accessibility_event_router_views.cc |
+++ b/chrome/browser/ui/views/accessibility/accessibility_event_router_views.cc |
@@ -24,9 +24,12 @@ |
#include "ui/views/widget/widget.h" |
using views::FocusManager; |
+using views::ViewStorage; |
AccessibilityEventRouterViews::AccessibilityEventRouterViews() |
- : most_recent_profile_(NULL) { |
+ : most_recent_profile_(NULL), |
+ most_recent_view_id_( |
+ ViewStorage::GetInstance()->CreateStorageID()) { |
// Register for notification when profile is destroyed to ensure that all |
// observers are detatched at that time. |
registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
@@ -68,7 +71,7 @@ void AccessibilityEventRouterViews::HandleAccessibilityEvent( |
// event loop, to handle cases where the view's state changes after |
// the call to post the event. It's safe to use base::Unretained(this) |
// because AccessibilityEventRouterViews is a singleton. |
- views::ViewStorage* view_storage = views::ViewStorage::GetInstance(); |
+ ViewStorage* view_storage = ViewStorage::GetInstance(); |
int view_storage_id = view_storage->CreateStorageID(); |
view_storage->StoreView(view_storage_id, view); |
base::MessageLoop::current()->PostTask( |
@@ -120,7 +123,7 @@ void AccessibilityEventRouterViews::Observe( |
void AccessibilityEventRouterViews::DispatchEventOnViewStorageId( |
int view_storage_id, |
ui::AXEvent type) { |
- views::ViewStorage* view_storage = views::ViewStorage::GetInstance(); |
+ ViewStorage* view_storage = ViewStorage::GetInstance(); |
views::View* view = view_storage->RetrieveView(view_storage_id); |
view_storage->RemoveView(view_storage_id); |
if (!view) |
@@ -163,6 +166,20 @@ void AccessibilityEventRouterViews::DispatchAccessibilityEvent( |
return; |
} |
+ view = FindFirstAccessibleAncestor(view); |
+ |
+ // Since multiple items could share a highest focusable view, these items |
+ // could all dispatch the same accessibility hover events, which isn't |
+ // necessary. |
+ if (type == ui::AX_EVENT_HOVER && |
+ ViewStorage::GetInstance()->RetrieveView(most_recent_view_id_) == view) { |
+ return; |
+ } |
+ // If there was already a view stored here from before, it must be removed |
+ // before storing a new view. |
+ ViewStorage::GetInstance()->RemoveView(most_recent_view_id_); |
+ ViewStorage::GetInstance()->StoreView(most_recent_view_id_, view); |
+ |
ui::AXViewState state; |
view->GetAccessibleState(&state); |
@@ -552,3 +569,12 @@ std::string AccessibilityEventRouterViews::RecursiveGetStaticText( |
} |
return std::string(); |
} |
+ |
+// static |
+views::View* AccessibilityEventRouterViews::FindFirstAccessibleAncestor( |
+ views::View* view) { |
+ while (view->parent() && !view->IsAccessibilityFocusable()) { |
+ view = view->parent(); |
+ } |
+ return view; |
+} |