Chromium Code Reviews| Index: ui/views/accessibility/native_view_accessibility_auralinux.cc |
| diff --git a/ui/views/accessibility/native_view_accessibility_auralinux.cc b/ui/views/accessibility/native_view_accessibility_auralinux.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..fcca85a5bc836d30fe6046e393852d05bc3ee37e |
| --- /dev/null |
| +++ b/ui/views/accessibility/native_view_accessibility_auralinux.cc |
| @@ -0,0 +1,165 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "ui/views/accessibility/native_view_accessibility_auralinux.h" |
| + |
| +#include <algorithm> |
| +#include <vector> |
| + |
| +#include "base/memory/singleton.h" |
| +#include "ui/accessibility/ax_enums.h" |
| +#include "ui/accessibility/ax_node_data.h" |
| +#include "ui/accessibility/platform/ax_platform_node_auralinux.h" |
| +#include "ui/accessibility/platform/ax_platform_node_delegate.h" |
| +#include "ui/gfx/native_widget_types.h" |
| +#include "ui/views/views_delegate.h" |
| +#include "ui/views/widget/widget.h" |
| +#include "ui/views/widget/widget_observer.h" |
| + |
| +namespace views { |
| + |
| +namespace { |
| + |
| +// ATK requires that we have a single root "application" object that's the |
| +// owner of all other windows. This is a simple class that implements the |
| +// AXPlatformNodeDelegate interface so we can create such an application |
| +// object. Every time we create an accessibility object for a View, we add its |
| +// top-level widget to a vector so we can return the list of all top-level |
| +// windows as children of this application object. |
| +class AuraLinuxApplication |
| + : public ui::AXPlatformNodeDelegate, |
| + public WidgetObserver { |
| + public: |
| + // Get the single instance of this class. |
| + static AuraLinuxApplication* GetInstance() { |
| + return Singleton<AuraLinuxApplication>::get(); |
| + } |
| + |
| + // Called every time we create a new accessibility on a View. |
| + // Add the top-level widget to our registry so that we can enumerate all |
| + // top-level widgets. |
| + void RegisterWidget(Widget* widget) { |
| + if (!widget) |
| + return; |
| + |
| + widget = widget->GetTopLevelWidget(); |
| + if (std::find(widgets_.begin(), widgets_.end(), widget) != widgets_.end()) |
| + return; |
| + |
| + widgets_.push_back(widget); |
| + widget->AddObserver(this); |
| + } |
| + |
| + gfx::NativeViewAccessible GetNativeViewAccessible() { |
| + return platform_node_->GetNativeViewAccessible(); |
| + } |
| + |
| + // |
| + // WidgetObserver overrides. |
| + // |
| + |
| + void OnWidgetDestroying(Widget* widget) override { |
| + auto iter = std::find(widgets_.begin(), widgets_.end(), widget); |
| + if (iter != widgets_.end()) |
| + widgets_.erase(iter); |
| + } |
| + |
| + // |
| + // ui::AXPlatformNodeDelegate overrides. |
| + // |
| + |
| + const ui::AXNodeData& GetData() override { |
| + return data_; |
| + } |
| + |
| + gfx::NativeViewAccessible GetParent() override { |
| + return nullptr; |
| + } |
| + |
| + int GetChildCount() override { |
| + return static_cast<int>(widgets_.size()); |
| + } |
| + |
| + gfx::NativeViewAccessible ChildAtIndex(int index) override { |
| + if (index < 0 || index >= GetChildCount()) |
| + return nullptr; |
| + |
| + Widget* widget = widgets_[index]; |
| + CHECK(widget); |
| + View* root_view = widget->GetRootView(); |
| + if (!root_view) |
|
sky
2015/03/11 23:05:57
Can this really happen?
dmazzoni
2015/03/11 23:38:55
Removed.
|
| + return nullptr; |
| + return root_view->GetNativeViewAccessible(); |
| + } |
| + |
| + gfx::Vector2d GetGlobalCoordinateOffset() override { |
| + return gfx::Vector2d(); |
| + } |
| + |
| + gfx::NativeViewAccessible HitTestSync(int x, int y) override { |
| + return nullptr; |
| + } |
| + |
| + gfx::NativeViewAccessible GetFocus() override { |
| + return nullptr; |
| + } |
| + |
| + gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override { |
| + return gfx::kNullAcceleratedWidget; |
| + } |
| + |
| + void DoDefaultAction() override { |
| + } |
| + |
| + bool SetStringValue(const base::string16& new_value) override { |
| + return false; |
| + } |
| + |
| + private: |
| + friend struct DefaultSingletonTraits<AuraLinuxApplication>; |
| + |
| + AuraLinuxApplication() { |
| + data_.role = ui::AX_ROLE_APPLICATION; |
| + if (ViewsDelegate::views_delegate) { |
| + data_.AddStringAttribute( |
| + ui::AX_ATTR_NAME, |
| + ViewsDelegate::views_delegate->GetApplicationName()); |
| + } |
| + platform_node_ = ui::AXPlatformNode::Create(this); |
|
sky
2015/03/11 23:05:56
move to initializer list?
dmazzoni
2015/03/11 23:38:55
Done.
|
| + ui::AXPlatformNodeAuraLinux::SetApplication(platform_node_); |
| + } |
| + |
| + ~AuraLinuxApplication() override { |
| + platform_node_->Destroy(); |
| + platform_node_ = nullptr; |
| + } |
| + |
| + ui::AXPlatformNode* platform_node_; |
| + ui::AXNodeData data_; |
| + std::vector<Widget*> widgets_; |
| +}; |
|
sky
2015/03/11 23:05:56
DISALLOW..
dmazzoni
2015/03/11 23:38:56
Done.
|
| + |
| +} // namespace |
| + |
| +// static |
| +NativeViewAccessibility* NativeViewAccessibility::Create(View* view) { |
| + AuraLinuxApplication::GetInstance()->RegisterWidget(view->GetWidget()); |
|
sky
2015/03/11 23:05:56
When is Create() called? If there is no widget at
dmazzoni
2015/03/11 23:38:56
This is typically called as a result of View::Noti
|
| + return new NativeViewAccessibilityAuraLinux(view); |
| +} |
| + |
| +NativeViewAccessibilityAuraLinux::NativeViewAccessibilityAuraLinux(View* view) |
| + : NativeViewAccessibility(view) { |
| +} |
| + |
| +NativeViewAccessibilityAuraLinux::~NativeViewAccessibilityAuraLinux() { |
| +} |
| + |
| +gfx::NativeViewAccessible NativeViewAccessibilityAuraLinux::GetParent() { |
| + gfx::NativeViewAccessible parent = NativeViewAccessibility::GetParent(); |
| + if (!parent) |
| + parent = AuraLinuxApplication::GetInstance()->GetNativeViewAccessible(); |
| + return parent; |
| +} |
| + |
| +} // namespace views |