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..73deccb728fd67d63658ff67bb67b6707cc78527 |
--- /dev/null |
+++ b/ui/views/accessibility/native_view_accessibility_auralinux.cc |
@@ -0,0 +1,160 @@ |
+// 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/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()) |
Peter Lundblad
2015/03/11 14:58:21
Should be ||.
dmazzoni
2015/03/11 18:39:53
Good catch!
|
+ return nullptr; |
+ |
+ Widget* widget = widgets_[index]; |
+ CHECK(widget); |
+ View* root_view = widget->GetRootView(); |
+ if (!root_view) |
+ 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; |
+ data_.AddStringAttribute(ui::AX_ATTR_NAME, "Chrome"); |
Peter Lundblad
2015/03/11 14:58:21
Is this a UI string? If so, it should be set from
dmazzoni
2015/03/11 18:39:53
Not sure IDS_SHORT_PRODUCT_NAME is available from
|
+ platform_node_ = ui::AXPlatformNode::Create(this); |
+ ui::AXPlatformNodeAuraLinux::SetApplication(platform_node_); |
+ } |
+ |
+ ~AuraLinuxApplication() override { |
+ platform_node_->Destroy(); |
+ platform_node_ = nullptr; |
+ } |
+ |
+ ui::AXPlatformNode* platform_node_; |
+ ui::AXNodeData data_; |
+ std::vector<Widget*> widgets_; |
+}; |
+ |
+} // namespace |
+ |
+// static |
+NativeViewAccessibility* NativeViewAccessibility::Create(View* view) { |
+ AuraLinuxApplication::GetInstance()->RegisterWidget(view->GetWidget()); |
+ 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 |