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

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: Review comments. Created 4 years 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 "ui/events/event_utils.h" 8 #include "ui/events/event_utils.h"
9 #include "ui/gfx/native_widget_types.h" 9 #include "ui/gfx/native_widget_types.h"
10 #include "ui/views/controls/native/native_view_host.h" 10 #include "ui/views/controls/native/native_view_host.h"
11 #include "ui/views/view.h" 11 #include "ui/views/view.h"
12 #include "ui/views/widget/widget.h" 12 #include "ui/views/widget/widget.h"
13 13
14 namespace views { 14 namespace views {
15 15
16 #if defined(OS_MACOSX)
17 namespace {
18
19 bool IsAccessibilityFocusableWhenEnabled(View* view) {
20 return view->focus_behavior() != View::FocusBehavior::NEVER &&
21 view->IsDrawn();
22 }
23
24 bool ViewHasFocusableAncestor(View* view) {
25 while ((view = view->parent())) {
26 if (IsAccessibilityFocusableWhenEnabled(view))
27 return true;
28 }
29 return false;
30 }
31
32 } // namespace
33 #endif
34
16 #if !defined(PLATFORM_HAS_NATIVE_VIEW_ACCESSIBILITY_IMPL) 35 #if !defined(PLATFORM_HAS_NATIVE_VIEW_ACCESSIBILITY_IMPL)
17 // static 36 // static
18 NativeViewAccessibility* NativeViewAccessibility::Create(View* view) { 37 NativeViewAccessibility* NativeViewAccessibility::Create(View* view) {
19 return new NativeViewAccessibility(view); 38 return new NativeViewAccessibility(view);
20 } 39 }
21 #endif // !defined(PLATFORM_HAS_NATIVE_VIEW_ACCESSIBILITY_IMPL) 40 #endif // !defined(PLATFORM_HAS_NATIVE_VIEW_ACCESSIBILITY_IMPL)
22 41
23 NativeViewAccessibility::NativeViewAccessibility(View* view) 42 NativeViewAccessibility::NativeViewAccessibility(View* view)
24 : view_(view), 43 : view_(view),
25 parent_widget_(nullptr), 44 parent_widget_(nullptr),
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 } 92 }
74 93
75 view_->GetAccessibleNodeData(&data_); 94 view_->GetAccessibleNodeData(&data_);
76 data_.location = gfx::RectF(view_->GetBoundsInScreen()); 95 data_.location = gfx::RectF(view_->GetBoundsInScreen());
77 base::string16 description; 96 base::string16 description;
78 view_->GetTooltipText(gfx::Point(), &description); 97 view_->GetTooltipText(gfx::Point(), &description);
79 data_.AddStringAttribute(ui::AX_ATTR_DESCRIPTION, 98 data_.AddStringAttribute(ui::AX_ATTR_DESCRIPTION,
80 base::UTF16ToUTF8(description)); 99 base::UTF16ToUTF8(description));
81 100
82 if (view_->IsAccessibilityFocusable()) 101 if (view_->IsAccessibilityFocusable())
83 data_.state |= (1 << ui::AX_STATE_FOCUSABLE); 102 data_.AddStateFlag(ui::AX_STATE_FOCUSABLE);
84 103
85 if (!view_->enabled()) 104 if (!view_->enabled())
86 data_.state |= (1 << ui::AX_STATE_DISABLED); 105 data_.AddStateFlag(ui::AX_STATE_DISABLED);
87 106
88 if (!view_->visible()) 107 if (!view_->visible())
89 data_.state |= (1 << ui::AX_STATE_INVISIBLE); 108 data_.AddStateFlag(ui::AX_STATE_INVISIBLE);
109
110 #if defined(OS_MACOSX)
dmazzoni 2016/11/30 23:12:44 I'd prefer to find a solution that works for all p
Patti Lor 2016/12/01 01:12:07 See next comment.
111 // Make sure this element is ignored if there's a focusable parent. All
112 // keyboard focusable elements should be leaf nodes in the accessibility tree.
113 // Exceptions to this rule will themselves be accessibility focusable.
114 if (!IsAccessibilityFocusableWhenEnabled(view_) &&
115 ViewHasFocusableAncestor(view_))
116 data_.role = ui::AX_ROLE_UNKNOWN;
dmazzoni 2016/11/30 23:12:44 Rather than setting the role to unknown, what if w
Patti Lor 2016/12/01 01:12:07 Yes - this was my approach in patchset 8. Removing
117 #endif
90 118
91 return data_; 119 return data_;
92 } 120 }
93 121
94 int NativeViewAccessibility::GetChildCount() { 122 int NativeViewAccessibility::GetChildCount() {
95 int child_count = view_->child_count(); 123 int child_count = view_->child_count();
dmazzoni 2016/11/30 23:12:44 Right here, you could add: if (IsAccessibilityFoc
Patti Lor 2016/12/01 01:12:07 See above comment.
96 124
97 std::vector<Widget*> child_widgets; 125 std::vector<Widget*> child_widgets;
98 PopulateChildWidgetVector(&child_widgets); 126 PopulateChildWidgetVector(&child_widgets);
99 child_count += child_widgets.size(); 127 child_count += child_widgets.size();
100 128
101 return child_count; 129 return child_count;
102 } 130 }
103 131
104 gfx::NativeViewAccessible NativeViewAccessibility::ChildAtIndex(int index) { 132 gfx::NativeViewAccessible NativeViewAccessibility::ChildAtIndex(int index) {
105 // If this is a root view, our widget might have child widgets. Include 133 // If this is a root view, our widget might have child widgets. Include
(...skipping 27 matching lines...) Expand all
133 return view_->GetWidget()->GetNativeView(); 161 return view_->GetWidget()->GetNativeView();
134 #endif 162 #endif
135 163
136 if (parent_widget_) 164 if (parent_widget_)
137 return parent_widget_->GetRootView()->GetNativeViewAccessible(); 165 return parent_widget_->GetRootView()->GetNativeViewAccessible();
138 166
139 return nullptr; 167 return nullptr;
140 } 168 }
141 169
142 gfx::Vector2d NativeViewAccessibility::GetGlobalCoordinateOffset() { 170 gfx::Vector2d NativeViewAccessibility::GetGlobalCoordinateOffset() {
143 return gfx::Vector2d(0, 0); // location is already in screen coordinates. 171 return gfx::Vector2d(0, 0); // Location is already in screen coordinates.
144 } 172 }
145 173
146 gfx::NativeViewAccessible NativeViewAccessibility::HitTestSync(int x, int y) { 174 gfx::NativeViewAccessible NativeViewAccessibility::HitTestSync(int x, int y) {
147 if (!view_ || !view_->GetWidget()) 175 if (!view_ || !view_->GetWidget())
148 return nullptr; 176 return nullptr;
149 177
150 // Search child widgets first, since they're on top in the z-order. 178 // Search child widgets first, since they're on top in the z-order.
151 std::vector<Widget*> child_widgets; 179 std::vector<Widget*> child_widgets;
152 PopulateChildWidgetVector(&child_widgets); 180 PopulateChildWidgetVector(&child_widgets);
153 for (Widget* child_widget : child_widgets) { 181 for (Widget* child_widget : child_widgets) {
154 View* child_root_view = child_widget->GetRootView(); 182 View* child_root_view = child_widget->GetRootView();
155 gfx::Point point(x, y); 183 gfx::Point point(x, y);
156 View::ConvertPointFromScreen(child_root_view, &point); 184 View::ConvertPointFromScreen(child_root_view, &point);
157 if (child_root_view->HitTestPoint(point)) 185 if (child_root_view->HitTestPoint(point))
158 return child_root_view->GetNativeViewAccessible(); 186 return child_root_view->GetNativeViewAccessible();
159 } 187 }
160 188
161 gfx::Point point(x, y); 189 gfx::Point point(x, y);
162 View::ConvertPointFromScreen(view_, &point); 190 View::ConvertPointFromScreen(view_, &point);
163 if (!view_->HitTestPoint(point)) 191 if (!view_->HitTestPoint(point))
164 return nullptr; 192 return nullptr;
165 193
166 // Check if the point is within any of the immediate children of this 194 // Check if the point is within any of the immediate children of this view. We
167 // view. We don't have to search further because AXPlatformNode will 195 // don't have to search further because AXPlatformNodeWin will do a recursive
dmazzoni 2016/11/30 23:12:44 Is this specific only to AXPlatformNodeWin?
Patti Lor 2016/12/01 01:12:07 Yes, AFAICT, HitTestSync is only used for Windows
168 // do a recursive hit test if we return anything other than |this| or NULL. 196 // hit test if we return anything other than GetNativeObject() or nullptr.
169 for (int i = view_->child_count() - 1; i >= 0; --i) { 197 for (int i = view_->child_count() - 1; i >= 0; --i) {
170 View* child_view = view_->child_at(i); 198 View* child_view = view_->child_at(i);
171 if (!child_view->visible()) 199 if (!child_view->visible())
172 continue; 200 continue;
173 201
174 gfx::Point point_in_child_coords(point); 202 gfx::Point point_in_child_coords(point);
175 view_->ConvertPointToTarget(view_, child_view, &point_in_child_coords); 203 view_->ConvertPointToTarget(view_, child_view, &point_in_child_coords);
176 if (child_view->HitTestPoint(point_in_child_coords)) 204 if (child_view->HitTestPoint(point_in_child_coords))
177 return child_view->GetNativeViewAccessible(); 205 return child_view->GetNativeViewAccessible();
178 } 206 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 child_widget_platform_node->GetDelegate()); 304 child_widget_platform_node->GetDelegate());
277 if (child_widget_view_accessibility->parent_widget() != widget) 305 if (child_widget_view_accessibility->parent_widget() != widget)
278 child_widget_view_accessibility->SetParentWidget(widget); 306 child_widget_view_accessibility->SetParentWidget(widget);
279 } 307 }
280 308
281 result_child_widgets->push_back(child_widget); 309 result_child_widgets->push_back(child_widget);
282 } 310 }
283 } 311 }
284 312
285 } // namespace views 313 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698