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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 } | 68 } |
69 | 69 |
70 IAccessible* BrowserAccessibilityManagerWin::GetParentIAccessible() { | 70 IAccessible* BrowserAccessibilityManagerWin::GetParentIAccessible() { |
71 if (!delegate_) | 71 if (!delegate_) |
72 return NULL; | 72 return NULL; |
73 return delegate_->AccessibilityGetNativeViewAccessible(); | 73 return delegate_->AccessibilityGetNativeViewAccessible(); |
74 } | 74 } |
75 | 75 |
76 void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(DWORD event, | 76 void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(DWORD event, |
77 LONG child_id) { | 77 LONG child_id) { |
78 if (!delegate_) | 78 BrowserAccessibilityDelegate* delegate = GetDelegateFromRootManager(); |
| 79 if (!delegate) |
79 return; | 80 return; |
80 | 81 |
81 HWND hwnd = delegate_->AccessibilityGetAcceleratedWidget(); | 82 HWND hwnd = delegate->AccessibilityGetAcceleratedWidget(); |
82 if (!hwnd) | 83 if (!hwnd) |
83 return; | 84 return; |
84 | 85 |
85 ::NotifyWinEvent(event, hwnd, OBJID_CLIENT, child_id); | 86 ::NotifyWinEvent(event, hwnd, OBJID_CLIENT, child_id); |
86 } | 87 } |
87 | 88 |
88 | |
89 void BrowserAccessibilityManagerWin::OnNodeCreated(ui::AXNode* node) { | 89 void BrowserAccessibilityManagerWin::OnNodeCreated(ui::AXNode* node) { |
90 BrowserAccessibilityManager::OnNodeCreated(node); | 90 BrowserAccessibilityManager::OnNodeCreated(node); |
91 BrowserAccessibility* obj = GetFromAXNode(node); | 91 BrowserAccessibility* obj = GetFromAXNode(node); |
92 LONG unique_id_win = obj->ToBrowserAccessibilityWin()->unique_id_win(); | 92 LONG unique_id_win = obj->ToBrowserAccessibilityWin()->unique_id_win(); |
93 unique_id_to_ax_id_map_[unique_id_win] = obj->GetId(); | 93 unique_id_to_ax_id_map_[unique_id_win] = obj->GetId(); |
94 } | 94 } |
95 | 95 |
96 void BrowserAccessibilityManagerWin::OnNodeWillBeDeleted(ui::AXNode* node) { | 96 void BrowserAccessibilityManagerWin::OnNodeWillBeDeleted(ui::AXNode* node) { |
97 BrowserAccessibilityManager::OnNodeWillBeDeleted(node); | 97 BrowserAccessibilityManager::OnNodeWillBeDeleted(node); |
98 BrowserAccessibility* obj = GetFromAXNode(node); | 98 BrowserAccessibility* obj = GetFromAXNode(node); |
(...skipping 23 matching lines...) Expand all Loading... |
122 // Try to fire a focus event on the root first and then the focused node. | 122 // Try to fire a focus event on the root first and then the focused node. |
123 // This will clear focus_event_on_root_needed_ if successful. | 123 // This will clear focus_event_on_root_needed_ if successful. |
124 if (focus_ != tree_->GetRoot()) | 124 if (focus_ != tree_->GetRoot()) |
125 NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetRoot()); | 125 NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetRoot()); |
126 BrowserAccessibilityManager::OnWindowFocused(); | 126 BrowserAccessibilityManager::OnWindowFocused(); |
127 } | 127 } |
128 | 128 |
129 void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( | 129 void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( |
130 ui::AXEvent event_type, | 130 ui::AXEvent event_type, |
131 BrowserAccessibility* node) { | 131 BrowserAccessibility* node) { |
132 if (!delegate_ || !delegate_->AccessibilityGetAcceleratedWidget()) | 132 BrowserAccessibilityDelegate* root_delegate = GetDelegateFromRootManager(); |
| 133 if (!root_delegate || !root_delegate->AccessibilityGetAcceleratedWidget()) |
133 return; | 134 return; |
134 | 135 |
135 // Inline text boxes are an internal implementation detail, we don't | 136 // Inline text boxes are an internal implementation detail, we don't |
136 // expose them to Windows. | 137 // expose them to Windows. |
137 if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) | 138 if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) |
138 return; | 139 return; |
139 | 140 |
140 // Don't fire focus, blur, or load complete notifications if the | 141 // Don't fire focus, blur, or load complete notifications if the |
141 // window isn't focused, because that can confuse screen readers into | 142 // window isn't focused, because that can confuse screen readers into |
142 // entering their "browse" mode. | 143 // entering their "browse" mode. |
143 if ((event_type == ui::AX_EVENT_FOCUS || | 144 if ((event_type == ui::AX_EVENT_FOCUS || |
144 event_type == ui::AX_EVENT_BLUR || | 145 event_type == ui::AX_EVENT_BLUR || |
145 event_type == ui::AX_EVENT_LOAD_COMPLETE) && | 146 event_type == ui::AX_EVENT_LOAD_COMPLETE) && |
146 (!delegate_ || !delegate_->AccessibilityViewHasFocus())) { | 147 !root_delegate->AccessibilityViewHasFocus()) { |
147 return; | 148 return; |
148 } | 149 } |
149 | 150 |
150 // NVDA gets confused if we focus the main document element when it hasn't | 151 // NVDA gets confused if we focus the main document element when it hasn't |
151 // finished loading and it has no children at all, so suppress that event. | 152 // finished loading and it has no children at all, so suppress that event. |
152 if (event_type == ui::AX_EVENT_FOCUS && | 153 if (event_type == ui::AX_EVENT_FOCUS && |
153 node == GetRoot() && | 154 node == GetRoot() && |
154 node->PlatformChildCount() == 0 && | 155 node->PlatformChildCount() == 0 && |
155 !node->HasState(ui::AX_STATE_BUSY) && | 156 !node->HasState(ui::AX_STATE_BUSY) && |
156 !node->GetBoolAttribute(ui::AX_ATTR_DOC_LOADED)) { | 157 !node->GetBoolAttribute(ui::AX_ATTR_DOC_LOADED)) { |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 | 279 |
279 BrowserAccessibilityWin* BrowserAccessibilityManagerWin::GetFromUniqueIdWin( | 280 BrowserAccessibilityWin* BrowserAccessibilityManagerWin::GetFromUniqueIdWin( |
280 LONG unique_id_win) { | 281 LONG unique_id_win) { |
281 base::hash_map<LONG, int32>::iterator iter = | 282 base::hash_map<LONG, int32>::iterator iter = |
282 unique_id_to_ax_id_map_.find(unique_id_win); | 283 unique_id_to_ax_id_map_.find(unique_id_win); |
283 if (iter != unique_id_to_ax_id_map_.end()) { | 284 if (iter != unique_id_to_ax_id_map_.end()) { |
284 BrowserAccessibility* result = GetFromID(iter->second); | 285 BrowserAccessibility* result = GetFromID(iter->second); |
285 if (result) | 286 if (result) |
286 return result->ToBrowserAccessibilityWin(); | 287 return result->ToBrowserAccessibilityWin(); |
287 } | 288 } |
| 289 |
| 290 // Also search all child frames, such as out-of-process iframes or |
| 291 // guest browser plugins. |
| 292 if (delegate()) { |
| 293 std::vector<BrowserAccessibilityManager*> child_frames; |
| 294 delegate()->AccessibilityGetAllChildFrames(&child_frames); |
| 295 for (size_t i = 0; i < child_frames.size(); ++i) { |
| 296 BrowserAccessibilityManagerWin* child_manager = |
| 297 child_frames[i]->ToBrowserAccessibilityManagerWin(); |
| 298 BrowserAccessibilityWin* result = |
| 299 child_manager->GetFromUniqueIdWin(unique_id_win); |
| 300 if (result) |
| 301 return result; |
| 302 } |
| 303 } |
| 304 |
288 return NULL; | 305 return NULL; |
289 } | 306 } |
290 | 307 |
291 } // namespace content | 308 } // namespace content |
OLD | NEW |