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

Side by Side Diff: ui/views/accessibility/native_view_accessibility.cc

Issue 909143003: Re-land: Implement NativeViewAccessibilityWin using AXPlatformNodeWin. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update GN build Created 5 years, 10 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "ui/views/accessibility/native_view_accessibility.h" 5 #include "ui/views/accessibility/native_view_accessibility.h"
6 6
7 #include "base/strings/utf_string_conversions.h"
7 #include "ui/accessibility/ax_view_state.h" 8 #include "ui/accessibility/ax_view_state.h"
9 #include "ui/events/event_utils.h"
10 #include "ui/views/controls/native/native_view_host.h"
8 #include "ui/views/view.h" 11 #include "ui/views/view.h"
9 #include "ui/views/widget/widget.h" 12 #include "ui/views/widget/widget.h"
10 13
11 namespace views { 14 namespace views {
12 15
13 #if !defined(OS_WIN) 16 #if !defined(OS_WIN)
14 // static 17 // static
15 NativeViewAccessibility* NativeViewAccessibility::Create(View* view) { 18 NativeViewAccessibility* NativeViewAccessibility::Create(View* view) {
16 DCHECK(view); 19 return new NativeViewAccessibility(view);
17 NativeViewAccessibility* instance = new NativeViewAccessibility();
18 instance->set_view(view);
19 return instance;
20 } 20 }
21 #endif 21 #endif
22 22
23 NativeViewAccessibility::NativeViewAccessibility() 23 NativeViewAccessibility::NativeViewAccessibility(View* view)
24 : view_(NULL), ax_node_(ui::AXPlatformNode::Create(this)) { 24 : view_(view),
25 parent_widget_(nullptr),
26 ax_node_(ui::AXPlatformNode::Create(this)) {
25 } 27 }
26 28
27 NativeViewAccessibility::~NativeViewAccessibility() { 29 NativeViewAccessibility::~NativeViewAccessibility() {
28 if (ax_node_) 30 if (ax_node_)
29 ax_node_->Destroy(); 31 ax_node_->Destroy();
32 if (parent_widget_)
33 parent_widget_->RemoveObserver(this);
30 } 34 }
31 35
32 gfx::NativeViewAccessible NativeViewAccessibility::GetNativeObject() { 36 gfx::NativeViewAccessible NativeViewAccessibility::GetNativeObject() {
33 return ax_node_ ? ax_node_->GetNativeViewAccessible() : NULL; 37 return ax_node_ ? ax_node_->GetNativeViewAccessible() : nullptr;
34 } 38 }
35 39
36 void NativeViewAccessibility::Destroy() { 40 void NativeViewAccessibility::Destroy() {
37 delete this; 41 delete this;
38 } 42 }
39 43
40 #if !defined(OS_WIN) 44 void NativeViewAccessibility::NotifyAccessibilityEvent(ui::AXEvent event_type) {
41 // static 45 if (ax_node_)
42 void NativeViewAccessibility::RegisterWebView(View* web_view) { 46 ax_node_->NotifyAccessibilityEvent(event_type);
43 } 47 }
44
45 // static
46 void NativeViewAccessibility::UnregisterWebView(View* web_view) {
47 }
48 #endif
49 48
50 // ui::AXPlatformNodeDelegate 49 // ui::AXPlatformNodeDelegate
51 50
52 ui::AXNodeData* NativeViewAccessibility::GetData() { 51 const ui::AXNodeData& NativeViewAccessibility::GetData() {
53 ui::AXViewState state; 52 ui::AXViewState state;
54 view_->GetAccessibleState(&state); 53 view_->GetAccessibleState(&state);
54 data_ = ui::AXNodeData();
55 data_.role = state.role; 55 data_.role = state.role;
56 data_.state = state.state();
56 data_.location = view_->GetBoundsInScreen(); 57 data_.location = view_->GetBoundsInScreen();
57 return &data_; 58 data_.AddStringAttribute(ui::AX_ATTR_NAME, base::UTF16ToUTF8(state.name));
59 data_.AddStringAttribute(ui::AX_ATTR_VALUE, base::UTF16ToUTF8(state.value));
60 data_.AddStringAttribute(ui::AX_ATTR_ACTION,
61 base::UTF16ToUTF8(state.default_action));
62 data_.AddStringAttribute(ui::AX_ATTR_SHORTCUT,
63 base::UTF16ToUTF8(state.keyboard_shortcut));
64 data_.AddIntAttribute(ui::AX_ATTR_TEXT_SEL_START, state.selection_start);
65 data_.AddIntAttribute(ui::AX_ATTR_TEXT_SEL_END, state.selection_end);
66
67 data_.state |= (1 << ui::AX_STATE_FOCUSABLE);
68
69 if (!view_->enabled())
70 data_.state |= (1 << ui::AX_STATE_DISABLED);
71
72 if (!view_->visible())
73 data_.state |= (1 << ui::AX_STATE_INVISIBLE);
74
75 if (view_->HasFocus())
76 data_.state |= (1 << ui::AX_STATE_FOCUSED);
77
78 return data_;
58 } 79 }
59 80
60 int NativeViewAccessibility::GetChildCount() { 81 int NativeViewAccessibility::GetChildCount() {
61 return view_->child_count(); 82 int child_count = view_->child_count();
83
84 std::vector<Widget*> child_widgets;
85 PopulateChildWidgetVector(&child_widgets);
86 child_count += child_widgets.size();
87
88 return child_count;
62 } 89 }
63 90
64 gfx::NativeViewAccessible NativeViewAccessibility::ChildAtIndex(int index) { 91 gfx::NativeViewAccessible NativeViewAccessibility::ChildAtIndex(int index) {
65 if (index < 0 || index >= view_->child_count()) 92 // If this is a root view, our widget might have child widgets. Include
66 return NULL; 93 std::vector<Widget*> child_widgets;
67 return view_->child_at(index)->GetNativeViewAccessible(); 94 PopulateChildWidgetVector(&child_widgets);
95 int child_widget_count = static_cast<int>(child_widgets.size());
96
97 if (index < view_->child_count()) {
98 return view_->child_at(index)->GetNativeViewAccessible();
99 } else if (index < view_->child_count() + child_widget_count) {
100 Widget* child_widget = child_widgets[index - view_->child_count()];
101 return child_widget->GetRootView()->GetNativeViewAccessible();
102 }
103
104 return nullptr;
68 } 105 }
69 106
70 gfx::NativeViewAccessible NativeViewAccessibility::GetParent() { 107 gfx::NativeViewAccessible NativeViewAccessibility::GetParent() {
71 if (view_->parent()) 108 if (view_->parent())
72 return view_->parent()->GetNativeViewAccessible(); 109 return view_->parent()->GetNativeViewAccessible();
73 110
111 // TODO: move this to NativeViewAccessibilityMac.
74 #if defined(OS_MACOSX) 112 #if defined(OS_MACOSX)
75 if (view_->GetWidget()) 113 if (view_->GetWidget())
76 return view_->GetWidget()->GetNativeView(); 114 return view_->GetWidget()->GetNativeView();
77 #endif 115 #endif
78 116
79 return NULL; 117 if (parent_widget_)
118 return parent_widget_->GetRootView()->GetNativeViewAccessible();
119
120 return nullptr;
80 } 121 }
81 122
82 gfx::Vector2d NativeViewAccessibility::GetGlobalCoordinateOffset() { 123 gfx::Vector2d NativeViewAccessibility::GetGlobalCoordinateOffset() {
83 return gfx::Vector2d(0, 0); // location is already in screen coordinates. 124 return gfx::Vector2d(0, 0); // location is already in screen coordinates.
84 } 125 }
85 126
86 void NativeViewAccessibility::NotifyAccessibilityEvent(ui::AXEvent event_type) { 127 gfx::NativeViewAccessible NativeViewAccessibility::HitTestSync(int x, int y) {
128 if (!view_ || !view_->GetWidget())
129 return nullptr;
130
131 // Search child widgets first, since they're on top in the z-order.
132 std::vector<Widget*> child_widgets;
133 PopulateChildWidgetVector(&child_widgets);
134 for (Widget* child_widget : child_widgets) {
135 View* child_root_view = child_widget->GetRootView();
136 gfx::Point point(x, y);
137 View::ConvertPointFromScreen(child_root_view, &point);
138 if (child_root_view->HitTestPoint(point))
139 return child_root_view->GetNativeViewAccessible();
140 }
141
142 gfx::Point point(x, y);
143 View::ConvertPointFromScreen(view_, &point);
144 if (!view_->HitTestPoint(point))
145 return nullptr;
146
147 // Check if the point is within any of the immediate children of this
148 // view. We don't have to search further because AXPlatformNode will
149 // do a recursive hit test if we return anything other than |this| or NULL.
150 for (int i = view_->child_count() - 1; i >= 0; --i) {
151 View* child_view = view_->child_at(i);
152 if (!child_view->visible())
153 continue;
154
155 gfx::Point point_in_child_coords(point);
156 view_->ConvertPointToTarget(view_, child_view, &point_in_child_coords);
157 if (child_view->HitTestPoint(point_in_child_coords))
158 return child_view->GetNativeViewAccessible();
159 }
160
161 // If it's not inside any of our children, it's inside this view.
162 return GetNativeObject();
163 }
164
165 gfx::NativeViewAccessible NativeViewAccessibility::GetFocus() {
166 FocusManager* focus_manager = view_->GetFocusManager();
167 View* focused_view =
168 focus_manager ? focus_manager->GetFocusedView() : nullptr;
169 return focused_view ? focused_view->GetNativeViewAccessible() : nullptr;
170 }
171
172 gfx::AcceleratedWidget
173 NativeViewAccessibility::GetTargetForNativeAccessibilityEvent() {
174 return gfx::kNullAcceleratedWidget;
175 }
176
177 void NativeViewAccessibility::DoDefaultAction() {
178 gfx::Point center = view_->GetLocalBounds().CenterPoint();
179 view_->OnMousePressed(ui::MouseEvent(ui::ET_MOUSE_PRESSED,
180 center,
181 center,
182 ui::EventTimeForNow(),
183 ui::EF_LEFT_MOUSE_BUTTON,
184 ui::EF_LEFT_MOUSE_BUTTON));
185 view_->OnMouseReleased(ui::MouseEvent(ui::ET_MOUSE_RELEASED,
186 center,
187 center,
188 ui::EventTimeForNow(),
189 ui::EF_LEFT_MOUSE_BUTTON,
190 ui::EF_LEFT_MOUSE_BUTTON));
191 }
192
193 bool NativeViewAccessibility::SetStringValue(const base::string16& new_value) {
194 // Return an error if the view can't set the value.
195 ui::AXViewState state;
196 view_->GetAccessibleState(&state);
197 if (state.set_value_callback.is_null())
198 return false;
199
200 state.set_value_callback.Run(new_value);
201 return true;
202 }
203
204 void NativeViewAccessibility::OnWidgetDestroying(Widget* widget) {
205 if (parent_widget_ == widget)
206 parent_widget_ = nullptr;
207 }
208
209 void NativeViewAccessibility::SetParentWidget(Widget* parent_widget) {
210 if (parent_widget_)
211 parent_widget_->RemoveObserver(this);
212 parent_widget_ = parent_widget;
213 parent_widget_->AddObserver(this);
214 }
215
216 void NativeViewAccessibility::PopulateChildWidgetVector(
217 std::vector<Widget*>* result_child_widgets) {
218 // Only attach child widgets to the root view.
219 Widget* widget = view_->GetWidget();
220 if (!widget || widget->GetRootView() != view_)
221 return;
222
223 std::set<Widget*> child_widgets;
224 Widget::GetAllOwnedWidgets(widget->GetNativeView(), &child_widgets);
225 for (auto iter = child_widgets.begin(); iter != child_widgets.end(); ++iter) {
226 Widget* child_widget = *iter;
227 DCHECK_NE(widget, child_widget);
228
229 if (!child_widget->IsVisible())
230 continue;
231
232 if (widget->GetNativeWindowProperty(kWidgetNativeViewHostKey))
233 continue;
234
235 gfx::NativeViewAccessible child_widget_accessible =
236 child_widget->GetRootView()->GetNativeViewAccessible();
237 ui::AXPlatformNode* child_widget_platform_node =
238 ui::AXPlatformNode::FromNativeViewAccessible(child_widget_accessible);
239 if (child_widget_platform_node) {
240 NativeViewAccessibility* child_widget_view_accessibility =
241 static_cast<NativeViewAccessibility*>(
242 child_widget_platform_node->GetDelegate());
243 if (child_widget_view_accessibility->parent_widget() != widget)
244 child_widget_view_accessibility->SetParentWidget(widget);
245 }
246
247 result_child_widgets->push_back(child_widget);
248 }
87 } 249 }
88 250
89 } // namespace views 251 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/accessibility/native_view_accessibility.h ('k') | ui/views/accessibility/native_view_accessibility_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698