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 |