| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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/window_server.h" | |
| 6 | |
| 7 #include <set> | |
| 8 #include <string> | |
| 9 | |
| 10 #include "base/logging.h" | |
| 11 #include "base/memory/ptr_util.h" | |
| 12 #include "base/stl_util.h" | |
| 13 #include "components/mus/ws/display.h" | |
| 14 #include "components/mus/ws/display_binding.h" | |
| 15 #include "components/mus/ws/display_manager.h" | |
| 16 #include "components/mus/ws/operation.h" | |
| 17 #include "components/mus/ws/server_window.h" | |
| 18 #include "components/mus/ws/user_activity_monitor.h" | |
| 19 #include "components/mus/ws/window_coordinate_conversions.h" | |
| 20 #include "components/mus/ws/window_manager_access_policy.h" | |
| 21 #include "components/mus/ws/window_manager_display_root.h" | |
| 22 #include "components/mus/ws/window_manager_state.h" | |
| 23 #include "components/mus/ws/window_manager_window_tree_factory.h" | |
| 24 #include "components/mus/ws/window_server_delegate.h" | |
| 25 #include "components/mus/ws/window_tree.h" | |
| 26 #include "components/mus/ws/window_tree_binding.h" | |
| 27 #include "services/shell/public/cpp/connection.h" | |
| 28 #include "ui/gfx/geometry/size_conversions.h" | |
| 29 | |
| 30 namespace mus { | |
| 31 namespace ws { | |
| 32 | |
| 33 WindowServer::WindowServer( | |
| 34 WindowServerDelegate* delegate, | |
| 35 const scoped_refptr<mus::SurfacesState>& surfaces_state) | |
| 36 : delegate_(delegate), | |
| 37 surfaces_state_(surfaces_state), | |
| 38 next_client_id_(1), | |
| 39 display_manager_(new DisplayManager(this, &user_id_tracker_)), | |
| 40 current_operation_(nullptr), | |
| 41 in_destructor_(false), | |
| 42 next_wm_change_id_(0), | |
| 43 window_manager_window_tree_factory_set_(this, &user_id_tracker_) { | |
| 44 user_id_tracker_.AddObserver(this); | |
| 45 OnUserIdAdded(user_id_tracker_.active_id()); | |
| 46 } | |
| 47 | |
| 48 WindowServer::~WindowServer() { | |
| 49 in_destructor_ = true; | |
| 50 | |
| 51 // Destroys the window trees results in querying for the display. Tear down | |
| 52 // the displays first so that the trees are notified of the display going | |
| 53 // away while the display is still valid. | |
| 54 display_manager_->DestroyAllDisplays(); | |
| 55 | |
| 56 while (!tree_map_.empty()) | |
| 57 DestroyTree(tree_map_.begin()->second.get()); | |
| 58 | |
| 59 display_manager_.reset(); | |
| 60 } | |
| 61 | |
| 62 ServerWindow* WindowServer::CreateServerWindow( | |
| 63 const WindowId& id, | |
| 64 const std::map<std::string, std::vector<uint8_t>>& properties) { | |
| 65 ServerWindow* window = new ServerWindow(this, id, properties); | |
| 66 window->AddObserver(this); | |
| 67 return window; | |
| 68 } | |
| 69 | |
| 70 ClientSpecificId WindowServer::GetAndAdvanceNextClientId() { | |
| 71 const ClientSpecificId id = next_client_id_++; | |
| 72 DCHECK_LT(id, next_client_id_); | |
| 73 return id; | |
| 74 } | |
| 75 | |
| 76 WindowTree* WindowServer::EmbedAtWindow( | |
| 77 ServerWindow* root, | |
| 78 const UserId& user_id, | |
| 79 mojom::WindowTreeClientPtr client, | |
| 80 uint32_t flags, | |
| 81 std::unique_ptr<AccessPolicy> access_policy) { | |
| 82 std::unique_ptr<WindowTree> tree_ptr( | |
| 83 new WindowTree(this, user_id, root, std::move(access_policy))); | |
| 84 WindowTree* tree = tree_ptr.get(); | |
| 85 if (flags & mojom::kEmbedFlagEmbedderInterceptsEvents) | |
| 86 tree->set_embedder_intercepts_events(); | |
| 87 | |
| 88 mojom::WindowTreePtr window_tree_ptr; | |
| 89 mojom::WindowTreeRequest window_tree_request = GetProxy(&window_tree_ptr); | |
| 90 std::unique_ptr<WindowTreeBinding> binding = | |
| 91 delegate_->CreateWindowTreeBinding( | |
| 92 WindowServerDelegate::BindingType::EMBED, this, tree, | |
| 93 &window_tree_request, &client); | |
| 94 if (!binding) { | |
| 95 binding.reset(new ws::DefaultWindowTreeBinding( | |
| 96 tree, this, std::move(window_tree_request), std::move(client))); | |
| 97 } | |
| 98 | |
| 99 AddTree(std::move(tree_ptr), std::move(binding), std::move(window_tree_ptr)); | |
| 100 OnTreeMessagedClient(tree->id()); | |
| 101 return tree; | |
| 102 } | |
| 103 | |
| 104 void WindowServer::AddTree(std::unique_ptr<WindowTree> tree_impl_ptr, | |
| 105 std::unique_ptr<WindowTreeBinding> binding, | |
| 106 mojom::WindowTreePtr tree_ptr) { | |
| 107 CHECK_EQ(0u, tree_map_.count(tree_impl_ptr->id())); | |
| 108 WindowTree* tree = tree_impl_ptr.get(); | |
| 109 tree_map_[tree->id()] = std::move(tree_impl_ptr); | |
| 110 tree->Init(std::move(binding), std::move(tree_ptr)); | |
| 111 } | |
| 112 | |
| 113 WindowTree* WindowServer::CreateTreeForWindowManager( | |
| 114 const UserId& user_id, | |
| 115 mojom::WindowTreeRequest window_tree_request, | |
| 116 mojom::WindowTreeClientPtr window_tree_client) { | |
| 117 std::unique_ptr<WindowTree> window_tree(new WindowTree( | |
| 118 this, user_id, nullptr, base::WrapUnique(new WindowManagerAccessPolicy))); | |
| 119 std::unique_ptr<WindowTreeBinding> window_tree_binding = | |
| 120 delegate_->CreateWindowTreeBinding( | |
| 121 WindowServerDelegate::BindingType::WINDOW_MANAGER, this, | |
| 122 window_tree.get(), &window_tree_request, &window_tree_client); | |
| 123 if (!window_tree_binding) { | |
| 124 window_tree_binding.reset(new DefaultWindowTreeBinding( | |
| 125 window_tree.get(), this, std::move(window_tree_request), | |
| 126 std::move(window_tree_client))); | |
| 127 } | |
| 128 WindowTree* window_tree_ptr = window_tree.get(); | |
| 129 AddTree(std::move(window_tree), std::move(window_tree_binding), nullptr); | |
| 130 window_tree_ptr->ConfigureWindowManager(); | |
| 131 return window_tree_ptr; | |
| 132 } | |
| 133 | |
| 134 void WindowServer::DestroyTree(WindowTree* tree) { | |
| 135 std::unique_ptr<WindowTree> tree_ptr; | |
| 136 { | |
| 137 auto iter = tree_map_.find(tree->id()); | |
| 138 DCHECK(iter != tree_map_.end()); | |
| 139 tree_ptr = std::move(iter->second); | |
| 140 tree_map_.erase(iter); | |
| 141 } | |
| 142 | |
| 143 // Notify remaining connections so that they can cleanup. | |
| 144 for (auto& pair : tree_map_) | |
| 145 pair.second->OnWindowDestroyingTreeImpl(tree); | |
| 146 | |
| 147 // Notify the hosts, taking care to only notify each host once. | |
| 148 std::set<Display*> displays_notified; | |
| 149 for (auto* root : tree->roots()) { | |
| 150 // WindowTree holds its roots as a const, which is right as WindowTree | |
| 151 // doesn't need to modify the window. OTOH we do. We could look up the | |
| 152 // window using the id to get non-const version, but instead we cast. | |
| 153 Display* display = | |
| 154 display_manager_->GetDisplayContaining(const_cast<ServerWindow*>(root)); | |
| 155 if (display && displays_notified.count(display) == 0) { | |
| 156 display->OnWillDestroyTree(tree); | |
| 157 displays_notified.insert(display); | |
| 158 } | |
| 159 } | |
| 160 | |
| 161 window_manager_window_tree_factory_set_.DeleteFactoryAssociatedWithTree(tree); | |
| 162 | |
| 163 // Remove any requests from the client that resulted in a call to the window | |
| 164 // manager and we haven't gotten a response back yet. | |
| 165 std::set<uint32_t> to_remove; | |
| 166 for (auto& pair : in_flight_wm_change_map_) { | |
| 167 if (pair.second.client_id == tree->id()) | |
| 168 to_remove.insert(pair.first); | |
| 169 } | |
| 170 for (uint32_t id : to_remove) | |
| 171 in_flight_wm_change_map_.erase(id); | |
| 172 } | |
| 173 | |
| 174 WindowTree* WindowServer::GetTreeWithId(ClientSpecificId client_id) { | |
| 175 auto iter = tree_map_.find(client_id); | |
| 176 return iter == tree_map_.end() ? nullptr : iter->second.get(); | |
| 177 } | |
| 178 | |
| 179 WindowTree* WindowServer::GetTreeWithClientName( | |
| 180 const std::string& client_name) { | |
| 181 for (const auto& entry : tree_map_) { | |
| 182 if (entry.second->name() == client_name) | |
| 183 return entry.second.get(); | |
| 184 } | |
| 185 return nullptr; | |
| 186 } | |
| 187 | |
| 188 ServerWindow* WindowServer::GetWindow(const WindowId& id) { | |
| 189 // kInvalidClientId is used for Display and WindowManager nodes. | |
| 190 if (id.client_id == kInvalidClientId) { | |
| 191 for (Display* display : display_manager_->displays()) { | |
| 192 ServerWindow* window = display->GetRootWithId(id); | |
| 193 if (window) | |
| 194 return window; | |
| 195 } | |
| 196 } | |
| 197 WindowTree* tree = GetTreeWithId(id.client_id); | |
| 198 return tree ? tree->GetWindow(id) : nullptr; | |
| 199 } | |
| 200 | |
| 201 void WindowServer::SchedulePaint(ServerWindow* window, | |
| 202 const gfx::Rect& bounds) { | |
| 203 Display* display = display_manager_->GetDisplayContaining(window); | |
| 204 if (display) | |
| 205 display->SchedulePaint(window, bounds); | |
| 206 } | |
| 207 | |
| 208 void WindowServer::OnTreeMessagedClient(ClientSpecificId id) { | |
| 209 if (current_operation_) | |
| 210 current_operation_->MarkTreeAsMessaged(id); | |
| 211 } | |
| 212 | |
| 213 bool WindowServer::DidTreeMessageClient(ClientSpecificId id) const { | |
| 214 return current_operation_ && current_operation_->DidMessageTree(id); | |
| 215 } | |
| 216 | |
| 217 const WindowTree* WindowServer::GetTreeWithRoot( | |
| 218 const ServerWindow* window) const { | |
| 219 if (!window) | |
| 220 return nullptr; | |
| 221 for (auto& pair : tree_map_) { | |
| 222 if (pair.second->HasRoot(window)) | |
| 223 return pair.second.get(); | |
| 224 } | |
| 225 return nullptr; | |
| 226 } | |
| 227 | |
| 228 void WindowServer::OnFirstWindowManagerWindowTreeFactoryReady() { | |
| 229 if (display_manager_->has_active_or_pending_displays()) | |
| 230 return; | |
| 231 | |
| 232 // We've been supplied a WindowManagerFactory and no displays have been | |
| 233 // created yet. Treat this as a signal to create a Display. | |
| 234 // TODO(sky): we need a better way to determine this, most likely a switch. | |
| 235 delegate_->CreateDefaultDisplays(); | |
| 236 } | |
| 237 | |
| 238 UserActivityMonitor* WindowServer::GetUserActivityMonitorForUser( | |
| 239 const UserId& user_id) { | |
| 240 DCHECK_GT(activity_monitor_map_.count(user_id), 0u); | |
| 241 return activity_monitor_map_[user_id].get(); | |
| 242 } | |
| 243 | |
| 244 bool WindowServer::SetFocusedWindow(ServerWindow* window) { | |
| 245 // TODO(sky): this should fail if there is modal dialog active and |window| | |
| 246 // is outside that. | |
| 247 ServerWindow* currently_focused = GetFocusedWindow(); | |
| 248 Display* focused_display = | |
| 249 currently_focused | |
| 250 ? display_manager_->GetDisplayContaining(currently_focused) | |
| 251 : nullptr; | |
| 252 if (!window) | |
| 253 return focused_display ? focused_display->SetFocusedWindow(nullptr) : true; | |
| 254 | |
| 255 Display* display = display_manager_->GetDisplayContaining(window); | |
| 256 DCHECK(display); // It's assumed callers do validation before calling this. | |
| 257 const bool result = display->SetFocusedWindow(window); | |
| 258 // If the focus actually changed, and focus was in another display, then we | |
| 259 // need to notify the previously focused display so that it cleans up state | |
| 260 // and notifies appropriately. | |
| 261 if (result && display->GetFocusedWindow() && display != focused_display && | |
| 262 focused_display) { | |
| 263 const bool cleared_focus = focused_display->SetFocusedWindow(nullptr); | |
| 264 DCHECK(cleared_focus); | |
| 265 } | |
| 266 return result; | |
| 267 } | |
| 268 | |
| 269 ServerWindow* WindowServer::GetFocusedWindow() { | |
| 270 for (Display* display : display_manager_->displays()) { | |
| 271 ServerWindow* focused_window = display->GetFocusedWindow(); | |
| 272 if (focused_window) | |
| 273 return focused_window; | |
| 274 } | |
| 275 return nullptr; | |
| 276 } | |
| 277 | |
| 278 uint32_t WindowServer::GenerateWindowManagerChangeId( | |
| 279 WindowTree* source, | |
| 280 uint32_t client_change_id) { | |
| 281 const uint32_t wm_change_id = next_wm_change_id_++; | |
| 282 in_flight_wm_change_map_[wm_change_id] = {source->id(), client_change_id}; | |
| 283 return wm_change_id; | |
| 284 } | |
| 285 | |
| 286 void WindowServer::WindowManagerChangeCompleted( | |
| 287 uint32_t window_manager_change_id, | |
| 288 bool success) { | |
| 289 InFlightWindowManagerChange change; | |
| 290 if (!GetAndClearInFlightWindowManagerChange(window_manager_change_id, | |
| 291 &change)) { | |
| 292 return; | |
| 293 } | |
| 294 | |
| 295 WindowTree* tree = GetTreeWithId(change.client_id); | |
| 296 tree->OnChangeCompleted(change.client_change_id, success); | |
| 297 } | |
| 298 | |
| 299 void WindowServer::WindowManagerCreatedTopLevelWindow( | |
| 300 WindowTree* wm_tree, | |
| 301 uint32_t window_manager_change_id, | |
| 302 const ServerWindow* window) { | |
| 303 InFlightWindowManagerChange change; | |
| 304 if (!GetAndClearInFlightWindowManagerChange(window_manager_change_id, | |
| 305 &change)) { | |
| 306 return; | |
| 307 } | |
| 308 if (!window) { | |
| 309 WindowManagerSentBogusMessage(); | |
| 310 return; | |
| 311 } | |
| 312 | |
| 313 WindowTree* tree = GetTreeWithId(change.client_id); | |
| 314 // The window manager should have created the window already, and it should | |
| 315 // be ready for embedding. | |
| 316 if (!tree->IsWaitingForNewTopLevelWindow(window_manager_change_id) || | |
| 317 !window || window->id().client_id != wm_tree->id() || | |
| 318 !window->children().empty() || GetTreeWithRoot(window)) { | |
| 319 WindowManagerSentBogusMessage(); | |
| 320 return; | |
| 321 } | |
| 322 | |
| 323 tree->OnWindowManagerCreatedTopLevelWindow(window_manager_change_id, | |
| 324 change.client_change_id, window); | |
| 325 } | |
| 326 | |
| 327 void WindowServer::ProcessWindowBoundsChanged(const ServerWindow* window, | |
| 328 const gfx::Rect& old_bounds, | |
| 329 const gfx::Rect& new_bounds) { | |
| 330 for (auto& pair : tree_map_) { | |
| 331 pair.second->ProcessWindowBoundsChanged(window, old_bounds, new_bounds, | |
| 332 IsOperationSource(pair.first)); | |
| 333 } | |
| 334 } | |
| 335 | |
| 336 void WindowServer::ProcessClientAreaChanged( | |
| 337 const ServerWindow* window, | |
| 338 const gfx::Insets& new_client_area, | |
| 339 const std::vector<gfx::Rect>& new_additional_client_areas) { | |
| 340 for (auto& pair : tree_map_) { | |
| 341 pair.second->ProcessClientAreaChanged(window, new_client_area, | |
| 342 new_additional_client_areas, | |
| 343 IsOperationSource(pair.first)); | |
| 344 } | |
| 345 } | |
| 346 | |
| 347 void WindowServer::ProcessLostCapture(const ServerWindow* window) { | |
| 348 for (auto& pair : tree_map_) | |
| 349 pair.second->ProcessLostCapture(window, IsOperationSource(pair.first)); | |
| 350 } | |
| 351 | |
| 352 void WindowServer::ProcessWillChangeWindowHierarchy( | |
| 353 const ServerWindow* window, | |
| 354 const ServerWindow* new_parent, | |
| 355 const ServerWindow* old_parent) { | |
| 356 for (auto& pair : tree_map_) { | |
| 357 pair.second->ProcessWillChangeWindowHierarchy( | |
| 358 window, new_parent, old_parent, IsOperationSource(pair.first)); | |
| 359 } | |
| 360 } | |
| 361 | |
| 362 void WindowServer::ProcessWindowHierarchyChanged( | |
| 363 const ServerWindow* window, | |
| 364 const ServerWindow* new_parent, | |
| 365 const ServerWindow* old_parent) { | |
| 366 for (auto& pair : tree_map_) { | |
| 367 pair.second->ProcessWindowHierarchyChanged(window, new_parent, old_parent, | |
| 368 IsOperationSource(pair.first)); | |
| 369 } | |
| 370 } | |
| 371 | |
| 372 void WindowServer::ProcessWindowReorder(const ServerWindow* window, | |
| 373 const ServerWindow* relative_window, | |
| 374 const mojom::OrderDirection direction) { | |
| 375 // We'll probably do a bit of reshuffling when we add a transient window. | |
| 376 if ((current_operation_type() == OperationType::ADD_TRANSIENT_WINDOW) || | |
| 377 (current_operation_type() == | |
| 378 OperationType::REMOVE_TRANSIENT_WINDOW_FROM_PARENT)) { | |
| 379 return; | |
| 380 } | |
| 381 for (auto& pair : tree_map_) { | |
| 382 pair.second->ProcessWindowReorder(window, relative_window, direction, | |
| 383 IsOperationSource(pair.first)); | |
| 384 } | |
| 385 } | |
| 386 | |
| 387 void WindowServer::ProcessWindowDeleted(const ServerWindow* window) { | |
| 388 for (auto& pair : tree_map_) | |
| 389 pair.second->ProcessWindowDeleted(window, IsOperationSource(pair.first)); | |
| 390 } | |
| 391 | |
| 392 void WindowServer::ProcessWillChangeWindowPredefinedCursor(ServerWindow* window, | |
| 393 int32_t cursor_id) { | |
| 394 for (auto& pair : tree_map_) { | |
| 395 pair.second->ProcessCursorChanged(window, cursor_id, | |
| 396 IsOperationSource(pair.first)); | |
| 397 } | |
| 398 } | |
| 399 | |
| 400 void WindowServer::SendToEventObservers(const ui::Event& event, | |
| 401 const UserId& user_id, | |
| 402 WindowTree* ignore_tree) { | |
| 403 for (auto& pair : tree_map_) { | |
| 404 WindowTree* tree = pair.second.get(); | |
| 405 if (tree->user_id() == user_id && tree != ignore_tree) | |
| 406 tree->SendToEventObserver(event); | |
| 407 } | |
| 408 } | |
| 409 | |
| 410 void WindowServer::SetPaintCallback( | |
| 411 const base::Callback<void(ServerWindow*)>& callback) { | |
| 412 DCHECK(delegate_->IsTestConfig()) << "Paint callbacks are expensive, and " | |
| 413 << "allowed only in tests."; | |
| 414 DCHECK(window_paint_callback_.is_null() || callback.is_null()); | |
| 415 window_paint_callback_ = callback; | |
| 416 } | |
| 417 | |
| 418 bool WindowServer::GetAndClearInFlightWindowManagerChange( | |
| 419 uint32_t window_manager_change_id, | |
| 420 InFlightWindowManagerChange* change) { | |
| 421 // There are valid reasons as to why we wouldn't know about the id. The | |
| 422 // most likely is the client disconnected before the response from the window | |
| 423 // manager came back. | |
| 424 auto iter = in_flight_wm_change_map_.find(window_manager_change_id); | |
| 425 if (iter == in_flight_wm_change_map_.end()) | |
| 426 return false; | |
| 427 | |
| 428 *change = iter->second; | |
| 429 in_flight_wm_change_map_.erase(iter); | |
| 430 return true; | |
| 431 } | |
| 432 | |
| 433 void WindowServer::PrepareForOperation(Operation* op) { | |
| 434 // Should only ever have one change in flight. | |
| 435 CHECK(!current_operation_); | |
| 436 current_operation_ = op; | |
| 437 } | |
| 438 | |
| 439 void WindowServer::FinishOperation() { | |
| 440 // PrepareForOperation/FinishOperation should be balanced. | |
| 441 CHECK(current_operation_); | |
| 442 current_operation_ = nullptr; | |
| 443 } | |
| 444 | |
| 445 void WindowServer::UpdateNativeCursorFromMouseLocation(ServerWindow* window) { | |
| 446 WindowManagerDisplayRoot* display_root = | |
| 447 display_manager_->GetWindowManagerDisplayRoot(window); | |
| 448 if (display_root) { | |
| 449 EventDispatcher* event_dispatcher = | |
| 450 display_root->window_manager_state()->event_dispatcher(); | |
| 451 event_dispatcher->UpdateCursorProviderByLastKnownLocation(); | |
| 452 int32_t cursor_id = 0; | |
| 453 if (event_dispatcher->GetCurrentMouseCursor(&cursor_id)) | |
| 454 display_root->display()->UpdateNativeCursor(cursor_id); | |
| 455 } | |
| 456 } | |
| 457 | |
| 458 void WindowServer::UpdateNativeCursorIfOver(ServerWindow* window) { | |
| 459 WindowManagerDisplayRoot* display_root = | |
| 460 display_manager_->GetWindowManagerDisplayRoot(window); | |
| 461 if (!display_root) | |
| 462 return; | |
| 463 | |
| 464 EventDispatcher* event_dispatcher = | |
| 465 display_root->window_manager_state()->event_dispatcher(); | |
| 466 if (window != event_dispatcher->mouse_cursor_source_window()) | |
| 467 return; | |
| 468 | |
| 469 event_dispatcher->UpdateNonClientAreaForCurrentWindow(); | |
| 470 int32_t cursor_id = 0; | |
| 471 if (event_dispatcher->GetCurrentMouseCursor(&cursor_id)) | |
| 472 display_root->display()->UpdateNativeCursor(cursor_id); | |
| 473 } | |
| 474 | |
| 475 mus::SurfacesState* WindowServer::GetSurfacesState() { | |
| 476 return surfaces_state_.get(); | |
| 477 } | |
| 478 | |
| 479 void WindowServer::OnScheduleWindowPaint(ServerWindow* window) { | |
| 480 if (in_destructor_) | |
| 481 return; | |
| 482 | |
| 483 SchedulePaint(window, gfx::Rect(window->bounds().size())); | |
| 484 if (!window_paint_callback_.is_null()) | |
| 485 window_paint_callback_.Run(window); | |
| 486 } | |
| 487 | |
| 488 const ServerWindow* WindowServer::GetRootWindow( | |
| 489 const ServerWindow* window) const { | |
| 490 const Display* display = display_manager_->GetDisplayContaining(window); | |
| 491 return display ? display->root_window() : nullptr; | |
| 492 } | |
| 493 | |
| 494 void WindowServer::ScheduleSurfaceDestruction(ServerWindow* window) { | |
| 495 Display* display = display_manager_->GetDisplayContaining(window); | |
| 496 if (display) | |
| 497 display->ScheduleSurfaceDestruction(window); | |
| 498 } | |
| 499 | |
| 500 void WindowServer::OnWindowDestroyed(ServerWindow* window) { | |
| 501 ProcessWindowDeleted(window); | |
| 502 } | |
| 503 | |
| 504 void WindowServer::OnWillChangeWindowHierarchy(ServerWindow* window, | |
| 505 ServerWindow* new_parent, | |
| 506 ServerWindow* old_parent) { | |
| 507 if (in_destructor_) | |
| 508 return; | |
| 509 | |
| 510 ProcessWillChangeWindowHierarchy(window, new_parent, old_parent); | |
| 511 } | |
| 512 | |
| 513 void WindowServer::OnWindowHierarchyChanged(ServerWindow* window, | |
| 514 ServerWindow* new_parent, | |
| 515 ServerWindow* old_parent) { | |
| 516 if (in_destructor_) | |
| 517 return; | |
| 518 | |
| 519 WindowManagerDisplayRoot* display_root = | |
| 520 display_manager_->GetWindowManagerDisplayRoot(window); | |
| 521 if (display_root) | |
| 522 display_root->window_manager_state() | |
| 523 ->ReleaseCaptureBlockedByAnyModalWindow(); | |
| 524 | |
| 525 ProcessWindowHierarchyChanged(window, new_parent, old_parent); | |
| 526 | |
| 527 // TODO(beng): optimize. | |
| 528 if (old_parent) | |
| 529 SchedulePaint(old_parent, gfx::Rect(old_parent->bounds().size())); | |
| 530 if (new_parent) | |
| 531 SchedulePaint(new_parent, gfx::Rect(new_parent->bounds().size())); | |
| 532 | |
| 533 UpdateNativeCursorFromMouseLocation(window); | |
| 534 } | |
| 535 | |
| 536 void WindowServer::OnWindowBoundsChanged(ServerWindow* window, | |
| 537 const gfx::Rect& old_bounds, | |
| 538 const gfx::Rect& new_bounds) { | |
| 539 if (in_destructor_) | |
| 540 return; | |
| 541 | |
| 542 ProcessWindowBoundsChanged(window, old_bounds, new_bounds); | |
| 543 if (!window->parent()) | |
| 544 return; | |
| 545 | |
| 546 SchedulePaint(window->parent(), old_bounds); | |
| 547 SchedulePaint(window->parent(), new_bounds); | |
| 548 | |
| 549 UpdateNativeCursorFromMouseLocation(window); | |
| 550 } | |
| 551 | |
| 552 void WindowServer::OnWindowClientAreaChanged( | |
| 553 ServerWindow* window, | |
| 554 const gfx::Insets& new_client_area, | |
| 555 const std::vector<gfx::Rect>& new_additional_client_areas) { | |
| 556 if (in_destructor_) | |
| 557 return; | |
| 558 | |
| 559 ProcessClientAreaChanged(window, new_client_area, | |
| 560 new_additional_client_areas); | |
| 561 | |
| 562 UpdateNativeCursorIfOver(window); | |
| 563 } | |
| 564 | |
| 565 void WindowServer::OnWindowReordered(ServerWindow* window, | |
| 566 ServerWindow* relative, | |
| 567 mojom::OrderDirection direction) { | |
| 568 ProcessWindowReorder(window, relative, direction); | |
| 569 if (!in_destructor_) | |
| 570 SchedulePaint(window, gfx::Rect(window->bounds().size())); | |
| 571 UpdateNativeCursorFromMouseLocation(window); | |
| 572 } | |
| 573 | |
| 574 void WindowServer::OnWillChangeWindowVisibility(ServerWindow* window) { | |
| 575 if (in_destructor_) | |
| 576 return; | |
| 577 | |
| 578 // Need to repaint if the window was drawn (which means it's in the process of | |
| 579 // hiding) or the window is transitioning to drawn. | |
| 580 if (window->parent() && | |
| 581 (window->IsDrawn() || | |
| 582 (!window->visible() && window->parent()->IsDrawn()))) { | |
| 583 SchedulePaint(window->parent(), window->bounds()); | |
| 584 } | |
| 585 | |
| 586 for (auto& pair : tree_map_) { | |
| 587 pair.second->ProcessWillChangeWindowVisibility( | |
| 588 window, IsOperationSource(pair.first)); | |
| 589 } | |
| 590 } | |
| 591 | |
| 592 void WindowServer::OnWindowOpacityChanged(ServerWindow* window, | |
| 593 float old_opacity, | |
| 594 float new_opacity) { | |
| 595 DCHECK(!in_destructor_); | |
| 596 | |
| 597 for (auto& pair : tree_map_) { | |
| 598 pair.second->ProcessWindowOpacityChanged(window, old_opacity, new_opacity, | |
| 599 IsOperationSource(pair.first)); | |
| 600 } | |
| 601 } | |
| 602 | |
| 603 void WindowServer::OnWindowVisibilityChanged(ServerWindow* window) { | |
| 604 if (in_destructor_) | |
| 605 return; | |
| 606 | |
| 607 WindowManagerDisplayRoot* display_root = | |
| 608 display_manager_->GetWindowManagerDisplayRoot(window); | |
| 609 if (display_root) | |
| 610 display_root->window_manager_state()->ReleaseCaptureBlockedByModalWindow( | |
| 611 window); | |
| 612 } | |
| 613 | |
| 614 void WindowServer::OnWindowPredefinedCursorChanged(ServerWindow* window, | |
| 615 int32_t cursor_id) { | |
| 616 if (in_destructor_) | |
| 617 return; | |
| 618 | |
| 619 ProcessWillChangeWindowPredefinedCursor(window, cursor_id); | |
| 620 | |
| 621 UpdateNativeCursorIfOver(window); | |
| 622 } | |
| 623 | |
| 624 void WindowServer::OnWindowNonClientCursorChanged(ServerWindow* window, | |
| 625 int32_t cursor_id) { | |
| 626 if (in_destructor_) | |
| 627 return; | |
| 628 | |
| 629 UpdateNativeCursorIfOver(window); | |
| 630 } | |
| 631 | |
| 632 void WindowServer::OnWindowSharedPropertyChanged( | |
| 633 ServerWindow* window, | |
| 634 const std::string& name, | |
| 635 const std::vector<uint8_t>* new_data) { | |
| 636 for (auto& pair : tree_map_) { | |
| 637 pair.second->ProcessWindowPropertyChanged(window, name, new_data, | |
| 638 IsOperationSource(pair.first)); | |
| 639 } | |
| 640 } | |
| 641 | |
| 642 void WindowServer::OnWindowTextInputStateChanged( | |
| 643 ServerWindow* window, | |
| 644 const ui::TextInputState& state) { | |
| 645 Display* display = display_manager_->GetDisplayContaining(window); | |
| 646 display->UpdateTextInputState(window, state); | |
| 647 } | |
| 648 | |
| 649 void WindowServer::OnTransientWindowAdded(ServerWindow* window, | |
| 650 ServerWindow* transient_child) { | |
| 651 for (auto& pair : tree_map_) { | |
| 652 pair.second->ProcessTransientWindowAdded(window, transient_child, | |
| 653 IsOperationSource(pair.first)); | |
| 654 } | |
| 655 } | |
| 656 | |
| 657 void WindowServer::OnTransientWindowRemoved(ServerWindow* window, | |
| 658 ServerWindow* transient_child) { | |
| 659 // If we're deleting a window, then this is a superfluous message. | |
| 660 if (current_operation_type() == OperationType::DELETE_WINDOW) | |
| 661 return; | |
| 662 for (auto& pair : tree_map_) { | |
| 663 pair.second->ProcessTransientWindowRemoved(window, transient_child, | |
| 664 IsOperationSource(pair.first)); | |
| 665 } | |
| 666 } | |
| 667 | |
| 668 void WindowServer::OnFirstDisplayReady() { | |
| 669 delegate_->OnFirstDisplayReady(); | |
| 670 } | |
| 671 | |
| 672 void WindowServer::OnNoMoreDisplays() { | |
| 673 delegate_->OnNoMoreDisplays(); | |
| 674 } | |
| 675 | |
| 676 bool WindowServer::GetFrameDecorationsForUser( | |
| 677 const UserId& user_id, | |
| 678 mojom::FrameDecorationValuesPtr* values) { | |
| 679 WindowManagerState* window_manager_state = | |
| 680 window_manager_window_tree_factory_set_.GetWindowManagerStateForUser( | |
| 681 user_id); | |
| 682 if (!window_manager_state) | |
| 683 return false; | |
| 684 if (values && window_manager_state->got_frame_decoration_values()) | |
| 685 *values = window_manager_state->frame_decoration_values().Clone(); | |
| 686 return window_manager_state->got_frame_decoration_values(); | |
| 687 } | |
| 688 | |
| 689 WindowManagerState* WindowServer::GetWindowManagerStateForUser( | |
| 690 const UserId& user_id) { | |
| 691 return window_manager_window_tree_factory_set_.GetWindowManagerStateForUser( | |
| 692 user_id); | |
| 693 } | |
| 694 | |
| 695 void WindowServer::OnActiveUserIdChanged(const UserId& previously_active_id, | |
| 696 const UserId& active_id) {} | |
| 697 | |
| 698 void WindowServer::OnUserIdAdded(const UserId& id) { | |
| 699 activity_monitor_map_[id] = base::MakeUnique<UserActivityMonitor>(nullptr); | |
| 700 } | |
| 701 | |
| 702 void WindowServer::OnUserIdRemoved(const UserId& id) { | |
| 703 activity_monitor_map_.erase(id); | |
| 704 } | |
| 705 | |
| 706 } // namespace ws | |
| 707 } // namespace mus | |
| OLD | NEW |