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/mus/window_manager_connection.h" | |
6 | |
7 #include <algorithm> | |
8 #include <set> | |
9 #include <utility> | |
10 | |
11 #include "base/lazy_instance.h" | |
12 #include "base/memory/ptr_util.h" | |
13 #include "base/threading/thread_local.h" | |
14 #include "services/service_manager/public/cpp/connection.h" | |
15 #include "services/service_manager/public/cpp/connector.h" | |
16 #include "services/ui/public/cpp/gpu/gpu.h" | |
17 #include "services/ui/public/cpp/property_type_converters.h" | |
18 #include "services/ui/public/cpp/window.h" | |
19 #include "services/ui/public/cpp/window_property.h" | |
20 #include "services/ui/public/cpp/window_tree_client.h" | |
21 #include "services/ui/public/interfaces/event_matcher.mojom.h" | |
22 #include "services/ui/public/interfaces/window_tree.mojom.h" | |
23 #include "ui/aura/env.h" | |
24 #include "ui/aura/mus/os_exchange_data_provider_mus.h" | |
25 #include "ui/views/mus/clipboard_mus.h" | |
26 #include "ui/views/mus/native_widget_mus.h" | |
27 #include "ui/views/mus/pointer_watcher_event_router.h" | |
28 #include "ui/views/mus/screen_mus.h" | |
29 #include "ui/views/mus/surface_context_factory.h" | |
30 #include "ui/views/pointer_watcher.h" | |
31 #include "ui/views/views_delegate.h" | |
32 | |
33 namespace views { | |
34 namespace { | |
35 | |
36 using WindowManagerConnectionPtr = | |
37 base::ThreadLocalPointer<views::WindowManagerConnection>; | |
38 | |
39 // Env is thread local so that aura may be used on multiple threads. | |
40 base::LazyInstance<WindowManagerConnectionPtr>::Leaky lazy_tls_ptr = | |
41 LAZY_INSTANCE_INITIALIZER; | |
42 | |
43 // Recursively finds the deepest visible window from |windows| that contains | |
44 // |screen_point|, when offsetting by the display origins from | |
45 // |display_origins|. | |
46 ui::Window* GetWindowFrom(const std::map<int64_t, gfx::Point>& display_origins, | |
47 const std::vector<ui::Window*>& windows, | |
48 const gfx::Point& screen_point) { | |
49 for (ui::Window* window : windows) { | |
50 if (!window->visible()) | |
51 continue; | |
52 | |
53 auto it = display_origins.find(window->display_id()); | |
54 if (it == display_origins.end()) | |
55 continue; | |
56 | |
57 gfx::Rect bounds_in_screen = window->GetBoundsInRoot(); | |
58 bounds_in_screen.Offset(it->second.x(), it->second.y()); | |
59 | |
60 if (bounds_in_screen.Contains(screen_point)) { | |
61 if (!window->children().empty()) { | |
62 ui::Window* child = | |
63 GetWindowFrom(display_origins, window->children(), screen_point); | |
64 if (child) | |
65 return child; | |
66 } | |
67 | |
68 return window; | |
69 } | |
70 } | |
71 return nullptr; | |
72 } | |
73 | |
74 aura::Window* GetAuraWindowFromUiWindow(ui::Window* window) { | |
75 if (!window) | |
76 return nullptr; | |
77 NativeWidgetMus* nw_mus = NativeWidgetMus::GetForWindow(window); | |
78 return nw_mus | |
79 ? static_cast<internal::NativeWidgetPrivate*>(nw_mus) | |
80 ->GetNativeView() | |
81 : nullptr; | |
82 } | |
83 | |
84 } // namespace | |
85 | |
86 WindowManagerConnection::~WindowManagerConnection() { | |
87 // ~WindowTreeClient calls back to us (we're its delegate), destroy it while | |
88 // we are still valid. | |
89 client_.reset(); | |
90 ui::OSExchangeDataProviderFactory::SetFactory(nullptr); | |
91 ui::Clipboard::DestroyClipboardForCurrentThread(); | |
92 gpu_.reset(); | |
93 lazy_tls_ptr.Pointer()->Set(nullptr); | |
94 | |
95 if (ViewsDelegate::GetInstance()) { | |
96 ViewsDelegate::GetInstance()->set_native_widget_factory( | |
97 ViewsDelegate::NativeWidgetFactory()); | |
98 } | |
99 } | |
100 | |
101 // static | |
102 std::unique_ptr<WindowManagerConnection> WindowManagerConnection::Create( | |
103 service_manager::Connector* connector, | |
104 const service_manager::Identity& identity, | |
105 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { | |
106 DCHECK(!lazy_tls_ptr.Pointer()->Get()); | |
107 WindowManagerConnection* connection = | |
108 new WindowManagerConnection(connector, identity, std::move(task_runner)); | |
109 DCHECK(lazy_tls_ptr.Pointer()->Get()); | |
110 return base::WrapUnique(connection); | |
111 } | |
112 | |
113 // static | |
114 WindowManagerConnection* WindowManagerConnection::Get() { | |
115 WindowManagerConnection* connection = lazy_tls_ptr.Pointer()->Get(); | |
116 DCHECK(connection); | |
117 return connection; | |
118 } | |
119 | |
120 // static | |
121 bool WindowManagerConnection::Exists() { | |
122 return !!lazy_tls_ptr.Pointer()->Get(); | |
123 } | |
124 | |
125 ui::Window* WindowManagerConnection::NewTopLevelWindow( | |
126 const std::map<std::string, std::vector<uint8_t>>& properties) { | |
127 return client_->NewTopLevelWindow(&properties); | |
128 } | |
129 | |
130 NativeWidget* WindowManagerConnection::CreateNativeWidgetMus( | |
131 const std::map<std::string, std::vector<uint8_t>>& props, | |
132 const Widget::InitParams& init_params, | |
133 internal::NativeWidgetDelegate* delegate) { | |
134 // TYPE_CONTROL widgets require a NativeWidgetAura. So we let this fall | |
135 // through, so that the default NativeWidgetPrivate::CreateNativeWidget() is | |
136 // used instead. | |
137 if (init_params.type == Widget::InitParams::TYPE_CONTROL) | |
138 return nullptr; | |
139 std::map<std::string, std::vector<uint8_t>> properties = props; | |
140 NativeWidgetMus::ConfigurePropertiesForNewWindow(init_params, &properties); | |
141 properties[ui::mojom::WindowManager::kAppID_Property] = | |
142 mojo::ConvertTo<std::vector<uint8_t>>(identity_.name()); | |
143 return new NativeWidgetMus(delegate, NewTopLevelWindow(properties), | |
144 ui::mojom::CompositorFrameSinkType::DEFAULT); | |
145 } | |
146 | |
147 const std::set<ui::Window*>& WindowManagerConnection::GetRoots() const { | |
148 return client_->GetRoots(); | |
149 } | |
150 | |
151 WindowManagerConnection::WindowManagerConnection( | |
152 service_manager::Connector* connector, | |
153 const service_manager::Identity& identity, | |
154 scoped_refptr<base::SingleThreadTaskRunner> task_runner) | |
155 : connector_(connector), identity_(identity) { | |
156 lazy_tls_ptr.Pointer()->Set(this); | |
157 | |
158 gpu_ = ui::Gpu::Create(connector, std::move(task_runner)); | |
159 compositor_context_factory_ = | |
160 base::MakeUnique<views::SurfaceContextFactory>(gpu_.get()); | |
161 aura::Env::GetInstance()->set_context_factory( | |
162 compositor_context_factory_.get()); | |
163 client_ = base::MakeUnique<ui::WindowTreeClient>(this, nullptr, nullptr); | |
164 client_->ConnectViaWindowTreeFactory(connector_); | |
165 | |
166 pointer_watcher_event_router_ = | |
167 base::MakeUnique<PointerWatcherEventRouter>(client_.get()); | |
168 | |
169 screen_ = base::MakeUnique<ScreenMus>(this); | |
170 screen_->Init(connector); | |
171 | |
172 std::unique_ptr<ClipboardMus> clipboard = base::MakeUnique<ClipboardMus>(); | |
173 clipboard->Init(connector); | |
174 ui::Clipboard::SetClipboardForCurrentThread(std::move(clipboard)); | |
175 | |
176 ui::OSExchangeDataProviderFactory::SetFactory(this); | |
177 | |
178 ViewsDelegate::GetInstance()->set_native_widget_factory(base::Bind( | |
179 &WindowManagerConnection::CreateNativeWidgetMus, | |
180 base::Unretained(this), | |
181 std::map<std::string, std::vector<uint8_t>>())); | |
182 } | |
183 | |
184 ui::Window* WindowManagerConnection::GetUiWindowAtScreenPoint( | |
185 const gfx::Point& point) { | |
186 std::map<int64_t, gfx::Point> display_origins; | |
187 for (const display::Display& d : | |
188 display::Screen::GetScreen()->GetAllDisplays()) | |
189 display_origins[d.id()] = d.bounds().origin(); | |
190 | |
191 const std::set<ui::Window*>& roots = GetRoots(); | |
192 std::vector<ui::Window*> windows; | |
193 std::copy(roots.begin(), roots.end(), std::back_inserter(windows)); | |
194 return GetWindowFrom(display_origins, windows, point); | |
195 } | |
196 | |
197 void WindowManagerConnection::OnEmbed(ui::Window* root) {} | |
198 | |
199 void WindowManagerConnection::OnLostConnection(ui::WindowTreeClient* client) { | |
200 DCHECK_EQ(client, client_.get()); | |
201 client_.reset(); | |
202 } | |
203 | |
204 void WindowManagerConnection::OnEmbedRootDestroyed(ui::Window* root) { | |
205 // Not called for WindowManagerConnection as WindowTreeClient isn't created by | |
206 // way of an Embed(). | |
207 NOTREACHED(); | |
208 } | |
209 | |
210 void WindowManagerConnection::OnPointerEventObserved( | |
211 const ui::PointerEvent& event, | |
212 ui::Window* target) { | |
213 pointer_watcher_event_router_->OnPointerEventObserved(event, target); | |
214 } | |
215 | |
216 void WindowManagerConnection::OnWindowManagerFrameValuesChanged() { | |
217 if (client_) | |
218 NativeWidgetMus::NotifyFrameChanged(client_.get()); | |
219 } | |
220 | |
221 gfx::Point WindowManagerConnection::GetCursorScreenPoint() { | |
222 return client_->GetCursorScreenPoint(); | |
223 } | |
224 | |
225 aura::Window* WindowManagerConnection::GetWindowAtScreenPoint( | |
226 const gfx::Point& point) { | |
227 return GetAuraWindowFromUiWindow(GetUiWindowAtScreenPoint(point)); | |
228 } | |
229 | |
230 std::unique_ptr<OSExchangeData::Provider> | |
231 WindowManagerConnection::BuildProvider() { | |
232 return base::MakeUnique<aura::OSExchangeDataProviderMus>(); | |
233 } | |
234 | |
235 } // namespace views | |
OLD | NEW |