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 <atlbase.h> | 7 #include <atlbase.h> |
scottmg
2014/01/31 17:28:48
Looks like you can remove all these ATL includes.
ananta
2014/01/31 18:25:29
Done.
| |
8 #include <atlapp.h> | 8 #include <atlapp.h> |
9 #include <atlcom.h> | 9 #include <atlcom.h> |
10 #include <atlcrack.h> | 10 #include <atlcrack.h> |
11 #include <oleacc.h> | 11 #include <oleacc.h> |
12 | 12 |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/win/scoped_comptr.h" | 14 #include "base/win/scoped_comptr.h" |
15 #include "base/win/windows_version.h" | 15 #include "base/win/windows_version.h" |
16 #include "content/browser/accessibility/browser_accessibility_state_impl.h" | 16 #include "content/browser/accessibility/browser_accessibility_state_impl.h" |
17 #include "content/browser/accessibility/browser_accessibility_win.h" | 17 #include "content/browser/accessibility/browser_accessibility_win.h" |
18 #include "content/browser/renderer_host/legacy_render_widget_host_win.h" | |
18 #include "content/common/accessibility_messages.h" | 19 #include "content/common/accessibility_messages.h" |
19 | 20 |
20 namespace content { | 21 namespace content { |
21 | 22 |
22 // Some screen readers expect every tab / every unique web content container | |
23 // to be in its own HWND, like it was before Aura, but with Aura there's just | |
24 // one main HWND for a frame, or even for the whole desktop. So, we need a | |
25 // fake HWND as the root of the accessibility tree for each tab. | |
26 // We should get rid of this code when the latest two versions of all | |
27 // supported screen readers no longer make this assumption. | |
28 // | |
29 // This class implements a child HWND with zero size, that delegates its | |
30 // accessibility implementation to the root of the BrowserAccessibilityManager | |
31 // tree. This HWND is hooked up as the parent of the root object in the | |
32 // BrowserAccessibilityManager tree, so when any accessibility client | |
33 // calls ::WindowFromAccessibleObject, they get this HWND instead of the | |
34 // DesktopWindowTreeHostWin. | |
35 class AccessibleHWND | |
36 : public ATL::CWindowImpl<AccessibleHWND, | |
37 ATL::CWindow, | |
38 ATL::CWinTraits<WS_CHILD> > { | |
39 public: | |
40 // Unfortunately, some screen readers look for this exact window class | |
41 // to enable certain features. It'd be great to remove this. | |
42 DECLARE_WND_CLASS_EX(L"Chrome_RenderWidgetHostHWND", CS_DBLCLKS, 0); | |
43 | |
44 BEGIN_MSG_MAP_EX(AccessibleHWND) | |
45 MESSAGE_HANDLER_EX(WM_GETOBJECT, OnGetObject) | |
46 END_MSG_MAP() | |
47 | |
48 AccessibleHWND(HWND parent, BrowserAccessibilityManagerWin* manager) | |
49 : manager_(manager) { | |
50 Create(parent); | |
51 ShowWindow(true); | |
52 MoveWindow(0, 0, 0, 0); | |
53 | |
54 HRESULT hr = ::CreateStdAccessibleObject( | |
55 hwnd(), OBJID_WINDOW, IID_IAccessible, | |
56 reinterpret_cast<void **>(window_accessible_.Receive())); | |
57 DCHECK(SUCCEEDED(hr)); | |
58 } | |
59 | |
60 HWND hwnd() { | |
61 DCHECK(::IsWindow(m_hWnd)); | |
62 return m_hWnd; | |
63 } | |
64 | |
65 IAccessible* window_accessible() { return window_accessible_; } | |
66 | |
67 void OnManagerDeleted() { | |
68 manager_ = NULL; | |
69 } | |
70 | |
71 protected: | |
72 virtual void OnFinalMessage(HWND hwnd) OVERRIDE { | |
73 if (manager_) | |
74 manager_->OnAccessibleHwndDeleted(); | |
75 delete this; | |
76 } | |
77 | |
78 private: | |
79 LRESULT OnGetObject(UINT message, | |
80 WPARAM w_param, | |
81 LPARAM l_param) { | |
82 if (OBJID_CLIENT != l_param || !manager_) | |
83 return static_cast<LRESULT>(0L); | |
84 | |
85 base::win::ScopedComPtr<IAccessible> root( | |
86 manager_->GetRoot()->ToBrowserAccessibilityWin()); | |
87 return LresultFromObject(IID_IAccessible, w_param, | |
88 static_cast<IAccessible*>(root.Detach())); | |
89 } | |
90 | |
91 BrowserAccessibilityManagerWin* manager_; | |
92 base::win::ScopedComPtr<IAccessible> window_accessible_; | |
93 | |
94 DISALLOW_COPY_AND_ASSIGN(AccessibleHWND); | |
95 }; | |
96 | |
97 | |
98 // static | 23 // static |
99 BrowserAccessibilityManager* BrowserAccessibilityManager::Create( | 24 BrowserAccessibilityManager* BrowserAccessibilityManager::Create( |
100 const ui::AXNodeData& src, | 25 const ui::AXNodeData& src, |
101 BrowserAccessibilityDelegate* delegate, | 26 BrowserAccessibilityDelegate* delegate, |
102 BrowserAccessibilityFactory* factory) { | 27 BrowserAccessibilityFactory* factory) { |
103 return new BrowserAccessibilityManagerWin( | 28 return new BrowserAccessibilityManagerWin( |
104 GetDesktopWindow(), NULL, src, delegate, factory); | 29 new content::LegacyRenderWidgetHostHWND(GetDesktopWindow()), NULL, src, |
30 delegate, factory); | |
105 } | 31 } |
106 | 32 |
107 BrowserAccessibilityManagerWin* | 33 BrowserAccessibilityManagerWin* |
108 BrowserAccessibilityManager::ToBrowserAccessibilityManagerWin() { | 34 BrowserAccessibilityManager::ToBrowserAccessibilityManagerWin() { |
109 return static_cast<BrowserAccessibilityManagerWin*>(this); | 35 return static_cast<BrowserAccessibilityManagerWin*>(this); |
110 } | 36 } |
111 | 37 |
112 BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin( | 38 BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin( |
113 HWND parent_hwnd, | 39 LegacyRenderWidgetHostHWND* accessible_hwnd, |
114 IAccessible* parent_iaccessible, | 40 IAccessible* parent_iaccessible, |
115 const ui::AXNodeData& src, | 41 const ui::AXNodeData& src, |
116 BrowserAccessibilityDelegate* delegate, | 42 BrowserAccessibilityDelegate* delegate, |
117 BrowserAccessibilityFactory* factory) | 43 BrowserAccessibilityFactory* factory) |
118 : BrowserAccessibilityManager(src, delegate, factory), | 44 : BrowserAccessibilityManager(src, delegate, factory), |
119 parent_hwnd_(parent_hwnd), | 45 parent_hwnd_(accessible_hwnd->parent()), |
120 parent_iaccessible_(parent_iaccessible), | 46 parent_iaccessible_(parent_iaccessible), |
121 tracked_scroll_object_(NULL), | 47 tracked_scroll_object_(NULL), |
122 accessible_hwnd_(NULL) { | 48 accessible_hwnd_(accessible_hwnd) { |
123 } | 49 } |
124 | 50 |
125 BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() { | 51 BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() { |
126 if (tracked_scroll_object_) { | 52 if (tracked_scroll_object_) { |
127 tracked_scroll_object_->Release(); | 53 tracked_scroll_object_->Release(); |
128 tracked_scroll_object_ = NULL; | 54 tracked_scroll_object_ = NULL; |
129 } | 55 } |
130 if (accessible_hwnd_) | 56 if (accessible_hwnd_) |
131 accessible_hwnd_->OnManagerDeleted(); | 57 accessible_hwnd_->OnManagerDeleted(); |
132 } | 58 } |
133 | 59 |
134 // static | 60 // static |
135 ui::AXNodeData BrowserAccessibilityManagerWin::GetEmptyDocument() { | 61 ui::AXNodeData BrowserAccessibilityManagerWin::GetEmptyDocument() { |
136 ui::AXNodeData empty_document; | 62 ui::AXNodeData empty_document; |
137 empty_document.id = 0; | 63 empty_document.id = 0; |
138 empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA; | 64 empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA; |
139 empty_document.state = | 65 empty_document.state = |
140 (1 << blink::WebAXStateEnabled) | | 66 (1 << blink::WebAXStateEnabled) | |
141 (1 << ui::AX_STATE_READONLY) | | 67 (1 << ui::AX_STATE_READONLY) | |
142 (1 << ui::AX_STATE_BUSY); | 68 (1 << ui::AX_STATE_BUSY); |
143 return empty_document; | 69 return empty_document; |
144 } | 70 } |
145 | 71 |
146 void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(DWORD event, | 72 void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(DWORD event, |
147 LONG child_id) { | 73 LONG child_id) { |
148 // Don't fire events if this view isn't hooked up to its parent. | 74 // Don't fire events if this view isn't hooked up to its parent. |
149 if (!parent_iaccessible()) | 75 if (!parent_iaccessible()) |
150 return; | 76 return; |
151 | 77 |
152 // If on Win 7 and complete accessibility is enabled, create a fake child HWND | 78 // If on Win 7 and complete accessibility is enabled, use the fake child HWND |
153 // to use as the root of the accessibility tree. See comments above | 79 // to use as the root of the accessibility tree. See comments above |
154 // AccessibleHWND for details. | 80 // LegacyRenderWidgetHostHWND for details. |
155 if (BrowserAccessibilityStateImpl::GetInstance()->IsAccessibleBrowser() && | 81 if (BrowserAccessibilityStateImpl::GetInstance()->IsAccessibleBrowser()) { |
156 !accessible_hwnd_) { | 82 DCHECK(accessible_hwnd_); |
157 accessible_hwnd_ = new AccessibleHWND(parent_hwnd_, this); | 83 accessible_hwnd_->set_browser_accessibility_manager(this); |
158 parent_hwnd_ = accessible_hwnd_->hwnd(); | 84 parent_hwnd_ = accessible_hwnd_->hwnd(); |
159 parent_iaccessible_ = accessible_hwnd_->window_accessible(); | 85 parent_iaccessible_ = accessible_hwnd_->window_accessible(); |
160 } | 86 } |
161 | |
162 ::NotifyWinEvent(event, parent_hwnd(), OBJID_CLIENT, child_id); | 87 ::NotifyWinEvent(event, parent_hwnd(), OBJID_CLIENT, child_id); |
163 } | 88 } |
164 | 89 |
165 void BrowserAccessibilityManagerWin::AddNodeToMap(BrowserAccessibility* node) { | 90 void BrowserAccessibilityManagerWin::AddNodeToMap(BrowserAccessibility* node) { |
166 BrowserAccessibilityManager::AddNodeToMap(node); | 91 BrowserAccessibilityManager::AddNodeToMap(node); |
167 LONG unique_id_win = node->ToBrowserAccessibilityWin()->unique_id_win(); | 92 LONG unique_id_win = node->ToBrowserAccessibilityWin()->unique_id_win(); |
168 unique_id_to_renderer_id_map_[unique_id_win] = node->renderer_id(); | 93 unique_id_to_renderer_id_map_[unique_id_win] = node->renderer_id(); |
169 } | 94 } |
170 | 95 |
171 void BrowserAccessibilityManagerWin::RemoveNode(BrowserAccessibility* node) { | 96 void BrowserAccessibilityManagerWin::RemoveNode(BrowserAccessibility* node) { |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
311 // |parent_iaccessible_| are no longer valid either, since they were | 236 // |parent_iaccessible_| are no longer valid either, since they were |
312 // derived from AccessibleHWND. We don't have to restore them to | 237 // derived from AccessibleHWND. We don't have to restore them to |
313 // previous values, though, because this should only happen | 238 // previous values, though, because this should only happen |
314 // during the destruct sequence for this window. | 239 // during the destruct sequence for this window. |
315 accessible_hwnd_ = NULL; | 240 accessible_hwnd_ = NULL; |
316 parent_hwnd_ = NULL; | 241 parent_hwnd_ = NULL; |
317 parent_iaccessible_ = NULL; | 242 parent_iaccessible_ = NULL; |
318 } | 243 } |
319 | 244 |
320 } // namespace content | 245 } // namespace content |
OLD | NEW |