| 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 "components/mus/ws/display.h" | |
| 6 | |
| 7 #include <set> | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/debug/debugger.h" | |
| 11 #include "base/strings/utf_string_conversions.h" | |
| 12 #include "components/mus/common/types.h" | |
| 13 #include "components/mus/ws/display_binding.h" | |
| 14 #include "components/mus/ws/display_manager.h" | |
| 15 #include "components/mus/ws/focus_controller.h" | |
| 16 #include "components/mus/ws/platform_display.h" | |
| 17 #include "components/mus/ws/platform_display_init_params.h" | |
| 18 #include "components/mus/ws/user_activity_monitor.h" | |
| 19 #include "components/mus/ws/window_manager_display_root.h" | |
| 20 #include "components/mus/ws/window_manager_state.h" | |
| 21 #include "components/mus/ws/window_manager_window_tree_factory.h" | |
| 22 #include "components/mus/ws/window_server.h" | |
| 23 #include "components/mus/ws/window_server_delegate.h" | |
| 24 #include "components/mus/ws/window_tree.h" | |
| 25 #include "components/mus/ws/window_tree_binding.h" | |
| 26 #include "mojo/common/common_type_converters.h" | |
| 27 #include "services/shell/public/interfaces/connector.mojom.h" | |
| 28 #include "ui/base/cursor/cursor.h" | |
| 29 | |
| 30 namespace mus { | |
| 31 namespace ws { | |
| 32 | |
| 33 Display::Display(WindowServer* window_server, | |
| 34 const PlatformDisplayInitParams& platform_display_init_params) | |
| 35 : id_(window_server->display_manager()->GetAndAdvanceNextDisplayId()), | |
| 36 window_server_(window_server), | |
| 37 platform_display_(PlatformDisplay::Create(platform_display_init_params)), | |
| 38 last_cursor_(ui::kCursorNone) { | |
| 39 platform_display_->Init(this); | |
| 40 | |
| 41 window_server_->window_manager_window_tree_factory_set()->AddObserver(this); | |
| 42 window_server_->user_id_tracker()->AddObserver(this); | |
| 43 } | |
| 44 | |
| 45 Display::~Display() { | |
| 46 window_server_->user_id_tracker()->RemoveObserver(this); | |
| 47 | |
| 48 window_server_->window_manager_window_tree_factory_set()->RemoveObserver( | |
| 49 this); | |
| 50 | |
| 51 if (!focus_controller_) { | |
| 52 focus_controller_->RemoveObserver(this); | |
| 53 focus_controller_.reset(); | |
| 54 } | |
| 55 | |
| 56 for (ServerWindow* window : windows_needing_frame_destruction_) | |
| 57 window->RemoveObserver(this); | |
| 58 | |
| 59 // If there is a |binding_| then the tree was created specifically for this | |
| 60 // display (which corresponds to a WindowTreeHost). | |
| 61 if (binding_ && !window_manager_display_root_map_.empty()) { | |
| 62 window_server_->DestroyTree(window_manager_display_root_map_.begin() | |
| 63 ->second->window_manager_state() | |
| 64 ->window_tree()); | |
| 65 } | |
| 66 } | |
| 67 | |
| 68 void Display::Init(std::unique_ptr<DisplayBinding> binding) { | |
| 69 init_called_ = true; | |
| 70 binding_ = std::move(binding); | |
| 71 display_manager()->AddDisplay(this); | |
| 72 InitWindowManagerDisplayRootsIfNecessary(); | |
| 73 } | |
| 74 | |
| 75 DisplayManager* Display::display_manager() { | |
| 76 return window_server_->display_manager(); | |
| 77 } | |
| 78 | |
| 79 const DisplayManager* Display::display_manager() const { | |
| 80 return window_server_->display_manager(); | |
| 81 } | |
| 82 | |
| 83 mojom::DisplayPtr Display::ToMojomDisplay() const { | |
| 84 mojom::DisplayPtr display_ptr = mojom::Display::New(); | |
| 85 display_ptr = mojom::Display::New(); | |
| 86 display_ptr->id = id_; | |
| 87 // TODO(sky): Display should know it's origin. | |
| 88 display_ptr->bounds.SetRect(0, 0, root_->bounds().size().width(), | |
| 89 root_->bounds().size().height()); | |
| 90 // TODO(sky): window manager needs an API to set the work area. | |
| 91 display_ptr->work_area = display_ptr->bounds; | |
| 92 display_ptr->device_pixel_ratio = platform_display_->GetDeviceScaleFactor(); | |
| 93 display_ptr->rotation = platform_display_->GetRotation(); | |
| 94 // TODO(sky): make this real. | |
| 95 display_ptr->is_primary = true; | |
| 96 // TODO(sky): make this real. | |
| 97 display_ptr->touch_support = mojom::TouchSupport::UNKNOWN; | |
| 98 display_ptr->frame_decoration_values = mojom::FrameDecorationValues::New(); | |
| 99 return display_ptr; | |
| 100 } | |
| 101 | |
| 102 void Display::SchedulePaint(const ServerWindow* window, | |
| 103 const gfx::Rect& bounds) { | |
| 104 DCHECK(root_->Contains(window)); | |
| 105 platform_display_->SchedulePaint(window, bounds); | |
| 106 } | |
| 107 | |
| 108 void Display::ScheduleSurfaceDestruction(ServerWindow* window) { | |
| 109 if (!platform_display_->IsFramePending()) { | |
| 110 window->DestroySurfacesScheduledForDestruction(); | |
| 111 return; | |
| 112 } | |
| 113 if (windows_needing_frame_destruction_.count(window)) | |
| 114 return; | |
| 115 windows_needing_frame_destruction_.insert(window); | |
| 116 window->AddObserver(this); | |
| 117 } | |
| 118 | |
| 119 mojom::Rotation Display::GetRotation() const { | |
| 120 return platform_display_->GetRotation(); | |
| 121 } | |
| 122 | |
| 123 gfx::Size Display::GetSize() const { | |
| 124 return root_->bounds().size(); | |
| 125 } | |
| 126 | |
| 127 int64_t Display::GetPlatformDisplayId() const { | |
| 128 return platform_display_->GetDisplayId(); | |
| 129 } | |
| 130 | |
| 131 ServerWindow* Display::GetRootWithId(const WindowId& id) { | |
| 132 if (id == root_->id()) | |
| 133 return root_.get(); | |
| 134 for (auto& pair : window_manager_display_root_map_) { | |
| 135 if (pair.second->root()->id() == id) | |
| 136 return pair.second->root(); | |
| 137 } | |
| 138 return nullptr; | |
| 139 } | |
| 140 | |
| 141 WindowManagerDisplayRoot* Display::GetWindowManagerDisplayRootWithRoot( | |
| 142 const ServerWindow* window) { | |
| 143 for (auto& pair : window_manager_display_root_map_) { | |
| 144 if (pair.second->root() == window) | |
| 145 return pair.second.get(); | |
| 146 } | |
| 147 return nullptr; | |
| 148 } | |
| 149 | |
| 150 const WindowManagerDisplayRoot* Display::GetWindowManagerDisplayRootForUser( | |
| 151 const UserId& user_id) const { | |
| 152 auto iter = window_manager_display_root_map_.find(user_id); | |
| 153 return iter == window_manager_display_root_map_.end() ? nullptr | |
| 154 : iter->second.get(); | |
| 155 } | |
| 156 | |
| 157 const WindowManagerDisplayRoot* Display::GetActiveWindowManagerDisplayRoot() | |
| 158 const { | |
| 159 return GetWindowManagerDisplayRootForUser( | |
| 160 window_server_->user_id_tracker()->active_id()); | |
| 161 } | |
| 162 | |
| 163 bool Display::SetFocusedWindow(ServerWindow* new_focused_window) { | |
| 164 ServerWindow* old_focused_window = focus_controller_->GetFocusedWindow(); | |
| 165 if (old_focused_window == new_focused_window) | |
| 166 return true; | |
| 167 DCHECK(!new_focused_window || root_window()->Contains(new_focused_window)); | |
| 168 return focus_controller_->SetFocusedWindow(new_focused_window); | |
| 169 } | |
| 170 | |
| 171 ServerWindow* Display::GetFocusedWindow() { | |
| 172 return focus_controller_->GetFocusedWindow(); | |
| 173 } | |
| 174 | |
| 175 void Display::ActivateNextWindow() { | |
| 176 // TODO(sky): this is wrong, needs to figure out the next window to activate | |
| 177 // and then route setting through WindowServer. | |
| 178 focus_controller_->ActivateNextWindow(); | |
| 179 } | |
| 180 | |
| 181 void Display::AddActivationParent(ServerWindow* window) { | |
| 182 activation_parents_.Add(window); | |
| 183 } | |
| 184 | |
| 185 void Display::RemoveActivationParent(ServerWindow* window) { | |
| 186 activation_parents_.Remove(window); | |
| 187 } | |
| 188 | |
| 189 void Display::UpdateTextInputState(ServerWindow* window, | |
| 190 const ui::TextInputState& state) { | |
| 191 // Do not need to update text input for unfocused windows. | |
| 192 if (!platform_display_ || focus_controller_->GetFocusedWindow() != window) | |
| 193 return; | |
| 194 platform_display_->UpdateTextInputState(state); | |
| 195 } | |
| 196 | |
| 197 void Display::SetImeVisibility(ServerWindow* window, bool visible) { | |
| 198 // Do not need to show or hide IME for unfocused window. | |
| 199 if (focus_controller_->GetFocusedWindow() != window) | |
| 200 return; | |
| 201 platform_display_->SetImeVisibility(visible); | |
| 202 } | |
| 203 | |
| 204 void Display::OnWillDestroyTree(WindowTree* tree) { | |
| 205 for (auto it = window_manager_display_root_map_.begin(); | |
| 206 it != window_manager_display_root_map_.end(); ++it) { | |
| 207 if (it->second->window_manager_state()->window_tree() == tree) { | |
| 208 window_manager_display_root_map_.erase(it); | |
| 209 break; | |
| 210 } | |
| 211 } | |
| 212 } | |
| 213 | |
| 214 void Display::UpdateNativeCursor(int32_t cursor_id) { | |
| 215 if (cursor_id != last_cursor_) { | |
| 216 platform_display_->SetCursorById(cursor_id); | |
| 217 last_cursor_ = cursor_id; | |
| 218 } | |
| 219 } | |
| 220 | |
| 221 void Display::SetSize(const gfx::Size& size) { | |
| 222 platform_display_->SetViewportSize(size); | |
| 223 } | |
| 224 | |
| 225 void Display::SetTitle(const mojo::String& title) { | |
| 226 platform_display_->SetTitle(title.To<base::string16>()); | |
| 227 } | |
| 228 | |
| 229 void Display::InitWindowManagerDisplayRootsIfNecessary() { | |
| 230 if (!init_called_ || !root_) | |
| 231 return; | |
| 232 | |
| 233 display_manager()->OnDisplayAcceleratedWidgetAvailable(this); | |
| 234 if (binding_) { | |
| 235 std::unique_ptr<WindowManagerDisplayRoot> display_root_ptr( | |
| 236 new WindowManagerDisplayRoot(this)); | |
| 237 WindowManagerDisplayRoot* display_root = display_root_ptr.get(); | |
| 238 // For this case we never create additional displays roots, so any | |
| 239 // id works. | |
| 240 window_manager_display_root_map_[shell::mojom::kRootUserID] = | |
| 241 std::move(display_root_ptr); | |
| 242 WindowTree* window_tree = binding_->CreateWindowTree(display_root->root()); | |
| 243 display_root->window_manager_state_ = window_tree->window_manager_state(); | |
| 244 } else { | |
| 245 CreateWindowManagerDisplayRootsFromFactories(); | |
| 246 } | |
| 247 } | |
| 248 | |
| 249 void Display::CreateWindowManagerDisplayRootsFromFactories() { | |
| 250 std::vector<WindowManagerWindowTreeFactory*> factories = | |
| 251 window_server_->window_manager_window_tree_factory_set()->GetFactories(); | |
| 252 for (WindowManagerWindowTreeFactory* factory : factories) { | |
| 253 if (factory->window_tree()) | |
| 254 CreateWindowManagerDisplayRootFromFactory(factory); | |
| 255 } | |
| 256 } | |
| 257 | |
| 258 void Display::CreateWindowManagerDisplayRootFromFactory( | |
| 259 WindowManagerWindowTreeFactory* factory) { | |
| 260 std::unique_ptr<WindowManagerDisplayRoot> display_root_ptr( | |
| 261 new WindowManagerDisplayRoot(this)); | |
| 262 WindowManagerDisplayRoot* display_root = display_root_ptr.get(); | |
| 263 window_manager_display_root_map_[factory->user_id()] = | |
| 264 std::move(display_root_ptr); | |
| 265 display_root->window_manager_state_ = | |
| 266 factory->window_tree()->window_manager_state(); | |
| 267 const bool is_active = | |
| 268 factory->user_id() == window_server_->user_id_tracker()->active_id(); | |
| 269 display_root->root()->SetVisible(is_active); | |
| 270 display_root->window_manager_state()->window_tree()->AddRootForWindowManager( | |
| 271 display_root->root()); | |
| 272 } | |
| 273 | |
| 274 ServerWindow* Display::GetRootWindow() { | |
| 275 return root_.get(); | |
| 276 } | |
| 277 | |
| 278 void Display::OnEvent(const ui::Event& event) { | |
| 279 WindowManagerDisplayRoot* display_root = GetActiveWindowManagerDisplayRoot(); | |
| 280 if (display_root) | |
| 281 display_root->window_manager_state()->ProcessEvent(event); | |
| 282 window_server_ | |
| 283 ->GetUserActivityMonitorForUser( | |
| 284 window_server_->user_id_tracker()->active_id()) | |
| 285 ->OnUserActivity(); | |
| 286 } | |
| 287 | |
| 288 void Display::OnNativeCaptureLost() { | |
| 289 WindowManagerDisplayRoot* display_root = GetActiveWindowManagerDisplayRoot(); | |
| 290 if (display_root) | |
| 291 display_root->window_manager_state()->SetCapture(nullptr, kInvalidClientId); | |
| 292 } | |
| 293 | |
| 294 void Display::OnDisplayClosed() { | |
| 295 display_manager()->DestroyDisplay(this); | |
| 296 } | |
| 297 | |
| 298 void Display::OnViewportMetricsChanged(const ViewportMetrics& old_metrics, | |
| 299 const ViewportMetrics& new_metrics) { | |
| 300 if (!root_) { | |
| 301 root_.reset(window_server_->CreateServerWindow( | |
| 302 display_manager()->GetAndAdvanceNextRootId(), | |
| 303 ServerWindow::Properties())); | |
| 304 root_->SetBounds(gfx::Rect(new_metrics.size_in_pixels)); | |
| 305 root_->SetVisible(true); | |
| 306 focus_controller_.reset(new FocusController(this, root_.get())); | |
| 307 focus_controller_->AddObserver(this); | |
| 308 InitWindowManagerDisplayRootsIfNecessary(); | |
| 309 } else { | |
| 310 root_->SetBounds(gfx::Rect(new_metrics.size_in_pixels)); | |
| 311 const gfx::Rect wm_bounds(root_->bounds().size()); | |
| 312 for (auto& pair : window_manager_display_root_map_) | |
| 313 pair.second->root()->SetBounds(wm_bounds); | |
| 314 } | |
| 315 display_manager()->OnDisplayUpdate(this); | |
| 316 } | |
| 317 | |
| 318 void Display::OnCompositorFrameDrawn() { | |
| 319 std::set<ServerWindow*> windows; | |
| 320 windows.swap(windows_needing_frame_destruction_); | |
| 321 for (ServerWindow* window : windows) { | |
| 322 window->RemoveObserver(this); | |
| 323 window->DestroySurfacesScheduledForDestruction(); | |
| 324 } | |
| 325 } | |
| 326 | |
| 327 bool Display::CanHaveActiveChildren(ServerWindow* window) const { | |
| 328 return window && activation_parents_.Contains(window); | |
| 329 } | |
| 330 | |
| 331 void Display::OnActivationChanged(ServerWindow* old_active_window, | |
| 332 ServerWindow* new_active_window) { | |
| 333 DCHECK_NE(new_active_window, old_active_window); | |
| 334 if (new_active_window && new_active_window->parent()) { | |
| 335 // Raise the new active window. | |
| 336 // TODO(sad): Let the WM dictate whether to raise the window or not? | |
| 337 new_active_window->parent()->StackChildAtTop(new_active_window); | |
| 338 } | |
| 339 } | |
| 340 | |
| 341 void Display::OnFocusChanged(FocusControllerChangeSource change_source, | |
| 342 ServerWindow* old_focused_window, | |
| 343 ServerWindow* new_focused_window) { | |
| 344 // TODO(sky): focus is global, not per windowtreehost. Move. | |
| 345 | |
| 346 // There are up to four clients that need to be notified: | |
| 347 // . the client containing |old_focused_window|. | |
| 348 // . the client with |old_focused_window| as its root. | |
| 349 // . the client containing |new_focused_window|. | |
| 350 // . the client with |new_focused_window| as its root. | |
| 351 // Some of these client may be the same. The following takes care to notify | |
| 352 // each only once. | |
| 353 WindowTree* owning_tree_old = nullptr; | |
| 354 WindowTree* embedded_tree_old = nullptr; | |
| 355 | |
| 356 if (old_focused_window) { | |
| 357 owning_tree_old = | |
| 358 window_server_->GetTreeWithId(old_focused_window->id().client_id); | |
| 359 if (owning_tree_old) { | |
| 360 owning_tree_old->ProcessFocusChanged(old_focused_window, | |
| 361 new_focused_window); | |
| 362 } | |
| 363 embedded_tree_old = window_server_->GetTreeWithRoot(old_focused_window); | |
| 364 if (embedded_tree_old) { | |
| 365 DCHECK_NE(owning_tree_old, embedded_tree_old); | |
| 366 embedded_tree_old->ProcessFocusChanged(old_focused_window, | |
| 367 new_focused_window); | |
| 368 } | |
| 369 } | |
| 370 WindowTree* owning_tree_new = nullptr; | |
| 371 WindowTree* embedded_tree_new = nullptr; | |
| 372 if (new_focused_window) { | |
| 373 owning_tree_new = | |
| 374 window_server_->GetTreeWithId(new_focused_window->id().client_id); | |
| 375 if (owning_tree_new && owning_tree_new != owning_tree_old && | |
| 376 owning_tree_new != embedded_tree_old) { | |
| 377 owning_tree_new->ProcessFocusChanged(old_focused_window, | |
| 378 new_focused_window); | |
| 379 } | |
| 380 embedded_tree_new = window_server_->GetTreeWithRoot(new_focused_window); | |
| 381 if (embedded_tree_new && embedded_tree_new != owning_tree_old && | |
| 382 embedded_tree_new != embedded_tree_old) { | |
| 383 DCHECK_NE(owning_tree_new, embedded_tree_new); | |
| 384 embedded_tree_new->ProcessFocusChanged(old_focused_window, | |
| 385 new_focused_window); | |
| 386 } | |
| 387 } | |
| 388 | |
| 389 // WindowManagers are always notified of focus changes. | |
| 390 WindowManagerDisplayRoot* display_root = GetActiveWindowManagerDisplayRoot(); | |
| 391 if (display_root) { | |
| 392 WindowTree* wm_tree = display_root->window_manager_state()->window_tree(); | |
| 393 if (wm_tree != owning_tree_old && wm_tree != embedded_tree_old && | |
| 394 wm_tree != owning_tree_new && wm_tree != embedded_tree_new) { | |
| 395 wm_tree->ProcessFocusChanged(old_focused_window, new_focused_window); | |
| 396 } | |
| 397 } | |
| 398 | |
| 399 UpdateTextInputState(new_focused_window, | |
| 400 new_focused_window->text_input_state()); | |
| 401 } | |
| 402 | |
| 403 void Display::OnWindowDestroyed(ServerWindow* window) { | |
| 404 windows_needing_frame_destruction_.erase(window); | |
| 405 window->RemoveObserver(this); | |
| 406 } | |
| 407 | |
| 408 void Display::OnUserIdRemoved(const UserId& id) { | |
| 409 window_manager_display_root_map_.erase(id); | |
| 410 } | |
| 411 | |
| 412 void Display::OnWindowManagerWindowTreeFactoryReady( | |
| 413 WindowManagerWindowTreeFactory* factory) { | |
| 414 if (!binding_) | |
| 415 CreateWindowManagerDisplayRootFromFactory(factory); | |
| 416 } | |
| 417 | |
| 418 } // namespace ws | |
| 419 } // namespace mus | |
| OLD | NEW |