OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |