| 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 |