Chromium Code Reviews| 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" |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |