| 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" |
| 11 #include "content/browser/accessibility/browser_accessibility_win.h" | 11 #include "content/browser/accessibility/browser_accessibility_win.h" |
| 12 #include "content/browser/renderer_host/legacy_render_widget_host_win.h" | 12 #include "content/browser/renderer_host/legacy_render_widget_host_win.h" |
| 13 #include "content/common/accessibility_messages.h" | 13 #include "content/common/accessibility_messages.h" |
| 14 #include "ui/base/win/atl_module.h" | 14 #include "ui/base/win/atl_module.h" |
| 15 | 15 |
| 16 namespace content { | 16 namespace content { |
| 17 | 17 |
| 18 // static | 18 // static |
| 19 BrowserAccessibilityManager* BrowserAccessibilityManager::Create( | 19 BrowserAccessibilityManager* BrowserAccessibilityManager::Create( |
| 20 const ui::AXTreeUpdate& initial_tree, | 20 const ui::AXTreeUpdate& initial_tree, |
| 21 BrowserAccessibilityDelegate* delegate, | 21 BrowserAccessibilityDelegate* delegate, |
| 22 BrowserAccessibilityFactory* factory) { | 22 BrowserAccessibilityFactory* factory) { |
| 23 return new BrowserAccessibilityManagerWin( | 23 return new BrowserAccessibilityManagerWin(initial_tree, delegate, factory); |
| 24 content::LegacyRenderWidgetHostHWND::Create(GetDesktopWindow()), | |
| 25 NULL, initial_tree, delegate, factory); | |
| 26 } | 24 } |
| 27 | 25 |
| 28 BrowserAccessibilityManagerWin* | 26 BrowserAccessibilityManagerWin* |
| 29 BrowserAccessibilityManager::ToBrowserAccessibilityManagerWin() { | 27 BrowserAccessibilityManager::ToBrowserAccessibilityManagerWin() { |
| 30 return static_cast<BrowserAccessibilityManagerWin*>(this); | 28 return static_cast<BrowserAccessibilityManagerWin*>(this); |
| 31 } | 29 } |
| 32 | 30 |
| 33 BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin( | 31 BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin( |
| 34 LegacyRenderWidgetHostHWND* accessible_hwnd, | |
| 35 IAccessible* parent_iaccessible, | |
| 36 const ui::AXTreeUpdate& initial_tree, | 32 const ui::AXTreeUpdate& initial_tree, |
| 37 BrowserAccessibilityDelegate* delegate, | 33 BrowserAccessibilityDelegate* delegate, |
| 38 BrowserAccessibilityFactory* factory) | 34 BrowserAccessibilityFactory* factory) |
| 39 : BrowserAccessibilityManager(initial_tree, delegate, factory), | 35 : BrowserAccessibilityManager(initial_tree, delegate, factory), |
| 40 parent_hwnd_(NULL), | |
| 41 parent_iaccessible_(parent_iaccessible), | |
| 42 tracked_scroll_object_(NULL), | 36 tracked_scroll_object_(NULL), |
| 43 accessible_hwnd_(accessible_hwnd), | |
| 44 focus_event_on_root_needed_(false) { | 37 focus_event_on_root_needed_(false) { |
| 45 ui::win::CreateATLModuleIfNeeded(); | 38 ui::win::CreateATLModuleIfNeeded(); |
| 46 if (accessible_hwnd_) { | |
| 47 accessible_hwnd_->set_browser_accessibility_manager(this); | |
| 48 parent_hwnd_ = accessible_hwnd_->GetParent(); | |
| 49 } | |
| 50 } | 39 } |
| 51 | 40 |
| 52 BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() { | 41 BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() { |
| 53 if (tracked_scroll_object_) { | 42 if (tracked_scroll_object_) { |
| 54 tracked_scroll_object_->Release(); | 43 tracked_scroll_object_->Release(); |
| 55 tracked_scroll_object_ = NULL; | 44 tracked_scroll_object_ = NULL; |
| 56 } | 45 } |
| 57 if (accessible_hwnd_) | |
| 58 accessible_hwnd_->OnManagerDeleted(this); | |
| 59 } | 46 } |
| 60 | 47 |
| 61 // static | 48 // static |
| 62 ui::AXTreeUpdate BrowserAccessibilityManagerWin::GetEmptyDocument() { | 49 ui::AXTreeUpdate BrowserAccessibilityManagerWin::GetEmptyDocument() { |
| 63 ui::AXNodeData empty_document; | 50 ui::AXNodeData empty_document; |
| 64 empty_document.id = 0; | 51 empty_document.id = 0; |
| 65 empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA; | 52 empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA; |
| 66 empty_document.state = | 53 empty_document.state = |
| 67 (1 << ui::AX_STATE_ENABLED) | | 54 (1 << ui::AX_STATE_ENABLED) | |
| 68 (1 << ui::AX_STATE_READ_ONLY) | | 55 (1 << ui::AX_STATE_READ_ONLY) | |
| 69 (1 << ui::AX_STATE_BUSY); | 56 (1 << ui::AX_STATE_BUSY); |
| 70 | 57 |
| 71 ui::AXTreeUpdate update; | 58 ui::AXTreeUpdate update; |
| 72 update.nodes.push_back(empty_document); | 59 update.nodes.push_back(empty_document); |
| 73 return update; | 60 return update; |
| 74 } | 61 } |
| 75 | 62 |
| 76 void BrowserAccessibilityManagerWin::SetAccessibleHWND( | 63 HWND BrowserAccessibilityManagerWin::GetParentHWND() { |
| 77 LegacyRenderWidgetHostHWND* accessible_hwnd) { | 64 if (!delegate_) |
| 78 if (accessible_hwnd_) | 65 return NULL; |
| 79 accessible_hwnd_->OnManagerDeleted(this); | 66 return delegate_->AccessibilityGetAcceleratedWidget(); |
| 67 } |
| 80 | 68 |
| 81 accessible_hwnd_ = accessible_hwnd; | 69 IAccessible* BrowserAccessibilityManagerWin::GetParentIAccessible() { |
| 82 | 70 if (!delegate_) |
| 83 if (accessible_hwnd_) { | 71 return NULL; |
| 84 accessible_hwnd_->set_browser_accessibility_manager(this); | 72 return delegate_->AccessibilityGetNativeViewAccessible(); |
| 85 parent_hwnd_ = accessible_hwnd_->GetParent(); | |
| 86 } | |
| 87 } | 73 } |
| 88 | 74 |
| 89 void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(DWORD event, | 75 void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(DWORD event, |
| 90 LONG child_id) { | 76 LONG child_id) { |
| 91 // If on Win 7 and complete accessibility is enabled, use the fake child HWND | 77 if (!delegate_) |
| 92 // to use as the root of the accessibility tree. See comments above | 78 return; |
| 93 // LegacyRenderWidgetHostHWND for details. | |
| 94 if (accessible_hwnd_ && | |
| 95 BrowserAccessibilityStateImpl::GetInstance()->IsAccessibleBrowser()) { | |
| 96 parent_hwnd_ = accessible_hwnd_->hwnd(); | |
| 97 parent_iaccessible_ = accessible_hwnd_->window_accessible(); | |
| 98 } | |
| 99 | 79 |
| 100 // Only fire events if this view is hooked up to its parent. | 80 HWND hwnd = delegate_->AccessibilityGetAcceleratedWidget(); |
| 101 if (parent_iaccessible() && parent_hwnd()) | 81 if (!hwnd) |
| 102 ::NotifyWinEvent(event, parent_hwnd(), OBJID_CLIENT, child_id); | 82 return; |
| 83 |
| 84 ::NotifyWinEvent(event, hwnd, OBJID_CLIENT, child_id); |
| 103 } | 85 } |
| 104 | 86 |
| 105 | 87 |
| 106 void BrowserAccessibilityManagerWin::OnNodeCreated(ui::AXNode* node) { | 88 void BrowserAccessibilityManagerWin::OnNodeCreated(ui::AXNode* node) { |
| 107 BrowserAccessibilityManager::OnNodeCreated(node); | 89 BrowserAccessibilityManager::OnNodeCreated(node); |
| 108 BrowserAccessibility* obj = GetFromAXNode(node); | 90 BrowserAccessibility* obj = GetFromAXNode(node); |
| 109 LONG unique_id_win = obj->ToBrowserAccessibilityWin()->unique_id_win(); | 91 LONG unique_id_win = obj->ToBrowserAccessibilityWin()->unique_id_win(); |
| 110 unique_id_to_ax_id_map_[unique_id_win] = obj->GetId(); | 92 unique_id_to_ax_id_map_[unique_id_win] = obj->GetId(); |
| 111 } | 93 } |
| 112 | 94 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 139 // Try to fire a focus event on the root first and then the focused node. | 121 // Try to fire a focus event on the root first and then the focused node. |
| 140 // This will clear focus_event_on_root_needed_ if successful. | 122 // This will clear focus_event_on_root_needed_ if successful. |
| 141 if (focus_ != tree_->GetRoot()) | 123 if (focus_ != tree_->GetRoot()) |
| 142 NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetRoot()); | 124 NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetRoot()); |
| 143 BrowserAccessibilityManager::OnWindowFocused(); | 125 BrowserAccessibilityManager::OnWindowFocused(); |
| 144 } | 126 } |
| 145 | 127 |
| 146 void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( | 128 void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( |
| 147 ui::AXEvent event_type, | 129 ui::AXEvent event_type, |
| 148 BrowserAccessibility* node) { | 130 BrowserAccessibility* node) { |
| 149 // If full accessibility is enabled, wait for the LegacyRenderWidgetHostHWND | 131 if (!delegate_ || !delegate_->AccessibilityGetAcceleratedWidget()) |
| 150 // to be initialized before sending any events - otherwise we'd be firing | |
| 151 // events on the wrong HWND. | |
| 152 if (BrowserAccessibilityStateImpl::GetInstance()->IsAccessibleBrowser() && | |
| 153 !accessible_hwnd_) { | |
| 154 return; | 132 return; |
| 155 } | |
| 156 | 133 |
| 157 // Inline text boxes are an internal implementation detail, we don't | 134 // Inline text boxes are an internal implementation detail, we don't |
| 158 // expose them to Windows. | 135 // expose them to Windows. |
| 159 if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) | 136 if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) |
| 160 return; | 137 return; |
| 161 | 138 |
| 162 // Don't fire focus, blur, or load complete notifications if the | 139 // Don't fire focus, blur, or load complete notifications if the |
| 163 // window isn't focused, because that can confuse screen readers into | 140 // window isn't focused, because that can confuse screen readers into |
| 164 // entering their "browse" mode. | 141 // entering their "browse" mode. |
| 165 if ((event_type == ui::AX_EVENT_FOCUS || | 142 if ((event_type == ui::AX_EVENT_FOCUS || |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 base::hash_map<LONG, int32>::iterator iter = | 280 base::hash_map<LONG, int32>::iterator iter = |
| 304 unique_id_to_ax_id_map_.find(unique_id_win); | 281 unique_id_to_ax_id_map_.find(unique_id_win); |
| 305 if (iter != unique_id_to_ax_id_map_.end()) { | 282 if (iter != unique_id_to_ax_id_map_.end()) { |
| 306 BrowserAccessibility* result = GetFromID(iter->second); | 283 BrowserAccessibility* result = GetFromID(iter->second); |
| 307 if (result) | 284 if (result) |
| 308 return result->ToBrowserAccessibilityWin(); | 285 return result->ToBrowserAccessibilityWin(); |
| 309 } | 286 } |
| 310 return NULL; | 287 return NULL; |
| 311 } | 288 } |
| 312 | 289 |
| 313 void BrowserAccessibilityManagerWin::OnAccessibleHwndDeleted() { | |
| 314 // If the AccessibleHWND is deleted, |parent_hwnd_| and | |
| 315 // |parent_iaccessible_| are no longer valid either, since they were | |
| 316 // derived from AccessibleHWND. We don't have to restore them to | |
| 317 // previous values, though, because this should only happen | |
| 318 // during the destruct sequence for this window. | |
| 319 accessible_hwnd_ = NULL; | |
| 320 parent_hwnd_ = NULL; | |
| 321 parent_iaccessible_ = NULL; | |
| 322 } | |
| 323 | |
| 324 } // namespace content | 290 } // namespace content |
| OLD | NEW |