OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/accessibility/browser_accessibility_manager_win.h" | 5 #include "content/browser/accessibility/browser_accessibility_manager_win.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/win/scoped_comptr.h" | 8 #include "base/win/scoped_comptr.h" |
9 #include "base/win/windows_version.h" | 9 #include "base/win/windows_version.h" |
10 #include "content/browser/accessibility/browser_accessibility_state_impl.h" | 10 #include "content/browser/accessibility/browser_accessibility_state_impl.h" |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 if (focus_ != tree_->GetRoot()) | 127 if (focus_ != tree_->GetRoot()) |
128 NotifyAccessibilityEvent(ui::AX_EVENT_BLUR, GetRoot()); | 128 NotifyAccessibilityEvent(ui::AX_EVENT_BLUR, GetRoot()); |
129 } | 129 } |
130 | 130 |
131 void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( | 131 void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( |
132 ui::AXEvent event_type, | 132 ui::AXEvent event_type, |
133 BrowserAccessibility* node) { | 133 BrowserAccessibility* node) { |
134 if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) | 134 if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) |
135 return; | 135 return; |
136 | 136 |
| 137 // NVDA gets confused if we focus the main document element when it hasn't |
| 138 // finished loading and it has no children at all, so suppress that event. |
| 139 if (event_type == ui::AX_EVENT_FOCUS && |
| 140 node == GetRoot() && |
| 141 node->PlatformChildCount() == 0 && |
| 142 !node->GetBoolAttribute(ui::AX_ATTR_DOC_LOADED)) { |
| 143 return; |
| 144 } |
| 145 |
137 LONG event_id = EVENT_MIN; | 146 LONG event_id = EVENT_MIN; |
138 switch (event_type) { | 147 switch (event_type) { |
139 case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED: | 148 case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED: |
140 event_id = IA2_EVENT_ACTIVE_DESCENDANT_CHANGED; | 149 event_id = IA2_EVENT_ACTIVE_DESCENDANT_CHANGED; |
141 break; | 150 break; |
142 case ui::AX_EVENT_ALERT: | 151 case ui::AX_EVENT_ALERT: |
143 event_id = EVENT_SYSTEM_ALERT; | 152 event_id = EVENT_SYSTEM_ALERT; |
144 break; | 153 break; |
145 case ui::AX_EVENT_ARIA_ATTRIBUTE_CHANGED: | 154 case ui::AX_EVENT_ARIA_ATTRIBUTE_CHANGED: |
146 event_id = IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED; | 155 event_id = IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 // accessibility notification. | 223 // accessibility notification. |
215 break; | 224 break; |
216 } | 225 } |
217 | 226 |
218 if (event_id != EVENT_MIN) { | 227 if (event_id != EVENT_MIN) { |
219 // Pass the node's unique id in the |child_id| argument to NotifyWinEvent; | 228 // Pass the node's unique id in the |child_id| argument to NotifyWinEvent; |
220 // the AT client will then call get_accChild on the HWND's accessibility | 229 // the AT client will then call get_accChild on the HWND's accessibility |
221 // object and pass it that same id, which we can use to retrieve the | 230 // object and pass it that same id, which we can use to retrieve the |
222 // IAccessible for this node. | 231 // IAccessible for this node. |
223 LONG child_id = node->ToBrowserAccessibilityWin()->unique_id_win(); | 232 LONG child_id = node->ToBrowserAccessibilityWin()->unique_id_win(); |
| 233 |
| 234 // Always send a focus before a load complete. |
| 235 if (event_type == ui::AX_EVENT_LOAD_COMPLETE) |
| 236 MaybeCallNotifyWinEvent(EVENT_OBJECT_FOCUS, child_id); |
224 MaybeCallNotifyWinEvent(event_id, child_id); | 237 MaybeCallNotifyWinEvent(event_id, child_id); |
225 } | 238 } |
226 | 239 |
227 // If this is a layout complete notification (sent when a container scrolls) | 240 // If this is a layout complete notification (sent when a container scrolls) |
228 // and there is a descendant tracked object, send a notification on it. | 241 // and there is a descendant tracked object, send a notification on it. |
229 // TODO(dmazzoni): remove once http://crbug.com/113483 is fixed. | 242 // TODO(dmazzoni): remove once http://crbug.com/113483 is fixed. |
230 if (event_type == ui::AX_EVENT_LAYOUT_COMPLETE && | 243 if (event_type == ui::AX_EVENT_LAYOUT_COMPLETE && |
231 tracked_scroll_object_ && | 244 tracked_scroll_object_ && |
232 tracked_scroll_object_->IsDescendantOf(node)) { | 245 tracked_scroll_object_->IsDescendantOf(node)) { |
233 MaybeCallNotifyWinEvent( | 246 MaybeCallNotifyWinEvent( |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 // |parent_iaccessible_| are no longer valid either, since they were | 281 // |parent_iaccessible_| are no longer valid either, since they were |
269 // derived from AccessibleHWND. We don't have to restore them to | 282 // derived from AccessibleHWND. We don't have to restore them to |
270 // previous values, though, because this should only happen | 283 // previous values, though, because this should only happen |
271 // during the destruct sequence for this window. | 284 // during the destruct sequence for this window. |
272 accessible_hwnd_ = NULL; | 285 accessible_hwnd_ = NULL; |
273 parent_hwnd_ = NULL; | 286 parent_hwnd_ = NULL; |
274 parent_iaccessible_ = NULL; | 287 parent_iaccessible_ = NULL; |
275 } | 288 } |
276 | 289 |
277 } // namespace content | 290 } // namespace content |
OLD | NEW |