| 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_base.h" |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "ui/events/event_utils.h" | 9 #include "ui/events/event_utils.h" |
| 10 #include "ui/gfx/native_widget_types.h" | 10 #include "ui/gfx/native_widget_types.h" |
| 11 #include "ui/views/controls/native/native_view_host.h" | 11 #include "ui/views/controls/native/native_view_host.h" |
| 12 #include "ui/views/view.h" | 12 #include "ui/views/view.h" |
| 13 #include "ui/views/widget/widget.h" | 13 #include "ui/views/widget/widget.h" |
| 14 | 14 |
| 15 namespace views { | 15 namespace views { |
| 16 | 16 |
| 17 #if !defined(PLATFORM_HAS_NATIVE_VIEW_ACCESSIBILITY_IMPL) | 17 NativeViewAccessibilityBase::NativeViewAccessibilityBase(View* view) |
| 18 // static | |
| 19 std::unique_ptr<NativeViewAccessibility> NativeViewAccessibility::Create( | |
| 20 View* view) { | |
| 21 // Use WrapUnique over MakeUnique to invoke the protected constructor. | |
| 22 return base::WrapUnique<NativeViewAccessibility>( | |
| 23 new NativeViewAccessibility(view)); | |
| 24 } | |
| 25 #endif // !defined(PLATFORM_HAS_NATIVE_VIEW_ACCESSIBILITY_IMPL) | |
| 26 | |
| 27 NativeViewAccessibility::NativeViewAccessibility(View* view) | |
| 28 : view_(view), | 18 : view_(view), |
| 29 parent_widget_(nullptr), | 19 parent_widget_(nullptr), |
| 30 ax_node_(nullptr) { | 20 ax_node_(ui::AXPlatformNode::Create(this)) { |
| 31 ax_node_ = ui::AXPlatformNode::Create(this); | 21 DCHECK(ax_node_); |
| 32 } | 22 } |
| 33 | 23 |
| 34 NativeViewAccessibility::~NativeViewAccessibility() { | 24 NativeViewAccessibilityBase::~NativeViewAccessibilityBase() { |
| 35 if (ax_node_) | 25 ax_node_->Destroy(); |
| 36 ax_node_->Destroy(); | |
| 37 if (parent_widget_) | 26 if (parent_widget_) |
| 38 parent_widget_->RemoveObserver(this); | 27 parent_widget_->RemoveObserver(this); |
| 39 } | 28 } |
| 40 | 29 |
| 41 gfx::NativeViewAccessible NativeViewAccessibility::GetNativeObject() { | 30 gfx::NativeViewAccessible NativeViewAccessibilityBase::GetNativeObject() { |
| 42 return ax_node_ ? ax_node_->GetNativeViewAccessible() : nullptr; | 31 return ax_node_->GetNativeViewAccessible(); |
| 43 } | 32 } |
| 44 | 33 |
| 45 void NativeViewAccessibility::NotifyAccessibilityEvent(ui::AXEvent event_type) { | 34 void NativeViewAccessibilityBase::NotifyAccessibilityEvent( |
| 46 if (ax_node_) | 35 ui::AXEvent event_type) { |
| 47 ax_node_->NotifyAccessibilityEvent(event_type); | 36 ax_node_->NotifyAccessibilityEvent(event_type); |
| 48 } | 37 } |
| 49 | 38 |
| 50 bool NativeViewAccessibility::SetFocused(bool focused) { | 39 bool NativeViewAccessibilityBase::SetFocused(bool focused) { |
| 51 if (!ui::AXNodeData::IsFlagSet(GetData().state, ui::AX_STATE_FOCUSABLE)) | 40 if (!ui::AXNodeData::IsFlagSet(GetData().state, ui::AX_STATE_FOCUSABLE)) |
| 52 return false; | 41 return false; |
| 53 | 42 |
| 54 if (focused) | 43 if (focused) |
| 55 view_->RequestFocus(); | 44 view_->RequestFocus(); |
| 56 else if (view_->HasFocus()) | 45 else if (view_->HasFocus()) |
| 57 view_->GetFocusManager()->ClearFocus(); | 46 view_->GetFocusManager()->ClearFocus(); |
| 58 return true; | 47 return true; |
| 59 } | 48 } |
| 60 | 49 |
| 61 // ui::AXPlatformNodeDelegate | 50 // ui::AXPlatformNodeDelegate |
| 62 | 51 |
| 63 const ui::AXNodeData& NativeViewAccessibility::GetData() { | 52 const ui::AXNodeData& NativeViewAccessibilityBase::GetData() { |
| 64 data_ = ui::AXNodeData(); | 53 data_ = ui::AXNodeData(); |
| 65 data_.state = 0; | 54 data_.state = 0; |
| 66 | 55 |
| 67 // Views may misbehave if their widget is closed; return an unknown role | 56 // Views may misbehave if their widget is closed; return an unknown role |
| 68 // rather than possibly crashing. | 57 // rather than possibly crashing. |
| 69 if (!view_->GetWidget() || view_->GetWidget()->IsClosed()) { | 58 if (!view_->GetWidget() || view_->GetWidget()->IsClosed()) { |
| 70 data_.role = ui::AX_ROLE_UNKNOWN; | 59 data_.role = ui::AX_ROLE_UNKNOWN; |
| 71 data_.state = 1 << ui::AX_STATE_DISABLED; | 60 data_.state = 1 << ui::AX_STATE_DISABLED; |
| 72 return data_; | 61 return data_; |
| 73 } | 62 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 84 | 73 |
| 85 if (!view_->enabled()) | 74 if (!view_->enabled()) |
| 86 data_.state |= (1 << ui::AX_STATE_DISABLED); | 75 data_.state |= (1 << ui::AX_STATE_DISABLED); |
| 87 | 76 |
| 88 if (!view_->IsDrawn()) | 77 if (!view_->IsDrawn()) |
| 89 data_.state |= (1 << ui::AX_STATE_INVISIBLE); | 78 data_.state |= (1 << ui::AX_STATE_INVISIBLE); |
| 90 | 79 |
| 91 return data_; | 80 return data_; |
| 92 } | 81 } |
| 93 | 82 |
| 94 int NativeViewAccessibility::GetChildCount() { | 83 int NativeViewAccessibilityBase::GetChildCount() { |
| 95 int child_count = view_->child_count(); | 84 int child_count = view_->child_count(); |
| 96 | 85 |
| 97 std::vector<Widget*> child_widgets; | 86 std::vector<Widget*> child_widgets; |
| 98 PopulateChildWidgetVector(&child_widgets); | 87 PopulateChildWidgetVector(&child_widgets); |
| 99 child_count += child_widgets.size(); | 88 child_count += child_widgets.size(); |
| 100 | 89 |
| 101 return child_count; | 90 return child_count; |
| 102 } | 91 } |
| 103 | 92 |
| 104 gfx::NativeViewAccessible NativeViewAccessibility::ChildAtIndex(int index) { | 93 gfx::NativeViewAccessible NativeViewAccessibilityBase::ChildAtIndex(int index) { |
| 105 // If this is a root view, our widget might have child widgets. Include | 94 // If this is a root view, our widget might have child widgets. Include |
| 106 std::vector<Widget*> child_widgets; | 95 std::vector<Widget*> child_widgets; |
| 107 PopulateChildWidgetVector(&child_widgets); | 96 PopulateChildWidgetVector(&child_widgets); |
| 108 int child_widget_count = static_cast<int>(child_widgets.size()); | 97 int child_widget_count = static_cast<int>(child_widgets.size()); |
| 109 | 98 |
| 110 if (index < view_->child_count()) { | 99 if (index < view_->child_count()) { |
| 111 return view_->child_at(index)->GetNativeViewAccessible(); | 100 return view_->child_at(index)->GetNativeViewAccessible(); |
| 112 } else if (index < view_->child_count() + child_widget_count) { | 101 } else if (index < view_->child_count() + child_widget_count) { |
| 113 Widget* child_widget = child_widgets[index - view_->child_count()]; | 102 Widget* child_widget = child_widgets[index - view_->child_count()]; |
| 114 return child_widget->GetRootView()->GetNativeViewAccessible(); | 103 return child_widget->GetRootView()->GetNativeViewAccessible(); |
| 115 } | 104 } |
| 116 | 105 |
| 117 return nullptr; | 106 return nullptr; |
| 118 } | 107 } |
| 119 | 108 |
| 120 gfx::NativeWindow NativeViewAccessibility::GetTopLevelWidget() { | 109 gfx::NativeWindow NativeViewAccessibilityBase::GetTopLevelWidget() { |
| 121 if (view_->GetWidget()) | 110 if (view_->GetWidget()) |
| 122 return view_->GetWidget()->GetTopLevelWidget()->GetNativeWindow(); | 111 return view_->GetWidget()->GetTopLevelWidget()->GetNativeWindow(); |
| 123 return nullptr; | 112 return nullptr; |
| 124 } | 113 } |
| 125 | 114 |
| 126 gfx::NativeViewAccessible NativeViewAccessibility::GetParent() { | 115 gfx::NativeViewAccessible NativeViewAccessibilityBase::GetParent() { |
| 127 if (view_->parent()) | 116 if (view_->parent()) |
| 128 return view_->parent()->GetNativeViewAccessible(); | 117 return view_->parent()->GetNativeViewAccessible(); |
| 129 | 118 |
| 130 if (parent_widget_) | 119 if (parent_widget_) |
| 131 return parent_widget_->GetRootView()->GetNativeViewAccessible(); | 120 return parent_widget_->GetRootView()->GetNativeViewAccessible(); |
| 132 | 121 |
| 133 return nullptr; | 122 return nullptr; |
| 134 } | 123 } |
| 135 | 124 |
| 136 gfx::Vector2d NativeViewAccessibility::GetGlobalCoordinateOffset() { | 125 gfx::Vector2d NativeViewAccessibilityBase::GetGlobalCoordinateOffset() { |
| 137 return gfx::Vector2d(0, 0); // location is already in screen coordinates. | 126 return gfx::Vector2d(0, 0); // location is already in screen coordinates. |
| 138 } | 127 } |
| 139 | 128 |
| 140 gfx::NativeViewAccessible NativeViewAccessibility::HitTestSync(int x, int y) { | 129 gfx::NativeViewAccessible NativeViewAccessibilityBase::HitTestSync(int x, |
| 130 int y) { |
| 141 if (!view_ || !view_->GetWidget()) | 131 if (!view_ || !view_->GetWidget()) |
| 142 return nullptr; | 132 return nullptr; |
| 143 | 133 |
| 144 // Search child widgets first, since they're on top in the z-order. | 134 // Search child widgets first, since they're on top in the z-order. |
| 145 std::vector<Widget*> child_widgets; | 135 std::vector<Widget*> child_widgets; |
| 146 PopulateChildWidgetVector(&child_widgets); | 136 PopulateChildWidgetVector(&child_widgets); |
| 147 for (Widget* child_widget : child_widgets) { | 137 for (Widget* child_widget : child_widgets) { |
| 148 View* child_root_view = child_widget->GetRootView(); | 138 View* child_root_view = child_widget->GetRootView(); |
| 149 gfx::Point point(x, y); | 139 gfx::Point point(x, y); |
| 150 View::ConvertPointFromScreen(child_root_view, &point); | 140 View::ConvertPointFromScreen(child_root_view, &point); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 168 gfx::Point point_in_child_coords(point); | 158 gfx::Point point_in_child_coords(point); |
| 169 view_->ConvertPointToTarget(view_, child_view, &point_in_child_coords); | 159 view_->ConvertPointToTarget(view_, child_view, &point_in_child_coords); |
| 170 if (child_view->HitTestPoint(point_in_child_coords)) | 160 if (child_view->HitTestPoint(point_in_child_coords)) |
| 171 return child_view->GetNativeViewAccessible(); | 161 return child_view->GetNativeViewAccessible(); |
| 172 } | 162 } |
| 173 | 163 |
| 174 // If it's not inside any of our children, it's inside this view. | 164 // If it's not inside any of our children, it's inside this view. |
| 175 return GetNativeObject(); | 165 return GetNativeObject(); |
| 176 } | 166 } |
| 177 | 167 |
| 178 gfx::NativeViewAccessible NativeViewAccessibility::GetFocus() { | 168 gfx::NativeViewAccessible NativeViewAccessibilityBase::GetFocus() { |
| 179 FocusManager* focus_manager = view_->GetFocusManager(); | 169 FocusManager* focus_manager = view_->GetFocusManager(); |
| 180 View* focused_view = | 170 View* focused_view = |
| 181 focus_manager ? focus_manager->GetFocusedView() : nullptr; | 171 focus_manager ? focus_manager->GetFocusedView() : nullptr; |
| 182 return focused_view ? focused_view->GetNativeViewAccessible() : nullptr; | 172 return focused_view ? focused_view->GetNativeViewAccessible() : nullptr; |
| 183 } | 173 } |
| 184 | 174 |
| 185 gfx::AcceleratedWidget | 175 gfx::AcceleratedWidget |
| 186 NativeViewAccessibility::GetTargetForNativeAccessibilityEvent() { | 176 NativeViewAccessibilityBase::GetTargetForNativeAccessibilityEvent() { |
| 187 return gfx::kNullAcceleratedWidget; | 177 return gfx::kNullAcceleratedWidget; |
| 188 } | 178 } |
| 189 | 179 |
| 190 bool NativeViewAccessibility::AccessibilityPerformAction( | 180 bool NativeViewAccessibilityBase::AccessibilityPerformAction( |
| 191 const ui::AXActionData& data) { | 181 const ui::AXActionData& data) { |
| 192 switch (data.action) { | 182 switch (data.action) { |
| 193 // Handle accessible actions that apply to all Views here. | 183 // Handle accessible actions that apply to all Views here. |
| 194 case ui::AX_ACTION_DO_DEFAULT: | 184 case ui::AX_ACTION_DO_DEFAULT: |
| 195 DoDefaultAction(); | 185 DoDefaultAction(); |
| 196 return true; | 186 return true; |
| 197 case ui::AX_ACTION_FOCUS: | 187 case ui::AX_ACTION_FOCUS: |
| 198 return SetFocused(true); | 188 return SetFocused(true); |
| 199 case ui::AX_ACTION_BLUR: | 189 case ui::AX_ACTION_BLUR: |
| 200 return SetFocused(false); | 190 return SetFocused(false); |
| 201 | 191 |
| 202 case ui::AX_ACTION_NONE: | 192 case ui::AX_ACTION_NONE: |
| 203 NOTREACHED(); | 193 NOTREACHED(); |
| 204 break; | 194 break; |
| 205 | 195 |
| 206 // All other actions can potentially be dealt with by the View itself. | 196 // All other actions can potentially be dealt with by the View itself. |
| 207 default: | 197 default: |
| 208 return view_->HandleAccessibleAction(data); | 198 return view_->HandleAccessibleAction(data); |
| 209 break; | 199 break; |
| 210 } | 200 } |
| 211 return false; | 201 return false; |
| 212 } | 202 } |
| 213 | 203 |
| 214 void NativeViewAccessibility::DoDefaultAction() { | 204 void NativeViewAccessibilityBase::DoDefaultAction() { |
| 215 gfx::Point center = view_->GetLocalBounds().CenterPoint(); | 205 gfx::Point center = view_->GetLocalBounds().CenterPoint(); |
| 216 view_->OnMousePressed(ui::MouseEvent(ui::ET_MOUSE_PRESSED, | 206 view_->OnMousePressed(ui::MouseEvent( |
| 217 center, | 207 ui::ET_MOUSE_PRESSED, center, center, ui::EventTimeForNow(), |
| 218 center, | 208 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); |
| 219 ui::EventTimeForNow(), | 209 view_->OnMouseReleased(ui::MouseEvent( |
| 220 ui::EF_LEFT_MOUSE_BUTTON, | 210 ui::ET_MOUSE_RELEASED, center, center, ui::EventTimeForNow(), |
| 221 ui::EF_LEFT_MOUSE_BUTTON)); | 211 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); |
| 222 view_->OnMouseReleased(ui::MouseEvent(ui::ET_MOUSE_RELEASED, | |
| 223 center, | |
| 224 center, | |
| 225 ui::EventTimeForNow(), | |
| 226 ui::EF_LEFT_MOUSE_BUTTON, | |
| 227 ui::EF_LEFT_MOUSE_BUTTON)); | |
| 228 } | 212 } |
| 229 | 213 |
| 230 void NativeViewAccessibility::OnWidgetDestroying(Widget* widget) { | 214 void NativeViewAccessibilityBase::OnWidgetDestroying(Widget* widget) { |
| 231 if (parent_widget_ == widget) { | 215 if (parent_widget_ == widget) { |
| 232 parent_widget_->RemoveObserver(this); | 216 parent_widget_->RemoveObserver(this); |
| 233 parent_widget_ = nullptr; | 217 parent_widget_ = nullptr; |
| 234 } | 218 } |
| 235 } | 219 } |
| 236 | 220 |
| 237 void NativeViewAccessibility::SetParentWidget(Widget* parent_widget) { | 221 void NativeViewAccessibilityBase::SetParentWidget(Widget* parent_widget) { |
| 238 if (parent_widget_) | 222 if (parent_widget_) |
| 239 parent_widget_->RemoveObserver(this); | 223 parent_widget_->RemoveObserver(this); |
| 240 parent_widget_ = parent_widget; | 224 parent_widget_ = parent_widget; |
| 241 parent_widget_->AddObserver(this); | 225 parent_widget_->AddObserver(this); |
| 242 } | 226 } |
| 243 | 227 |
| 244 void NativeViewAccessibility::PopulateChildWidgetVector( | 228 void NativeViewAccessibilityBase::PopulateChildWidgetVector( |
| 245 std::vector<Widget*>* result_child_widgets) { | 229 std::vector<Widget*>* result_child_widgets) { |
| 246 // Only attach child widgets to the root view. | 230 // Only attach child widgets to the root view. |
| 247 Widget* widget = view_->GetWidget(); | 231 Widget* widget = view_->GetWidget(); |
| 248 // Note that during window close, a Widget may exist in a state where it has | 232 // Note that during window close, a Widget may exist in a state where it has |
| 249 // no NativeView, but hasn't yet torn down its view hierarchy. | 233 // no NativeView, but hasn't yet torn down its view hierarchy. |
| 250 if (!widget || !widget->GetNativeView() || widget->GetRootView() != view_) | 234 if (!widget || !widget->GetNativeView() || widget->GetRootView() != view_) |
| 251 return; | 235 return; |
| 252 | 236 |
| 253 std::set<Widget*> child_widgets; | 237 std::set<Widget*> child_widgets; |
| 254 Widget::GetAllOwnedWidgets(widget->GetNativeView(), &child_widgets); | 238 Widget::GetAllOwnedWidgets(widget->GetNativeView(), &child_widgets); |
| 255 for (auto iter = child_widgets.begin(); iter != child_widgets.end(); ++iter) { | 239 for (auto iter = child_widgets.begin(); iter != child_widgets.end(); ++iter) { |
| 256 Widget* child_widget = *iter; | 240 Widget* child_widget = *iter; |
| 257 DCHECK_NE(widget, child_widget); | 241 DCHECK_NE(widget, child_widget); |
| 258 | 242 |
| 259 if (!child_widget->IsVisible()) | 243 if (!child_widget->IsVisible()) |
| 260 continue; | 244 continue; |
| 261 | 245 |
| 262 if (widget->GetNativeWindowProperty(kWidgetNativeViewHostKey)) | 246 if (widget->GetNativeWindowProperty(kWidgetNativeViewHostKey)) |
| 263 continue; | 247 continue; |
| 264 | 248 |
| 265 gfx::NativeViewAccessible child_widget_accessible = | 249 gfx::NativeViewAccessible child_widget_accessible = |
| 266 child_widget->GetRootView()->GetNativeViewAccessible(); | 250 child_widget->GetRootView()->GetNativeViewAccessible(); |
| 267 ui::AXPlatformNode* child_widget_platform_node = | 251 ui::AXPlatformNode* child_widget_platform_node = |
| 268 ui::AXPlatformNode::FromNativeViewAccessible(child_widget_accessible); | 252 ui::AXPlatformNode::FromNativeViewAccessible(child_widget_accessible); |
| 269 if (child_widget_platform_node) { | 253 if (child_widget_platform_node) { |
| 270 NativeViewAccessibility* child_widget_view_accessibility = | 254 NativeViewAccessibilityBase* child_widget_view_accessibility = |
| 271 static_cast<NativeViewAccessibility*>( | 255 static_cast<NativeViewAccessibilityBase*>( |
| 272 child_widget_platform_node->GetDelegate()); | 256 child_widget_platform_node->GetDelegate()); |
| 273 if (child_widget_view_accessibility->parent_widget() != widget) | 257 if (child_widget_view_accessibility->parent_widget() != widget) |
| 274 child_widget_view_accessibility->SetParentWidget(widget); | 258 child_widget_view_accessibility->SetParentWidget(widget); |
| 275 } | 259 } |
| 276 | 260 |
| 277 result_child_widgets->push_back(child_widget); | 261 result_child_widgets->push_back(child_widget); |
| 278 } | 262 } |
| 279 } | 263 } |
| 280 | 264 |
| 281 } // namespace views | 265 } // namespace views |
| OLD | NEW |