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

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

Issue 2119413004: a11y: Exclude children of nested keyboard accessible controls from a11y tree. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix compile error and final test in NativeWidgetMacTest. Created 4 years, 2 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 "base/strings/utf_string_conversions.h"
8 #include "build/build_config.h" 8 #include "build/build_config.h"
9 #include "ui/accessibility/ax_view_state.h" 9 #include "ui/accessibility/ax_view_state.h"
10 #include "ui/events/event_utils.h" 10 #include "ui/events/event_utils.h"
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 if (!view_->enabled()) 82 if (!view_->enabled())
83 data_.state |= (1 << ui::AX_STATE_DISABLED); 83 data_.state |= (1 << ui::AX_STATE_DISABLED);
84 84
85 if (!view_->visible()) 85 if (!view_->visible())
86 data_.state |= (1 << ui::AX_STATE_INVISIBLE); 86 data_.state |= (1 << ui::AX_STATE_INVISIBLE);
87 87
88 return data_; 88 return data_;
89 } 89 }
90 90
91 int NativeViewAccessibility::GetChildCount() { 91 int NativeViewAccessibility::GetChildCount() {
92 int child_count = view_->child_count(); 92 int child_count = 0;
93 for (int i = 0; i < view_->child_count(); ++i) {
94 View* child = view_->child_at(i);
95 if (child->GetNativeViewAccessibility()->IsIgnored()) {
96 // If not visible to accessibility clients, then use the children instead.
97 child_count += child->GetNativeViewAccessibility()->GetChildCount();
98 } else {
99 ++child_count;
100 }
101 }
93 102
94 std::vector<Widget*> child_widgets; 103 std::vector<Widget*> child_widgets;
95 PopulateChildWidgetVector(&child_widgets); 104 PopulateChildWidgetVector(&child_widgets);
96 child_count += child_widgets.size(); 105 child_count += child_widgets.size();
97 106
98 return child_count; 107 return child_count;
99 } 108 }
100 109
101 gfx::NativeViewAccessible NativeViewAccessibility::ChildAtIndex(int index) { 110 gfx::NativeViewAccessible NativeViewAccessibility::ChildAtIndex(int index) {
102 // If this is a root view, our widget might have child widgets. Include 111 if (IsLeafElement())
112 return nullptr;
113
114 // Include the child widgets that may be present if this is a root view.
103 std::vector<Widget*> child_widgets; 115 std::vector<Widget*> child_widgets;
104 PopulateChildWidgetVector(&child_widgets); 116 PopulateChildWidgetVector(&child_widgets);
105 int child_widget_count = static_cast<int>(child_widgets.size()); 117 int child_widget_count = static_cast<int>(child_widgets.size());
106 118
107 if (index < view_->child_count()) { 119 int ax_child_count = GetChildCount();
108 return view_->child_at(index)->GetNativeViewAccessible(); 120 if (index < ax_child_count) {
109 } else if (index < view_->child_count() + child_widget_count) { 121 int curr_child_count = 0;
122 for (int i = 0; i < view_->child_count(); ++i) {
123 View* child = view_->child_at(i);
124 bool ignored = child->GetNativeViewAccessibility()->IsIgnored();
125 int pending_children =
126 ignored ? child->GetNativeViewAccessibility()->GetChildCount() : 1;
127 if (index < curr_child_count + pending_children) {
128 if (ignored) {
129 return child->GetNativeViewAccessibility()->ChildAtIndex(
130 index - curr_child_count);
131 }
132 return child->GetNativeViewAccessible();
133 }
134 curr_child_count += pending_children;
135 }
136 } else if (index < ax_child_count + child_widget_count) {
110 Widget* child_widget = child_widgets[index - view_->child_count()]; 137 Widget* child_widget = child_widgets[index - view_->child_count()];
111 return child_widget->GetRootView()->GetNativeViewAccessible(); 138 return child_widget->GetRootView()->GetNativeViewAccessible();
112 } 139 }
113 140
114 return nullptr; 141 return nullptr;
115 } 142 }
116 143
117 gfx::NativeWindow NativeViewAccessibility::GetTopLevelWidget() { 144 gfx::NativeWindow NativeViewAccessibility::GetTopLevelWidget() {
118 if (view_->GetWidget()) 145 if (view_->GetWidget())
119 return view_->GetWidget()->GetTopLevelWidget()->GetNativeWindow(); 146 return view_->GetWidget()->GetTopLevelWidget()->GetNativeWindow();
120 return nullptr; 147 return nullptr;
121 } 148 }
122 149
123 gfx::NativeViewAccessible NativeViewAccessibility::GetParent() { 150 gfx::NativeViewAccessible NativeViewAccessibility::GetParent() {
124 if (view_->parent()) 151 View* parent_view = view_->parent();
125 return view_->parent()->GetNativeViewAccessible(); 152 if (parent_view) {
153 if (parent_view->GetNativeViewAccessibility()->IsIgnored())
154 return parent_view->GetNativeViewAccessibility()->GetParent();
155 else
156 return parent_view->GetNativeViewAccessible();
157 }
126 158
127 // TODO: move this to NativeViewAccessibilityMac. 159 // TODO: move this to NativeViewAccessibilityMac.
128 #if defined(OS_MACOSX) 160 #if defined(OS_MACOSX)
129 if (view_->GetWidget()) 161 if (view_->GetWidget())
130 return view_->GetWidget()->GetNativeView(); 162 return view_->GetWidget()->GetNativeView();
131 #endif 163 #endif
132 164
133 if (parent_widget_) 165 if (parent_widget_)
134 return parent_widget_->GetRootView()->GetNativeViewAccessible(); 166 return parent_widget_->GetRootView()->GetNativeViewAccessible();
135 167
(...skipping 12 matching lines...) Expand all
148 std::vector<Widget*> child_widgets; 180 std::vector<Widget*> child_widgets;
149 PopulateChildWidgetVector(&child_widgets); 181 PopulateChildWidgetVector(&child_widgets);
150 for (Widget* child_widget : child_widgets) { 182 for (Widget* child_widget : child_widgets) {
151 View* child_root_view = child_widget->GetRootView(); 183 View* child_root_view = child_widget->GetRootView();
152 gfx::Point point(x, y); 184 gfx::Point point(x, y);
153 View::ConvertPointFromScreen(child_root_view, &point); 185 View::ConvertPointFromScreen(child_root_view, &point);
154 if (child_root_view->HitTestPoint(point)) 186 if (child_root_view->HitTestPoint(point))
155 return child_root_view->GetNativeViewAccessible(); 187 return child_root_view->GetNativeViewAccessible();
156 } 188 }
157 189
190 if (IsLeafElement()) {
191 if (IsIgnored())
192 return GetParent();
193 return GetNativeObject();
194 }
195
158 gfx::Point point(x, y); 196 gfx::Point point(x, y);
159 View::ConvertPointFromScreen(view_, &point); 197 View::ConvertPointFromScreen(view_, &point);
160 if (!view_->HitTestPoint(point)) 198 if (!view_->HitTestPoint(point))
161 return nullptr; 199 return nullptr;
162 200
163 // Check if the point is within any of the immediate children of this 201 // Check if the point is within any of the immediate children of this view. We
164 // view. We don't have to search further because AXPlatformNode will 202 // don't have to search further because AXPlatformNodeWin will do a recursive
165 // do a recursive hit test if we return anything other than |this| or NULL. 203 // hit test if we return anything other than |GetNativeObject()| or nullptr.
166 for (int i = view_->child_count() - 1; i >= 0; --i) { 204 for (int i = view_->child_count() - 1; i >= 0; --i) {
167 View* child_view = view_->child_at(i); 205 View* child_view = view_->child_at(i);
168 if (!child_view->visible()) 206 if (!child_view->visible())
169 continue; 207 continue;
170 208
171 gfx::Point point_in_child_coords(point); 209 gfx::Point point_in_child_coords(point);
172 view_->ConvertPointToTarget(view_, child_view, &point_in_child_coords); 210 view_->ConvertPointToTarget(view_, child_view, &point_in_child_coords);
173 if (child_view->HitTestPoint(point_in_child_coords)) 211 if (child_view->HitTestPoint(point_in_child_coords))
174 return child_view->GetNativeViewAccessible(); 212 return child_view->GetNativeViewAccessible();
175 } 213 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 } 269 }
232 } 270 }
233 271
234 void NativeViewAccessibility::SetParentWidget(Widget* parent_widget) { 272 void NativeViewAccessibility::SetParentWidget(Widget* parent_widget) {
235 if (parent_widget_) 273 if (parent_widget_)
236 parent_widget_->RemoveObserver(this); 274 parent_widget_->RemoveObserver(this);
237 parent_widget_ = parent_widget; 275 parent_widget_ = parent_widget;
238 parent_widget_->AddObserver(this); 276 parent_widget_->AddObserver(this);
239 } 277 }
240 278
279 bool NativeViewAccessibility::IsLeafElement() {
280 if (GetChildCount() != 0)
281 return false;
282 return true;
283 }
284
285 bool NativeViewAccessibility::IsIgnored() {
286 if (view_->focus_behavior() == ClientView::FocusBehavior::NEVER)
287 return true;
288 return false;
289 }
290
241 void NativeViewAccessibility::PopulateChildWidgetVector( 291 void NativeViewAccessibility::PopulateChildWidgetVector(
242 std::vector<Widget*>* result_child_widgets) { 292 std::vector<Widget*>* result_child_widgets) {
243 // Only attach child widgets to the root view. 293 // Only attach child widgets to the root view.
244 Widget* widget = view_->GetWidget(); 294 Widget* widget = view_->GetWidget();
245 if (!widget || widget->GetRootView() != view_) 295 if (!widget || widget->GetRootView() != view_)
246 return; 296 return;
247 297
248 std::set<Widget*> child_widgets; 298 std::set<Widget*> child_widgets;
249 Widget::GetAllOwnedWidgets(widget->GetNativeView(), &child_widgets); 299 Widget::GetAllOwnedWidgets(widget->GetNativeView(), &child_widgets);
250 for (auto iter = child_widgets.begin(); iter != child_widgets.end(); ++iter) { 300 for (auto iter = child_widgets.begin(); iter != child_widgets.end(); ++iter) {
(...skipping 16 matching lines...) Expand all
267 child_widget_platform_node->GetDelegate()); 317 child_widget_platform_node->GetDelegate());
268 if (child_widget_view_accessibility->parent_widget() != widget) 318 if (child_widget_view_accessibility->parent_widget() != widget)
269 child_widget_view_accessibility->SetParentWidget(widget); 319 child_widget_view_accessibility->SetParentWidget(widget);
270 } 320 }
271 321
272 result_child_widgets->push_back(child_widget); 322 result_child_widgets->push_back(child_widget);
273 } 323 }
274 } 324 }
275 325
276 } // namespace views 326 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698