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

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: Move to a Mac-specific approach by ignoring elements with keyboard focusable parents. 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"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 if (!ui::AXNodeData::IsFlagSet(GetData().state, ui::AX_STATE_FOCUSABLE)) 51 if (!ui::AXNodeData::IsFlagSet(GetData().state, ui::AX_STATE_FOCUSABLE))
52 return false; 52 return false;
53 53
54 if (focused) 54 if (focused)
55 view_->RequestFocus(); 55 view_->RequestFocus();
56 else if (view_->HasFocus()) 56 else if (view_->HasFocus())
57 view_->GetFocusManager()->ClearFocus(); 57 view_->GetFocusManager()->ClearFocus();
58 return true; 58 return true;
59 } 59 }
60 60
61 #if defined(OS_MACOSX)
62 bool NativeViewAccessibility::HasFocusableAncestor() {
63 View* parent = view_;
64 while ((parent = parent->parent())) {
65 if (parent->IsAccessibilityFocusable())
66 return true;
67 }
68 return false;
69 }
70 #endif
71
61 // ui::AXPlatformNodeDelegate 72 // ui::AXPlatformNodeDelegate
62 73
63 const ui::AXNodeData& NativeViewAccessibility::GetData() { 74 const ui::AXNodeData& NativeViewAccessibility::GetData() {
64 data_ = ui::AXNodeData(); 75 data_ = ui::AXNodeData();
65 data_.state = 0; 76 data_.state = 0;
66 77
67 // Views may misbehave if their widget is closed; return an unknown role 78 // Views may misbehave if their widget is closed; return an unknown role
68 // rather than possibly crashing. 79 // rather than possibly crashing.
69 if (!view_->GetWidget() || view_->GetWidget()->IsClosed()) { 80 if (!view_->GetWidget() || view_->GetWidget()->IsClosed()) {
70 data_.role = ui::AX_ROLE_UNKNOWN; 81 data_.role = ui::AX_ROLE_UNKNOWN;
71 data_.state = 1 << ui::AX_STATE_DISABLED; 82 data_.state = 1 << ui::AX_STATE_DISABLED;
72 return data_; 83 return data_;
73 } 84 }
74 85
75 view_->GetAccessibleNodeData(&data_); 86 view_->GetAccessibleNodeData(&data_);
76 data_.location = gfx::RectF(view_->GetBoundsInScreen()); 87 data_.location = gfx::RectF(view_->GetBoundsInScreen());
77 base::string16 description; 88 base::string16 description;
78 view_->GetTooltipText(gfx::Point(), &description); 89 view_->GetTooltipText(gfx::Point(), &description);
79 data_.AddStringAttribute(ui::AX_ATTR_DESCRIPTION, 90 data_.AddStringAttribute(ui::AX_ATTR_DESCRIPTION,
80 base::UTF16ToUTF8(description)); 91 base::UTF16ToUTF8(description));
81 92
82 if (view_->IsAccessibilityFocusable()) 93 if (view_->IsAccessibilityFocusable())
83 data_.state |= (1 << ui::AX_STATE_FOCUSABLE); 94 data_.AddStateFlag(ui::AX_STATE_FOCUSABLE);
84 95
85 if (!view_->enabled()) 96 if (!view_->enabled())
86 data_.state |= (1 << ui::AX_STATE_DISABLED); 97 data_.AddStateFlag(ui::AX_STATE_DISABLED);
87 98
88 if (!view_->visible()) 99 if (!view_->visible())
89 data_.state |= (1 << ui::AX_STATE_INVISIBLE); 100 data_.AddStateFlag(ui::AX_STATE_INVISIBLE);
101
102 #if defined(OS_MACOSX)
103 // Make sure this element is ignored if there's a focusable parent. All
104 // keyboard focusable elements should be leaf nodes in the accessibility tree.
105 if (HasFocusableAncestor())
tapted 2016/11/25 04:36:27 should we do this only if the view itself is not a
Patti Lor 2016/11/28 06:40:23 That sounds reasonable - I don't think it fixes th
106 data_.role = ui::AX_ROLE_UNKNOWN;
107 #endif
90 108
91 return data_; 109 return data_;
92 } 110 }
93 111
94 int NativeViewAccessibility::GetChildCount() { 112 int NativeViewAccessibility::GetChildCount() {
95 int child_count = view_->child_count(); 113 int child_count = view_->child_count();
96 114
97 std::vector<Widget*> child_widgets; 115 std::vector<Widget*> child_widgets;
98 PopulateChildWidgetVector(&child_widgets); 116 PopulateChildWidgetVector(&child_widgets);
99 child_count += child_widgets.size(); 117 child_count += child_widgets.size();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 return view_->GetWidget()->GetNativeView(); 151 return view_->GetWidget()->GetNativeView();
134 #endif 152 #endif
135 153
136 if (parent_widget_) 154 if (parent_widget_)
137 return parent_widget_->GetRootView()->GetNativeViewAccessible(); 155 return parent_widget_->GetRootView()->GetNativeViewAccessible();
138 156
139 return nullptr; 157 return nullptr;
140 } 158 }
141 159
142 gfx::Vector2d NativeViewAccessibility::GetGlobalCoordinateOffset() { 160 gfx::Vector2d NativeViewAccessibility::GetGlobalCoordinateOffset() {
143 return gfx::Vector2d(0, 0); // location is already in screen coordinates. 161 return gfx::Vector2d(0, 0); // Location is already in screen coordinates.
144 } 162 }
145 163
146 gfx::NativeViewAccessible NativeViewAccessibility::HitTestSync(int x, int y) { 164 gfx::NativeViewAccessible NativeViewAccessibility::HitTestSync(int x, int y) {
147 if (!view_ || !view_->GetWidget()) 165 if (!view_ || !view_->GetWidget())
148 return nullptr; 166 return nullptr;
149 167
150 // Search child widgets first, since they're on top in the z-order. 168 // Search child widgets first, since they're on top in the z-order.
151 std::vector<Widget*> child_widgets; 169 std::vector<Widget*> child_widgets;
152 PopulateChildWidgetVector(&child_widgets); 170 PopulateChildWidgetVector(&child_widgets);
153 for (Widget* child_widget : child_widgets) { 171 for (Widget* child_widget : child_widgets) {
154 View* child_root_view = child_widget->GetRootView(); 172 View* child_root_view = child_widget->GetRootView();
155 gfx::Point point(x, y); 173 gfx::Point point(x, y);
156 View::ConvertPointFromScreen(child_root_view, &point); 174 View::ConvertPointFromScreen(child_root_view, &point);
157 if (child_root_view->HitTestPoint(point)) 175 if (child_root_view->HitTestPoint(point))
158 return child_root_view->GetNativeViewAccessible(); 176 return child_root_view->GetNativeViewAccessible();
159 } 177 }
160 178
161 gfx::Point point(x, y); 179 gfx::Point point(x, y);
162 View::ConvertPointFromScreen(view_, &point); 180 View::ConvertPointFromScreen(view_, &point);
163 if (!view_->HitTestPoint(point)) 181 if (!view_->HitTestPoint(point))
164 return nullptr; 182 return nullptr;
165 183
166 // Check if the point is within any of the immediate children of this 184 // 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 185 // don't have to search further because AXPlatformNodeWin will do a recursive
168 // do a recursive hit test if we return anything other than |this| or NULL. 186 // hit test if we return anything other than GetNativeObject() or nullptr.
169 for (int i = view_->child_count() - 1; i >= 0; --i) { 187 for (int i = view_->child_count() - 1; i >= 0; --i) {
170 View* child_view = view_->child_at(i); 188 View* child_view = view_->child_at(i);
171 if (!child_view->visible()) 189 if (!child_view->visible())
172 continue; 190 continue;
173 191
174 gfx::Point point_in_child_coords(point); 192 gfx::Point point_in_child_coords(point);
175 view_->ConvertPointToTarget(view_, child_view, &point_in_child_coords); 193 view_->ConvertPointToTarget(view_, child_view, &point_in_child_coords);
176 if (child_view->HitTestPoint(point_in_child_coords)) 194 if (child_view->HitTestPoint(point_in_child_coords))
177 return child_view->GetNativeViewAccessible(); 195 return child_view->GetNativeViewAccessible();
178 } 196 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 child_widget_platform_node->GetDelegate()); 294 child_widget_platform_node->GetDelegate());
277 if (child_widget_view_accessibility->parent_widget() != widget) 295 if (child_widget_view_accessibility->parent_widget() != widget)
278 child_widget_view_accessibility->SetParentWidget(widget); 296 child_widget_view_accessibility->SetParentWidget(widget);
279 } 297 }
280 298
281 result_child_widgets->push_back(child_widget); 299 result_child_widgets->push_back(child_widget);
282 } 300 }
283 } 301 }
284 302
285 } // namespace views 303 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698