Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Unified Diff: content/browser/accessibility/browser_accessibility_manager_win.cc

Issue 344573003: More NVDA browse mode fixes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@x64_2
Patch Set: Address feedback Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/accessibility/browser_accessibility_manager_win.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/accessibility/browser_accessibility_manager_win.cc
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
index 0efdb3c54a9665dde4f1222bdce0bc052af8ba6b..4e7153ab75a9ba1e081d97b6835ea2c3f07dee8b 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -40,7 +40,8 @@ BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin(
parent_hwnd_(NULL),
parent_iaccessible_(parent_iaccessible),
tracked_scroll_object_(NULL),
- accessible_hwnd_(accessible_hwnd) {
+ accessible_hwnd_(accessible_hwnd),
+ focus_event_on_root_needed_(false) {
ui::win::CreateATLModuleIfNeeded();
if (accessible_hwnd_) {
accessible_hwnd_->set_browser_accessibility_manager(this);
@@ -83,19 +84,18 @@ void BrowserAccessibilityManagerWin::SetAccessibleHWND(
void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(DWORD event,
LONG child_id) {
- // Don't fire events if this view isn't hooked up to its parent.
- if (!parent_iaccessible() || !parent_hwnd())
- return;
-
// If on Win 7 and complete accessibility is enabled, use the fake child HWND
// to use as the root of the accessibility tree. See comments above
// LegacyRenderWidgetHostHWND for details.
- if (BrowserAccessibilityStateImpl::GetInstance()->IsAccessibleBrowser()) {
- DCHECK(accessible_hwnd_);
+ if (accessible_hwnd_ &&
+ BrowserAccessibilityStateImpl::GetInstance()->IsAccessibleBrowser()) {
parent_hwnd_ = accessible_hwnd_->hwnd();
parent_iaccessible_ = accessible_hwnd_->window_accessible();
}
- ::NotifyWinEvent(event, parent_hwnd(), OBJID_CLIENT, child_id);
+
+ // Only fire events if this view is hooked up to its parent.
+ if (parent_iaccessible() && parent_hwnd())
+ ::NotifyWinEvent(event, parent_hwnd(), OBJID_CLIENT, child_id);
}
@@ -120,34 +120,58 @@ void BrowserAccessibilityManagerWin::OnNodeWillBeDeleted(ui::AXNode* node) {
}
void BrowserAccessibilityManagerWin::OnWindowFocused() {
- // Fire a focus event on the root first and then the focused node.
+ // This is called either when this web frame gets focused, or when
+ // the root of the accessibility tree changes. In both cases, we need
+ // to fire a focus event on the root and then on the focused element
+ // within the page, if different.
+
+ // Set this flag so that we'll keep trying to fire these focus events
+ // if they're not successful this time.
+ focus_event_on_root_needed_ = true;
+
+ if (!delegate_ || !delegate_->AccessibilityViewHasFocus())
+ return;
+
+ // Try to fire a focus event on the root first and then the focused node.
+ // This will clear focus_event_on_root_needed_ if successful.
if (focus_ != tree_->GetRoot())
NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetRoot());
BrowserAccessibilityManager::OnWindowFocused();
}
-void BrowserAccessibilityManagerWin::OnWindowBlurred() {
- // Fire a blur event on the focused node first and then the root.
- BrowserAccessibilityManager::OnWindowBlurred();
- if (focus_ != tree_->GetRoot())
- NotifyAccessibilityEvent(ui::AX_EVENT_BLUR, GetRoot());
-}
-
void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
ui::AXEvent event_type,
BrowserAccessibility* node) {
if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX)
return;
+ // Don't fire focus, blur, or load complete notifications if the
+ // window isn't focused, because that can confuse screen readers into
+ // entering their "browse" mode.
+ if ((event_type == ui::AX_EVENT_FOCUS ||
+ event_type == ui::AX_EVENT_BLUR ||
+ event_type == ui::AX_EVENT_LOAD_COMPLETE) &&
+ (!delegate_ || !delegate_->AccessibilityViewHasFocus())) {
+ return;
+ }
+
// NVDA gets confused if we focus the main document element when it hasn't
// finished loading and it has no children at all, so suppress that event.
if (event_type == ui::AX_EVENT_FOCUS &&
node == GetRoot() &&
node->PlatformChildCount() == 0 &&
+ !node->HasState(ui::AX_STATE_BUSY) &&
!node->GetBoolAttribute(ui::AX_ATTR_DOC_LOADED)) {
return;
}
+ // If a focus event is needed on the root, fire that first before
+ // this event.
+ if (event_type == ui::AX_EVENT_FOCUS && node == GetRoot())
+ focus_event_on_root_needed_ = false;
+ else if (focus_event_on_root_needed_)
+ OnWindowFocused();
+
LONG event_id = EVENT_MIN;
switch (event_type) {
case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED:
@@ -235,10 +259,6 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
// object and pass it that same id, which we can use to retrieve the
// IAccessible for this node.
LONG child_id = node->ToBrowserAccessibilityWin()->unique_id_win();
-
- // Always send a focus before a load complete.
- if (event_type == ui::AX_EVENT_LOAD_COMPLETE)
- MaybeCallNotifyWinEvent(EVENT_OBJECT_FOCUS, child_id);
MaybeCallNotifyWinEvent(event_id, child_id);
}
@@ -257,8 +277,9 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
}
void BrowserAccessibilityManagerWin::OnRootChanged(ui::AXNode* new_root) {
- if (delegate_ && delegate_->AccessibilityViewHasFocus())
- NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetRoot());
+ // In order to make screen readers aware of the new accessibility root,
+ // we need to fire a focus event on it.
+ OnWindowFocused();
}
void BrowserAccessibilityManagerWin::TrackScrollingObject(
« no previous file with comments | « content/browser/accessibility/browser_accessibility_manager_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698