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

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: Rebase 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/views/controls/native/native_view_host.h"
8 #include "ui/views/view.h" 10 #include "ui/views/view.h"
9 #include "ui/views/widget/widget.h" 11 #include "ui/views/widget/widget.h"
10 12
11 namespace views { 13 namespace views {
12 14
13 #if !defined(OS_WIN) 15 #if !defined(OS_WIN)
14 // static 16 // static
15 NativeViewAccessibility* NativeViewAccessibility::Create(View* view) { 17 NativeViewAccessibility* NativeViewAccessibility::Create(View* view) {
16 DCHECK(view); 18 return new NativeViewAccessibility(view);
17 NativeViewAccessibility* instance = new NativeViewAccessibility();
18 instance->set_view(view);
19 return instance;
20 } 19 }
21 #endif 20 #endif
22 21
23 NativeViewAccessibility::NativeViewAccessibility() 22 NativeViewAccessibility::NativeViewAccessibility(View* view)
24 : view_(NULL), ax_node_(ui::AXPlatformNode::Create(this)) { 23 : view_(view), ax_node_(ui::AXPlatformNode::Create(this)) {
25 } 24 }
26 25
27 NativeViewAccessibility::~NativeViewAccessibility() { 26 NativeViewAccessibility::~NativeViewAccessibility() {
28 if (ax_node_) 27 if (ax_node_)
29 ax_node_->Destroy(); 28 ax_node_->Destroy();
30 } 29 }
31 30
32 gfx::NativeViewAccessible NativeViewAccessibility::GetNativeObject() { 31 gfx::NativeViewAccessible NativeViewAccessibility::GetNativeObject() {
33 return ax_node_ ? ax_node_->GetNativeViewAccessible() : NULL; 32 return ax_node_ ? ax_node_->GetNativeViewAccessible() : NULL;
34 } 33 }
35 34
36 void NativeViewAccessibility::Destroy() { 35 void NativeViewAccessibility::Destroy() {
37 delete this; 36 delete this;
38 } 37 }
39 38
40 #if !defined(OS_WIN) 39 void NativeViewAccessibility::NotifyAccessibilityEvent(ui::AXEvent event_type) {
41 // static 40 if (ax_node_)
42 void NativeViewAccessibility::RegisterWebView(View* web_view) { 41 ax_node_->NotifyAccessibilityEvent(event_type);
43 } 42 }
44 43
45 // static
46 void NativeViewAccessibility::UnregisterWebView(View* web_view) {
47 }
48 #endif
49
50 // ui::AXPlatformNodeDelegate 44 // ui::AXPlatformNodeDelegate
51 45
52 ui::AXNodeData* NativeViewAccessibility::GetData() { 46 const ui::AXNodeData* NativeViewAccessibility::GetData() {
53 ui::AXViewState state; 47 ui::AXViewState state;
54 view_->GetAccessibleState(&state); 48 view_->GetAccessibleState(&state);
49 data_ = ui::AXNodeData();
55 data_.role = state.role; 50 data_.role = state.role;
51 data_.state = state.state();
56 data_.location = view_->GetBoundsInScreen(); 52 data_.location = view_->GetBoundsInScreen();
53 data_.AddStringAttribute(ui::AX_ATTR_NAME, base::UTF16ToUTF8(state.name));
54 data_.AddStringAttribute(ui::AX_ATTR_VALUE, base::UTF16ToUTF8(state.value));
55 data_.AddStringAttribute(ui::AX_ATTR_ACTION,
56 base::UTF16ToUTF8(state.default_action));
57 data_.AddStringAttribute(ui::AX_ATTR_SHORTCUT,
58 base::UTF16ToUTF8(state.keyboard_shortcut));
59 data_.AddIntAttribute(ui::AX_ATTR_TEXT_SEL_START, state.selection_start);
60 data_.AddIntAttribute(ui::AX_ATTR_TEXT_SEL_END, state.selection_end);
61
62 data_.state |= (1 << ui::AX_STATE_FOCUSABLE);
63
64 if (!view_->enabled())
65 data_.state |= (1 << ui::AX_STATE_DISABLED);
66
67 if (!view_->visible())
68 data_.state |= (1 << ui::AX_STATE_INVISIBLE);
69
70 if (view_->HasFocus())
71 data_.state |= (1 << ui::AX_STATE_FOCUSED);
72
57 return &data_; 73 return &data_;
58 } 74 }
59 75
60 int NativeViewAccessibility::GetChildCount() { 76 int NativeViewAccessibility::GetChildCount() {
61 return view_->child_count(); 77 int child_count = view_->child_count();
78
79 // If this is a root view, our widget might have child widgets. Include
80 // them, too.
81 if (view_->GetWidget() && view_->GetWidget()->GetRootView() == view_) {
82 std::vector<Widget*> child_widgets;
83 PopulateChildWidgetVector(&child_widgets);
84 child_count += child_widgets.size();
85 }
86
87 return child_count;
62 } 88 }
63 89
64 gfx::NativeViewAccessible NativeViewAccessibility::ChildAtIndex(int index) { 90 gfx::NativeViewAccessible NativeViewAccessibility::ChildAtIndex(int index) {
65 if (index < 0 || index >= view_->child_count()) 91 // If this is a root view, our widget might have child widgets. Include
66 return NULL; 92 std::vector<Widget*> child_widgets;
67 return view_->child_at(index)->GetNativeViewAccessible(); 93 if (view_->GetWidget() && view_->GetWidget()->GetRootView() == view_)
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 NULL;
sky 2015/02/19 16:40:32 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())
sky 2015/02/19 16:40:32 Why the ! here? Seems like you need it else 114 is
dmazzoni 2015/02/24 04:53:59 Ack, good catch. I didn't mean to change the Mac b
76 return view_->GetWidget()->GetNativeView(); 114 return view_->GetWidget()->GetNativeView();
77 #endif 115 #endif
78 116
79 return NULL; 117 return NULL;
80 } 118 }
81 119
120 int NativeViewAccessibility::GetIndexInParent() {
121 if (!view_->parent())
122 return 0;
sky 2015/02/19 16:40:32 If there is no parent than wouldn't -1 make more s
dmazzoni 2015/02/24 04:53:59 Done.
123 return view_->parent()->GetIndexOf(view_);
sky 2015/02/19 16:40:32 Does this work for child widgets?
dmazzoni 2015/02/24 04:53:59 Fixed now, we explicitly keep track of the parent
124 }
125
82 gfx::Vector2d NativeViewAccessibility::GetGlobalCoordinateOffset() { 126 gfx::Vector2d NativeViewAccessibility::GetGlobalCoordinateOffset() {
83 return gfx::Vector2d(0, 0); // location is already in screen coordinates. 127 return gfx::Vector2d(0, 0); // location is already in screen coordinates.
84 } 128 }
85 129
86 void NativeViewAccessibility::NotifyAccessibilityEvent(ui::AXEvent event_type) { 130 gfx::NativeViewAccessible NativeViewAccessibility::HitTestSync(int x, int y) {
131 if (!view_ || !view_->GetWidget())
132 return NULL;
sky 2015/02/19 16:40:32 nullptr
133
134 // If this is a root view, our widget might have child widgets.
135 // Search child widgets first, since they're on top in the z-order.
136 if (view_->GetWidget()->GetRootView() == view_) {
sky 2015/02/19 16:40:32 I think a IsRootView() would make this code more r
dmazzoni 2015/02/24 04:53:59 I went with the second option, PopulateChildWidget
137 std::vector<Widget*> child_widgets;
138 PopulateChildWidgetVector(&child_widgets);
139 for (size_t i = 0; i < child_widgets.size(); ++i) {
sky 2015/02/19 16:40:32 Use new for loop.
dmazzoni 2015/02/24 04:53:59 Can you clarify?
sky 2015/02/24 16:45:34 for (Widget* child_widget : child_widgets) { }
dmazzoni 2015/02/24 17:48:44 Done.
140 Widget* child_widget = child_widgets[i];
141 View* child_root_view = child_widget->GetRootView();
142 gfx::Point point(x, y);
143 View::ConvertPointFromScreen(child_root_view, &point);
144 if (child_root_view->HitTestPoint(point))
145 return child_root_view->GetNativeViewAccessible();
146 }
147 }
148
149 gfx::Point point(x, y);
150 View::ConvertPointFromScreen(view_, &point);
151
152 // If the point is not inside this view, return NULL.
sky 2015/02/19 16:40:32 This comment just describes the code and isn't hel
153 if (!view_->HitTestPoint(point))
154 return NULL;
sky 2015/02/19 16:40:32 nullptr
155
156 // Check if the point is within any of the immediate children of this
157 // view.
158 for (int i = view_->child_count() - 1; i >= 0; --i) {
159 View* child_view = view_->child_at(i);
160 if (!child_view->visible())
161 continue;
162
163 gfx::Point point_in_child_coords(point);
164 view_->ConvertPointToTarget(view_, child_view, &point_in_child_coords);
165 if (child_view->HitTestPoint(point_in_child_coords))
sky 2015/02/19 16:40:32 Why do you only descend one level here?
dmazzoni 2015/02/24 04:53:59 This will be called recursively when we return any
166 return child_view->GetNativeViewAccessible();
167 }
168
169 // If it's not inside any of our children, it's inside this view.
170 return GetNativeObject();
171 }
172
173 gfx::NativeViewAccessible NativeViewAccessibility::GetFocus() {
174 FocusManager* focus_manager = view_->GetFocusManager();
175 View* focused_view = focus_manager ? focus_manager->GetFocusedView() : NULL;
sky 2015/02/19 16:40:32 nullptr
176 return focused_view ? focused_view->GetNativeViewAccessible() : NULL;
177 }
178
179 gfx::AcceleratedWidget
180 NativeViewAccessibility::GetTargetForNativeAccessibilityEvent() {
181 return gfx::kNullAcceleratedWidget;
182 }
183
184 void NativeViewAccessibility::DoDefaultAction() {
185 gfx::Point center = view_->GetLocalBounds().CenterPoint();
186 view_->OnMousePressed(ui::MouseEvent(ui::ET_MOUSE_PRESSED,
187 center,
188 center,
189 ui::EF_LEFT_MOUSE_BUTTON,
190 ui::EF_LEFT_MOUSE_BUTTON));
191 view_->OnMouseReleased(ui::MouseEvent(ui::ET_MOUSE_RELEASED,
192 center,
193 center,
194 ui::EF_LEFT_MOUSE_BUTTON,
195 ui::EF_LEFT_MOUSE_BUTTON));
196 }
197
198 bool NativeViewAccessibility::SetStringValue(const base::string16& new_value) {
199 // Return an error if the view can't set the value.
200 ui::AXViewState state;
201 view_->GetAccessibleState(&state);
202 if (state.set_value_callback.is_null())
203 return false;
204
205 state.set_value_callback.Run(new_value);
206 return true;
207 }
208
209 void NativeViewAccessibility::PopulateChildWidgetVector(
210 std::vector<Widget*>* result_child_widgets) {
211 const Widget* widget = view_->GetWidget();
212 if (!widget)
213 return;
214
215 std::set<Widget*> child_widgets;
216 Widget::GetAllOwnedWidgets(widget->GetNativeView(), &child_widgets);
217 for (std::set<Widget*>::const_iterator iter = child_widgets.begin();
218 iter != child_widgets.end(); ++iter) {
219 Widget* child_widget = *iter;
220 DCHECK_NE(widget, child_widget);
221
222 if (!child_widget->IsVisible())
223 continue;
224
225 if (widget->GetNativeWindowProperty(kWidgetNativeViewHostKey))
226 continue;
227
228 result_child_widgets->push_back(child_widget);
229 }
87 } 230 }
88 231
89 } // namespace views 232 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698