OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "ui/views/accessibility/native_view_accessibility_auralinux.h" | |
6 | |
7 #include <algorithm> | |
8 #include <vector> | |
9 | |
10 #include "base/memory/singleton.h" | |
11 #include "ui/accessibility/ax_enums.h" | |
12 #include "ui/accessibility/ax_node_data.h" | |
13 #include "ui/accessibility/platform/ax_platform_node_auralinux.h" | |
14 #include "ui/accessibility/platform/ax_platform_node_delegate.h" | |
15 #include "ui/gfx/native_widget_types.h" | |
16 #include "ui/views/views_delegate.h" | |
17 #include "ui/views/widget/widget.h" | |
18 #include "ui/views/widget/widget_observer.h" | |
19 | |
20 namespace views { | |
21 | |
22 namespace { | |
23 | |
24 // ATK requires that we have a single root "application" object that's the | |
25 // owner of all other windows. This is a simple class that implements the | |
26 // AXPlatformNodeDelegate interface so we can create such an application | |
27 // object. Every time we create an accessibility object for a View, we add its | |
28 // top-level widget to a vector so we can return the list of all top-level | |
29 // windows as children of this application object. | |
30 class AuraLinuxApplication | |
31 : public ui::AXPlatformNodeDelegate, | |
32 public WidgetObserver { | |
33 public: | |
34 // Get the single instance of this class. | |
35 static AuraLinuxApplication* GetInstance() { | |
36 return Singleton<AuraLinuxApplication>::get(); | |
37 } | |
38 | |
39 // Called every time we create a new accessibility on a View. | |
40 // Add the top-level widget to our registry so that we can enumerate all | |
41 // top-level widgets. | |
42 void RegisterWidget(Widget* widget) { | |
43 if (!widget) | |
44 return; | |
45 | |
46 widget = widget->GetTopLevelWidget(); | |
47 if (std::find(widgets_.begin(), widgets_.end(), widget) != widgets_.end()) | |
48 return; | |
49 | |
50 widgets_.push_back(widget); | |
51 widget->AddObserver(this); | |
52 } | |
53 | |
54 gfx::NativeViewAccessible GetNativeViewAccessible() { | |
55 return platform_node_->GetNativeViewAccessible(); | |
56 } | |
57 | |
58 // | |
59 // WidgetObserver overrides. | |
60 // | |
61 | |
62 void OnWidgetDestroying(Widget* widget) override { | |
63 auto iter = std::find(widgets_.begin(), widgets_.end(), widget); | |
64 if (iter != widgets_.end()) | |
65 widgets_.erase(iter); | |
66 } | |
67 | |
68 // | |
69 // ui::AXPlatformNodeDelegate overrides. | |
70 // | |
71 | |
72 const ui::AXNodeData& GetData() override { | |
73 return data_; | |
74 } | |
75 | |
76 gfx::NativeViewAccessible GetParent() override { | |
77 return nullptr; | |
78 } | |
79 | |
80 int GetChildCount() override { | |
81 return static_cast<int>(widgets_.size()); | |
82 } | |
83 | |
84 gfx::NativeViewAccessible ChildAtIndex(int index) override { | |
85 if (index < 0 || index >= GetChildCount()) | |
86 return nullptr; | |
87 | |
88 Widget* widget = widgets_[index]; | |
89 CHECK(widget); | |
90 View* root_view = widget->GetRootView(); | |
91 if (!root_view) | |
sky
2015/03/11 23:05:57
Can this really happen?
dmazzoni
2015/03/11 23:38:55
Removed.
| |
92 return nullptr; | |
93 return root_view->GetNativeViewAccessible(); | |
94 } | |
95 | |
96 gfx::Vector2d GetGlobalCoordinateOffset() override { | |
97 return gfx::Vector2d(); | |
98 } | |
99 | |
100 gfx::NativeViewAccessible HitTestSync(int x, int y) override { | |
101 return nullptr; | |
102 } | |
103 | |
104 gfx::NativeViewAccessible GetFocus() override { | |
105 return nullptr; | |
106 } | |
107 | |
108 gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override { | |
109 return gfx::kNullAcceleratedWidget; | |
110 } | |
111 | |
112 void DoDefaultAction() override { | |
113 } | |
114 | |
115 bool SetStringValue(const base::string16& new_value) override { | |
116 return false; | |
117 } | |
118 | |
119 private: | |
120 friend struct DefaultSingletonTraits<AuraLinuxApplication>; | |
121 | |
122 AuraLinuxApplication() { | |
123 data_.role = ui::AX_ROLE_APPLICATION; | |
124 if (ViewsDelegate::views_delegate) { | |
125 data_.AddStringAttribute( | |
126 ui::AX_ATTR_NAME, | |
127 ViewsDelegate::views_delegate->GetApplicationName()); | |
128 } | |
129 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.
| |
130 ui::AXPlatformNodeAuraLinux::SetApplication(platform_node_); | |
131 } | |
132 | |
133 ~AuraLinuxApplication() override { | |
134 platform_node_->Destroy(); | |
135 platform_node_ = nullptr; | |
136 } | |
137 | |
138 ui::AXPlatformNode* platform_node_; | |
139 ui::AXNodeData data_; | |
140 std::vector<Widget*> widgets_; | |
141 }; | |
sky
2015/03/11 23:05:56
DISALLOW..
dmazzoni
2015/03/11 23:38:56
Done.
| |
142 | |
143 } // namespace | |
144 | |
145 // static | |
146 NativeViewAccessibility* NativeViewAccessibility::Create(View* view) { | |
147 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
| |
148 return new NativeViewAccessibilityAuraLinux(view); | |
149 } | |
150 | |
151 NativeViewAccessibilityAuraLinux::NativeViewAccessibilityAuraLinux(View* view) | |
152 : NativeViewAccessibility(view) { | |
153 } | |
154 | |
155 NativeViewAccessibilityAuraLinux::~NativeViewAccessibilityAuraLinux() { | |
156 } | |
157 | |
158 gfx::NativeViewAccessible NativeViewAccessibilityAuraLinux::GetParent() { | |
159 gfx::NativeViewAccessible parent = NativeViewAccessibility::GetParent(); | |
160 if (!parent) | |
161 parent = AuraLinuxApplication::GetInstance()->GetNativeViewAccessible(); | |
162 return parent; | |
163 } | |
164 | |
165 } // namespace views | |
OLD | NEW |