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/public/cpp/lib/window_tree_client_impl.h" | |
6 | |
7 #include <stddef.h> | |
8 | |
9 #include <string> | |
10 #include <utility> | |
11 #include <vector> | |
12 | |
13 #include "base/bind.h" | |
14 #include "base/memory/ptr_util.h" | |
15 #include "components/mus/common/util.h" | |
16 #include "components/mus/public/cpp/input_event_handler.h" | |
17 #include "components/mus/public/cpp/lib/in_flight_change.h" | |
18 #include "components/mus/public/cpp/lib/window_private.h" | |
19 #include "components/mus/public/cpp/window_manager_delegate.h" | |
20 #include "components/mus/public/cpp/window_observer.h" | |
21 #include "components/mus/public/cpp/window_tracker.h" | |
22 #include "components/mus/public/cpp/window_tree_connection.h" | |
23 #include "components/mus/public/cpp/window_tree_connection_observer.h" | |
24 #include "components/mus/public/cpp/window_tree_delegate.h" | |
25 #include "services/shell/public/cpp/connector.h" | |
26 #include "ui/events/event.h" | |
27 #include "ui/events/mojo/input_events_type_converters.h" | |
28 #include "ui/gfx/geometry/insets.h" | |
29 #include "ui/gfx/geometry/size.h" | |
30 | |
31 namespace mus { | |
32 | |
33 Id MakeTransportId(ClientSpecificId client_id, ClientSpecificId local_id) { | |
34 return (client_id << 16) | local_id; | |
35 } | |
36 | |
37 Id server_id(Window* window) { | |
38 return WindowPrivate(window).server_id(); | |
39 } | |
40 | |
41 // Helper called to construct a local window object from transport data. | |
42 Window* AddWindowToClient(WindowTreeClientImpl* client, | |
43 Window* parent, | |
44 const mojom::WindowDataPtr& window_data) { | |
45 // We don't use the ctor that takes a WindowTreeConnection here, since it | |
46 // will call back to the service and attempt to create a new window. | |
47 Window* window = WindowPrivate::LocalCreate(); | |
48 WindowPrivate private_window(window); | |
49 private_window.set_connection(client); | |
50 private_window.set_server_id(window_data->window_id); | |
51 private_window.set_visible(window_data->visible); | |
52 private_window.set_properties( | |
53 window_data->properties | |
54 .To<std::map<std::string, std::vector<uint8_t>>>()); | |
55 client->AddWindow(window); | |
56 private_window.LocalSetBounds(gfx::Rect(), window_data->bounds); | |
57 if (parent) | |
58 WindowPrivate(parent).LocalAddChild(window); | |
59 return window; | |
60 } | |
61 | |
62 Window* BuildWindowTree(WindowTreeClientImpl* client, | |
63 const mojo::Array<mojom::WindowDataPtr>& windows, | |
64 Window* initial_parent) { | |
65 std::vector<Window*> parents; | |
66 Window* root = NULL; | |
67 Window* last_window = NULL; | |
68 if (initial_parent) | |
69 parents.push_back(initial_parent); | |
70 for (size_t i = 0; i < windows.size(); ++i) { | |
71 if (last_window && windows[i]->parent_id == server_id(last_window)) { | |
72 parents.push_back(last_window); | |
73 } else if (!parents.empty()) { | |
74 while (server_id(parents.back()) != windows[i]->parent_id) | |
75 parents.pop_back(); | |
76 } | |
77 Window* window = AddWindowToClient( | |
78 client, !parents.empty() ? parents.back() : NULL, windows[i]); | |
79 if (!last_window) | |
80 root = window; | |
81 last_window = window; | |
82 } | |
83 return root; | |
84 } | |
85 | |
86 WindowTreeConnection* WindowTreeConnection::Create( | |
87 WindowTreeDelegate* delegate, | |
88 shell::Connector* connector) { | |
89 WindowTreeClientImpl* client = | |
90 new WindowTreeClientImpl(delegate, nullptr, nullptr); | |
91 client->ConnectViaWindowTreeFactory(connector); | |
92 return client; | |
93 } | |
94 | |
95 WindowTreeConnection* WindowTreeConnection::Create( | |
96 WindowTreeDelegate* delegate, | |
97 mojo::InterfaceRequest<mojom::WindowTreeClient> request, | |
98 CreateType create_type) { | |
99 WindowTreeClientImpl* client = | |
100 new WindowTreeClientImpl(delegate, nullptr, std::move(request)); | |
101 if (create_type == CreateType::WAIT_FOR_EMBED) | |
102 client->WaitForEmbed(); | |
103 return client; | |
104 } | |
105 | |
106 WindowTreeConnection* WindowTreeConnection::CreateForWindowManager( | |
107 WindowTreeDelegate* delegate, | |
108 mojo::InterfaceRequest<mojom::WindowTreeClient> request, | |
109 CreateType create_type, | |
110 WindowManagerDelegate* window_manager_delegate) { | |
111 WindowTreeClientImpl* client = new WindowTreeClientImpl( | |
112 delegate, window_manager_delegate, std::move(request)); | |
113 if (create_type == CreateType::WAIT_FOR_EMBED) | |
114 client->WaitForEmbed(); | |
115 return client; | |
116 } | |
117 | |
118 WindowTreeClientImpl::WindowTreeClientImpl( | |
119 WindowTreeDelegate* delegate, | |
120 WindowManagerDelegate* window_manager_delegate, | |
121 mojo::InterfaceRequest<mojom::WindowTreeClient> request) | |
122 : client_id_(0), | |
123 next_window_id_(1), | |
124 next_change_id_(1), | |
125 delegate_(delegate), | |
126 window_manager_delegate_(window_manager_delegate), | |
127 capture_window_(nullptr), | |
128 focused_window_(nullptr), | |
129 binding_(this), | |
130 tree_(nullptr), | |
131 delete_on_no_roots_(true), | |
132 in_destructor_(false), | |
133 cursor_location_memory_(nullptr), | |
134 weak_factory_(this) { | |
135 // Allow for a null request in tests. | |
136 if (request.is_pending()) | |
137 binding_.Bind(std::move(request)); | |
138 if (window_manager_delegate) | |
139 window_manager_delegate->SetWindowManagerClient(this); | |
140 } | |
141 | |
142 WindowTreeClientImpl::~WindowTreeClientImpl() { | |
143 in_destructor_ = true; | |
144 | |
145 std::vector<Window*> non_owned; | |
146 WindowTracker tracker; | |
147 while (!windows_.empty()) { | |
148 IdToWindowMap::iterator it = windows_.begin(); | |
149 if (OwnsWindow(it->second)) { | |
150 it->second->Destroy(); | |
151 } else { | |
152 tracker.Add(it->second); | |
153 windows_.erase(it); | |
154 } | |
155 } | |
156 | |
157 // Delete the non-owned windows last. In the typical case these are roots. The | |
158 // exception is the window manager and embed roots, which may know about | |
159 // other random windows that it doesn't own. | |
160 // NOTE: we manually delete as we're a friend. | |
161 while (!tracker.windows().empty()) | |
162 delete tracker.windows().front(); | |
163 | |
164 FOR_EACH_OBSERVER(WindowTreeConnectionObserver, observers_, | |
165 OnWillDestroyConnection(this)); | |
166 | |
167 delegate_->OnConnectionLost(this); | |
168 } | |
169 | |
170 void WindowTreeClientImpl::ConnectViaWindowTreeFactory( | |
171 shell::Connector* connector) { | |
172 // Clients created with no root shouldn't delete automatically. | |
173 delete_on_no_roots_ = false; | |
174 | |
175 // The client id doesn't really matter, we use 101 purely for debugging. | |
176 client_id_ = 101; | |
177 | |
178 mojom::WindowTreeFactoryPtr factory; | |
179 connector->ConnectToInterface("mojo:mus", &factory); | |
180 factory->CreateWindowTree(GetProxy(&tree_ptr_), | |
181 binding_.CreateInterfacePtrAndBind()); | |
182 tree_ = tree_ptr_.get(); | |
183 | |
184 tree_ptr_->GetCursorLocationMemory( | |
185 base::Bind(&WindowTreeClientImpl::OnReceivedCursorLocationMemory, | |
186 weak_factory_.GetWeakPtr())); | |
187 } | |
188 | |
189 void WindowTreeClientImpl::WaitForEmbed() { | |
190 DCHECK(roots_.empty()); | |
191 // OnEmbed() is the first function called. | |
192 binding_.WaitForIncomingMethodCall(); | |
193 // TODO(sky): deal with pipe being closed before we get OnEmbed(). | |
194 } | |
195 | |
196 void WindowTreeClientImpl::DestroyWindow(Window* window) { | |
197 DCHECK(tree_); | |
198 const uint32_t change_id = ScheduleInFlightChange(base::WrapUnique( | |
199 new CrashInFlightChange(window, ChangeType::DELETE_WINDOW))); | |
200 tree_->DeleteWindow(change_id, server_id(window)); | |
201 } | |
202 | |
203 void WindowTreeClientImpl::AddChild(Window* parent, Id child_id) { | |
204 DCHECK(tree_); | |
205 const uint32_t change_id = ScheduleInFlightChange( | |
206 base::WrapUnique(new CrashInFlightChange(parent, ChangeType::ADD_CHILD))); | |
207 tree_->AddWindow(change_id, parent->server_id(), child_id); | |
208 } | |
209 | |
210 void WindowTreeClientImpl::RemoveChild(Window* parent, Id child_id) { | |
211 DCHECK(tree_); | |
212 const uint32_t change_id = ScheduleInFlightChange(base::WrapUnique( | |
213 new CrashInFlightChange(parent, ChangeType::REMOVE_CHILD))); | |
214 tree_->RemoveWindowFromParent(change_id, child_id); | |
215 } | |
216 | |
217 void WindowTreeClientImpl::AddTransientWindow(Window* window, | |
218 Id transient_window_id) { | |
219 DCHECK(tree_); | |
220 const uint32_t change_id = ScheduleInFlightChange(base::WrapUnique( | |
221 new CrashInFlightChange(window, ChangeType::ADD_TRANSIENT_WINDOW))); | |
222 tree_->AddTransientWindow(change_id, server_id(window), transient_window_id); | |
223 } | |
224 | |
225 void WindowTreeClientImpl::RemoveTransientWindowFromParent(Window* window) { | |
226 DCHECK(tree_); | |
227 const uint32_t change_id = | |
228 ScheduleInFlightChange(base::WrapUnique(new CrashInFlightChange( | |
229 window, ChangeType::REMOVE_TRANSIENT_WINDOW_FROM_PARENT))); | |
230 tree_->RemoveTransientWindowFromParent(change_id, server_id(window)); | |
231 } | |
232 | |
233 void WindowTreeClientImpl::SetModal(Window* window) { | |
234 DCHECK(tree_); | |
235 const uint32_t change_id = ScheduleInFlightChange( | |
236 base::WrapUnique(new InFlightSetModalChange(window))); | |
237 tree_->SetModal(change_id, server_id(window)); | |
238 } | |
239 | |
240 void WindowTreeClientImpl::Reorder(Window* window, | |
241 Id relative_window_id, | |
242 mojom::OrderDirection direction) { | |
243 DCHECK(tree_); | |
244 const uint32_t change_id = ScheduleInFlightChange( | |
245 base::WrapUnique(new CrashInFlightChange(window, ChangeType::REORDER))); | |
246 tree_->ReorderWindow(change_id, server_id(window), relative_window_id, | |
247 direction); | |
248 } | |
249 | |
250 bool WindowTreeClientImpl::OwnsWindow(Window* window) const { | |
251 // Windows created via CreateTopLevelWindow() are not owned by us, but have | |
252 // our client id. | |
253 return HiWord(server_id(window)) == client_id_ && | |
254 roots_.count(window) == 0; | |
255 } | |
256 | |
257 void WindowTreeClientImpl::SetBounds(Window* window, | |
258 const gfx::Rect& old_bounds, | |
259 const gfx::Rect& bounds) { | |
260 DCHECK(tree_); | |
261 const uint32_t change_id = ScheduleInFlightChange( | |
262 base::WrapUnique(new InFlightBoundsChange(window, old_bounds))); | |
263 tree_->SetWindowBounds(change_id, server_id(window), bounds); | |
264 } | |
265 | |
266 void WindowTreeClientImpl::SetCapture(Window* window) { | |
267 // In order for us to get here we had to have exposed a window, which implies | |
268 // we got a client. | |
269 DCHECK(tree_); | |
270 if (capture_window_ == window) | |
271 return; | |
272 const uint32_t change_id = ScheduleInFlightChange( | |
273 base::WrapUnique(new InFlightCaptureChange(this, capture_window_))); | |
274 tree_->SetCapture(change_id, server_id(window)); | |
275 LocalSetCapture(window); | |
276 } | |
277 | |
278 void WindowTreeClientImpl::ReleaseCapture(Window* window) { | |
279 // In order for us to get here we had to have exposed a window, which implies | |
280 // we got a client. | |
281 DCHECK(tree_); | |
282 if (capture_window_ != window) | |
283 return; | |
284 const uint32_t change_id = ScheduleInFlightChange( | |
285 base::WrapUnique(new InFlightCaptureChange(this, window))); | |
286 tree_->ReleaseCapture(change_id, server_id(window)); | |
287 LocalSetCapture(nullptr); | |
288 } | |
289 | |
290 void WindowTreeClientImpl::SetClientArea( | |
291 Id window_id, | |
292 const gfx::Insets& client_area, | |
293 const std::vector<gfx::Rect>& additional_client_areas) { | |
294 DCHECK(tree_); | |
295 tree_->SetClientArea(window_id, client_area, additional_client_areas); | |
296 } | |
297 | |
298 void WindowTreeClientImpl::SetHitTestMask(Id window_id, const gfx::Rect& mask) { | |
299 DCHECK(tree_); | |
300 tree_->SetHitTestMask(window_id, mask); | |
301 } | |
302 | |
303 void WindowTreeClientImpl::ClearHitTestMask(Id window_id) { | |
304 DCHECK(tree_); | |
305 tree_->SetHitTestMask(window_id, {}); | |
306 } | |
307 | |
308 void WindowTreeClientImpl::SetFocus(Window* window) { | |
309 // In order for us to get here we had to have exposed a window, which implies | |
310 // we got a client. | |
311 DCHECK(tree_); | |
312 const uint32_t change_id = ScheduleInFlightChange( | |
313 base::WrapUnique(new InFlightFocusChange(this, focused_window_))); | |
314 tree_->SetFocus(change_id, window ? server_id(window) : 0); | |
315 LocalSetFocus(window); | |
316 } | |
317 | |
318 void WindowTreeClientImpl::SetCanFocus(Id window_id, bool can_focus) { | |
319 DCHECK(tree_); | |
320 tree_->SetCanFocus(window_id, can_focus); | |
321 } | |
322 | |
323 void WindowTreeClientImpl::SetPredefinedCursor(Id window_id, | |
324 mus::mojom::Cursor cursor_id) { | |
325 DCHECK(tree_); | |
326 | |
327 Window* window = GetWindowByServerId(window_id); | |
328 if (!window) | |
329 return; | |
330 | |
331 // We make an inflight change thing here. | |
332 const uint32_t change_id = ScheduleInFlightChange(base::WrapUnique( | |
333 new InFlightPredefinedCursorChange(window, window->predefined_cursor()))); | |
334 tree_->SetPredefinedCursor(change_id, window_id, cursor_id); | |
335 } | |
336 | |
337 void WindowTreeClientImpl::SetVisible(Window* window, bool visible) { | |
338 DCHECK(tree_); | |
339 const uint32_t change_id = ScheduleInFlightChange( | |
340 base::WrapUnique(new InFlightVisibleChange(window, !visible))); | |
341 tree_->SetWindowVisibility(change_id, server_id(window), visible); | |
342 } | |
343 | |
344 void WindowTreeClientImpl::SetOpacity(Window* window, float opacity) { | |
345 DCHECK(tree_); | |
346 const uint32_t change_id = ScheduleInFlightChange( | |
347 base::WrapUnique(new InFlightOpacityChange(window, window->opacity()))); | |
348 tree_->SetWindowOpacity(change_id, server_id(window), opacity); | |
349 } | |
350 | |
351 void WindowTreeClientImpl::SetProperty(Window* window, | |
352 const std::string& name, | |
353 mojo::Array<uint8_t> data) { | |
354 DCHECK(tree_); | |
355 | |
356 mojo::Array<uint8_t> old_value(nullptr); | |
357 if (window->HasSharedProperty(name)) | |
358 old_value = mojo::Array<uint8_t>::From(window->properties_[name]); | |
359 | |
360 const uint32_t change_id = ScheduleInFlightChange( | |
361 base::WrapUnique(new InFlightPropertyChange(window, name, old_value))); | |
362 tree_->SetWindowProperty(change_id, server_id(window), mojo::String(name), | |
363 std::move(data)); | |
364 } | |
365 | |
366 void WindowTreeClientImpl::SetWindowTextInputState( | |
367 Id window_id, | |
368 mojo::TextInputStatePtr state) { | |
369 DCHECK(tree_); | |
370 tree_->SetWindowTextInputState(window_id, std::move(state)); | |
371 } | |
372 | |
373 void WindowTreeClientImpl::SetImeVisibility(Id window_id, | |
374 bool visible, | |
375 mojo::TextInputStatePtr state) { | |
376 DCHECK(tree_); | |
377 tree_->SetImeVisibility(window_id, visible, std::move(state)); | |
378 } | |
379 | |
380 void WindowTreeClientImpl::Embed( | |
381 Id window_id, | |
382 mojom::WindowTreeClientPtr client, | |
383 const mojom::WindowTree::EmbedCallback& callback) { | |
384 DCHECK(tree_); | |
385 tree_->Embed(window_id, std::move(client), callback); | |
386 } | |
387 | |
388 void WindowTreeClientImpl::RequestClose(Window* window) { | |
389 if (window_manager_internal_client_) | |
390 window_manager_internal_client_->WmRequestClose(server_id(window)); | |
391 } | |
392 | |
393 void WindowTreeClientImpl::AttachSurface( | |
394 Id window_id, | |
395 mojom::SurfaceType type, | |
396 mojo::InterfaceRequest<mojom::Surface> surface, | |
397 mojom::SurfaceClientPtr client) { | |
398 DCHECK(tree_); | |
399 tree_->AttachSurface(window_id, type, std::move(surface), std::move(client)); | |
400 } | |
401 | |
402 void WindowTreeClientImpl::LocalSetCapture(Window* window) { | |
403 if (capture_window_ == window) | |
404 return; | |
405 Window* lost_capture = capture_window_; | |
406 capture_window_ = window; | |
407 if (lost_capture) { | |
408 FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(lost_capture).observers(), | |
409 OnWindowLostCapture(lost_capture)); | |
410 } | |
411 } | |
412 | |
413 void WindowTreeClientImpl::LocalSetFocus(Window* focused) { | |
414 Window* blurred = focused_window_; | |
415 // Update |focused_window_| before calling any of the observers, so that the | |
416 // observers get the correct result from calling |Window::HasFocus()|, | |
417 // |WindowTreeConnection::GetFocusedWindow()| etc. | |
418 focused_window_ = focused; | |
419 if (blurred) { | |
420 FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(blurred).observers(), | |
421 OnWindowFocusChanged(focused, blurred)); | |
422 } | |
423 if (focused) { | |
424 FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(focused).observers(), | |
425 OnWindowFocusChanged(focused, blurred)); | |
426 } | |
427 FOR_EACH_OBSERVER(WindowTreeConnectionObserver, observers_, | |
428 OnWindowTreeFocusChanged(focused, blurred)); | |
429 } | |
430 | |
431 void WindowTreeClientImpl::AddWindow(Window* window) { | |
432 DCHECK(windows_.find(server_id(window)) == windows_.end()); | |
433 windows_[server_id(window)] = window; | |
434 } | |
435 | |
436 void WindowTreeClientImpl::OnWindowDestroying(Window* window) { | |
437 // TODO(jonross): Also clear the focused window (crbug.com/611983) | |
438 if (window == capture_window_) { | |
439 InFlightCaptureChange reset_change(this, nullptr); | |
440 ApplyServerChangeToExistingInFlightChange(reset_change); | |
441 // Normally just updating the queued changes is sufficient. However since | |
442 // |window| is being destroyed, it will not be possible to notify its | |
443 // observers of the lost capture. Update local state now. | |
444 LocalSetCapture(nullptr); | |
445 } | |
446 } | |
447 | |
448 void WindowTreeClientImpl::OnWindowDestroyed(Window* window) { | |
449 windows_.erase(server_id(window)); | |
450 | |
451 for (auto& entry : embedded_windows_) { | |
452 auto it = entry.second.find(window); | |
453 if (it != entry.second.end()) { | |
454 entry.second.erase(it); | |
455 break; | |
456 } | |
457 } | |
458 | |
459 // Remove any InFlightChanges associated with the window. | |
460 std::set<uint32_t> in_flight_change_ids_to_remove; | |
461 for (const auto& pair : in_flight_map_) { | |
462 if (pair.second->window() == window) | |
463 in_flight_change_ids_to_remove.insert(pair.first); | |
464 } | |
465 for (auto change_id : in_flight_change_ids_to_remove) | |
466 in_flight_map_.erase(change_id); | |
467 | |
468 if (roots_.erase(window) > 0 && roots_.empty() && delete_on_no_roots_ && | |
469 !in_destructor_) { | |
470 delete this; | |
471 } | |
472 } | |
473 | |
474 Window* WindowTreeClientImpl::GetWindowByServerId(Id id) { | |
475 IdToWindowMap::const_iterator it = windows_.find(id); | |
476 return it != windows_.end() ? it->second : NULL; | |
477 } | |
478 | |
479 InFlightChange* WindowTreeClientImpl::GetOldestInFlightChangeMatching( | |
480 const InFlightChange& change) { | |
481 for (const auto& pair : in_flight_map_) { | |
482 if (pair.second->window() == change.window() && | |
483 pair.second->change_type() == change.change_type() && | |
484 pair.second->Matches(change)) { | |
485 return pair.second.get(); | |
486 } | |
487 } | |
488 return nullptr; | |
489 } | |
490 | |
491 uint32_t WindowTreeClientImpl::ScheduleInFlightChange( | |
492 std::unique_ptr<InFlightChange> change) { | |
493 DCHECK(!change->window() || | |
494 windows_.count(change->window()->server_id()) > 0); | |
495 const uint32_t change_id = next_change_id_++; | |
496 in_flight_map_[change_id] = std::move(change); | |
497 return change_id; | |
498 } | |
499 | |
500 bool WindowTreeClientImpl::ApplyServerChangeToExistingInFlightChange( | |
501 const InFlightChange& change) { | |
502 InFlightChange* existing_change = GetOldestInFlightChangeMatching(change); | |
503 if (!existing_change) | |
504 return false; | |
505 | |
506 existing_change->SetRevertValueFrom(change); | |
507 return true; | |
508 } | |
509 | |
510 Window* WindowTreeClientImpl::NewWindowImpl( | |
511 NewWindowType type, | |
512 const Window::SharedProperties* properties) { | |
513 DCHECK(tree_); | |
514 Window* window = | |
515 new Window(this, MakeTransportId(client_id_, next_window_id_++)); | |
516 if (properties) | |
517 window->properties_ = *properties; | |
518 AddWindow(window); | |
519 | |
520 const uint32_t change_id = ScheduleInFlightChange(base::WrapUnique( | |
521 new CrashInFlightChange(window, type == NewWindowType::CHILD | |
522 ? ChangeType::NEW_WINDOW | |
523 : ChangeType::NEW_TOP_LEVEL_WINDOW))); | |
524 mojo::Map<mojo::String, mojo::Array<uint8_t>> transport_properties; | |
525 if (properties) { | |
526 transport_properties = | |
527 mojo::Map<mojo::String, mojo::Array<uint8_t>>::From(*properties); | |
528 } | |
529 if (type == NewWindowType::CHILD) { | |
530 tree_->NewWindow(change_id, server_id(window), | |
531 std::move(transport_properties)); | |
532 } else { | |
533 roots_.insert(window); | |
534 tree_->NewTopLevelWindow(change_id, server_id(window), | |
535 std::move(transport_properties)); | |
536 } | |
537 return window; | |
538 } | |
539 | |
540 void WindowTreeClientImpl::OnEmbedImpl(mojom::WindowTree* window_tree, | |
541 ClientSpecificId client_id, | |
542 mojom::WindowDataPtr root_data, | |
543 int64_t display_id, | |
544 Id focused_window_id, | |
545 bool drawn) { | |
546 // WARNING: this is only called if WindowTreeClientImpl was created as the | |
547 // result of an embedding. | |
548 tree_ = window_tree; | |
549 client_id_ = client_id; | |
550 | |
551 DCHECK(roots_.empty()); | |
552 Window* root = AddWindowToClient(this, nullptr, root_data); | |
553 WindowPrivate(root).LocalSetDisplay(display_id); | |
554 roots_.insert(root); | |
555 | |
556 focused_window_ = GetWindowByServerId(focused_window_id); | |
557 | |
558 WindowPrivate(root).LocalSetParentDrawn(drawn); | |
559 | |
560 delegate_->OnEmbed(root); | |
561 | |
562 if (focused_window_) { | |
563 FOR_EACH_OBSERVER(WindowTreeConnectionObserver, observers_, | |
564 OnWindowTreeFocusChanged(focused_window_, nullptr)); | |
565 } | |
566 } | |
567 | |
568 void WindowTreeClientImpl::OnReceivedCursorLocationMemory( | |
569 mojo::ScopedSharedBufferHandle handle) { | |
570 cursor_location_handle_ = std::move(handle); | |
571 MojoResult result = mojo::MapBuffer( | |
572 cursor_location_handle_.get(), 0, | |
573 sizeof(base::subtle::Atomic32), | |
574 reinterpret_cast<void**>(&cursor_location_memory_), | |
575 MOJO_MAP_BUFFER_FLAG_NONE); | |
576 if (result != MOJO_RESULT_OK) { | |
577 NOTREACHED(); | |
578 return; | |
579 } | |
580 DCHECK(cursor_location_memory_); | |
581 } | |
582 | |
583 //////////////////////////////////////////////////////////////////////////////// | |
584 // WindowTreeClientImpl, WindowTreeConnection implementation: | |
585 | |
586 void WindowTreeClientImpl::SetDeleteOnNoRoots(bool value) { | |
587 delete_on_no_roots_ = value; | |
588 } | |
589 | |
590 const std::set<Window*>& WindowTreeClientImpl::GetRoots() { | |
591 return roots_; | |
592 } | |
593 | |
594 Window* WindowTreeClientImpl::GetFocusedWindow() { | |
595 return focused_window_; | |
596 } | |
597 | |
598 void WindowTreeClientImpl::ClearFocus() { | |
599 if (!focused_window_) | |
600 return; | |
601 | |
602 SetFocus(nullptr); | |
603 } | |
604 | |
605 gfx::Point WindowTreeClientImpl::GetCursorScreenPoint() { | |
606 // We raced initialization. Return (0, 0). | |
607 if (!cursor_location_memory_) | |
608 return gfx::Point(); | |
609 | |
610 base::subtle::Atomic32 location = | |
611 base::subtle::NoBarrier_Load(cursor_location_memory_); | |
612 return gfx::Point(static_cast<int16_t>(location >> 16), | |
613 static_cast<int16_t>(location & 0xFFFF)); | |
614 } | |
615 | |
616 void WindowTreeClientImpl::SetEventObserver(mojom::EventMatcherPtr matcher) { | |
617 if (matcher.is_null()) { | |
618 has_event_observer_ = false; | |
619 tree_->SetEventObserver(nullptr, 0u); | |
620 } else { | |
621 has_event_observer_ = true; | |
622 event_observer_id_++; | |
623 tree_->SetEventObserver(std::move(matcher), event_observer_id_); | |
624 } | |
625 } | |
626 | |
627 Window* WindowTreeClientImpl::NewWindow( | |
628 const Window::SharedProperties* properties) { | |
629 return NewWindowImpl(NewWindowType::CHILD, properties); | |
630 } | |
631 | |
632 Window* WindowTreeClientImpl::NewTopLevelWindow( | |
633 const Window::SharedProperties* properties) { | |
634 Window* window = NewWindowImpl(NewWindowType::TOP_LEVEL, properties); | |
635 // Assume newly created top level windows are drawn by default, otherwise | |
636 // requests to focus will fail. We will get the real value in | |
637 // OnTopLevelCreated(). | |
638 window->LocalSetParentDrawn(true); | |
639 return window; | |
640 } | |
641 | |
642 //////////////////////////////////////////////////////////////////////////////// | |
643 // WindowTreeClientImpl, WindowTreeClient implementation: | |
644 | |
645 void WindowTreeClientImpl::AddObserver(WindowTreeConnectionObserver* observer) { | |
646 observers_.AddObserver(observer); | |
647 } | |
648 | |
649 void WindowTreeClientImpl::RemoveObserver( | |
650 WindowTreeConnectionObserver* observer) { | |
651 observers_.RemoveObserver(observer); | |
652 } | |
653 | |
654 void WindowTreeClientImpl::OnEmbed(ClientSpecificId client_id, | |
655 mojom::WindowDataPtr root_data, | |
656 mojom::WindowTreePtr tree, | |
657 int64_t display_id, | |
658 Id focused_window_id, | |
659 bool drawn) { | |
660 DCHECK(!tree_ptr_); | |
661 tree_ptr_ = std::move(tree); | |
662 tree_ptr_.set_connection_error_handler([this]() { delete this; }); | |
663 | |
664 if (window_manager_delegate_) { | |
665 tree_ptr_->GetWindowManagerClient(GetProxy(&window_manager_internal_client_, | |
666 tree_ptr_.associated_group())); | |
667 } | |
668 | |
669 OnEmbedImpl(tree_ptr_.get(), client_id, std::move(root_data), display_id, | |
670 focused_window_id, drawn); | |
671 } | |
672 | |
673 void WindowTreeClientImpl::OnEmbeddedAppDisconnected(Id window_id) { | |
674 Window* window = GetWindowByServerId(window_id); | |
675 if (window) { | |
676 FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(window).observers(), | |
677 OnWindowEmbeddedAppDisconnected(window)); | |
678 } | |
679 } | |
680 | |
681 void WindowTreeClientImpl::OnUnembed(Id window_id) { | |
682 Window* window = GetWindowByServerId(window_id); | |
683 if (!window) | |
684 return; | |
685 | |
686 delegate_->OnUnembed(window); | |
687 WindowPrivate(window).LocalDestroy(); | |
688 } | |
689 | |
690 void WindowTreeClientImpl::OnLostCapture(Id window_id) { | |
691 Window* window = GetWindowByServerId(window_id); | |
692 if (!window) | |
693 return; | |
694 | |
695 InFlightCaptureChange reset_change(this, nullptr); | |
696 if (ApplyServerChangeToExistingInFlightChange(reset_change)) | |
697 return; | |
698 | |
699 LocalSetCapture(nullptr); | |
700 } | |
701 | |
702 void WindowTreeClientImpl::OnTopLevelCreated(uint32_t change_id, | |
703 mojom::WindowDataPtr data, | |
704 int64_t display_id, | |
705 bool drawn) { | |
706 // The server ack'd the top level window we created and supplied the state | |
707 // of the window at the time the server created it. For properties we do not | |
708 // have changes in flight for we can update them immediately. For properties | |
709 // with changes in flight we set the revert value from the server. | |
710 | |
711 if (!in_flight_map_.count(change_id)) { | |
712 // The window may have been destroyed locally before the server could finish | |
713 // creating the window, and before the server received the notification that | |
714 // the window has been destroyed. | |
715 return; | |
716 } | |
717 std::unique_ptr<InFlightChange> change(std::move(in_flight_map_[change_id])); | |
718 in_flight_map_.erase(change_id); | |
719 | |
720 Window* window = change->window(); | |
721 WindowPrivate window_private(window); | |
722 | |
723 // Drawn state and display-id always come from the server (they can't be | |
724 // modified locally). | |
725 window_private.LocalSetParentDrawn(drawn); | |
726 window_private.LocalSetDisplay(display_id); | |
727 | |
728 // The default visibilty is false, we only need update visibility if it | |
729 // differs from that. | |
730 if (data->visible) { | |
731 InFlightVisibleChange visible_change(window, data->visible); | |
732 InFlightChange* current_change = | |
733 GetOldestInFlightChangeMatching(visible_change); | |
734 if (current_change) | |
735 current_change->SetRevertValueFrom(visible_change); | |
736 else | |
737 window_private.LocalSetVisible(true); | |
738 } | |
739 | |
740 const gfx::Rect bounds(data->bounds); | |
741 { | |
742 InFlightBoundsChange bounds_change(window, bounds); | |
743 InFlightChange* current_change = | |
744 GetOldestInFlightChangeMatching(bounds_change); | |
745 if (current_change) | |
746 current_change->SetRevertValueFrom(bounds_change); | |
747 else if (window->bounds() != bounds) | |
748 window_private.LocalSetBounds(window->bounds(), bounds); | |
749 } | |
750 | |
751 // There is currently no API to bulk set properties, so we iterate over each | |
752 // property individually. | |
753 Window::SharedProperties properties = | |
754 data->properties.To<std::map<std::string, std::vector<uint8_t>>>(); | |
755 for (const auto& pair : properties) { | |
756 InFlightPropertyChange property_change( | |
757 window, pair.first, mojo::Array<uint8_t>::From(pair.second)); | |
758 InFlightChange* current_change = | |
759 GetOldestInFlightChangeMatching(property_change); | |
760 if (current_change) | |
761 current_change->SetRevertValueFrom(property_change); | |
762 else | |
763 window_private.LocalSetSharedProperty(pair.first, &(pair.second)); | |
764 } | |
765 | |
766 // Top level windows should not have a parent. | |
767 DCHECK_EQ(0u, data->parent_id); | |
768 } | |
769 | |
770 void WindowTreeClientImpl::OnWindowBoundsChanged(Id window_id, | |
771 const gfx::Rect& old_bounds, | |
772 const gfx::Rect& new_bounds) { | |
773 Window* window = GetWindowByServerId(window_id); | |
774 if (!window) | |
775 return; | |
776 | |
777 InFlightBoundsChange new_change(window, new_bounds); | |
778 if (ApplyServerChangeToExistingInFlightChange(new_change)) | |
779 return; | |
780 | |
781 WindowPrivate(window).LocalSetBounds(old_bounds, new_bounds); | |
782 } | |
783 | |
784 void WindowTreeClientImpl::OnClientAreaChanged( | |
785 uint32_t window_id, | |
786 const gfx::Insets& new_client_area, | |
787 mojo::Array<gfx::Rect> new_additional_client_areas) { | |
788 Window* window = GetWindowByServerId(window_id); | |
789 if (window) { | |
790 WindowPrivate(window).LocalSetClientArea( | |
791 new_client_area, | |
792 new_additional_client_areas.To<std::vector<gfx::Rect>>()); | |
793 } | |
794 } | |
795 | |
796 void WindowTreeClientImpl::OnTransientWindowAdded( | |
797 uint32_t window_id, | |
798 uint32_t transient_window_id) { | |
799 Window* window = GetWindowByServerId(window_id); | |
800 Window* transient_window = GetWindowByServerId(transient_window_id); | |
801 // window or transient_window or both may be null if a local delete occurs | |
802 // with an in flight add from the server. | |
803 if (window && transient_window) | |
804 WindowPrivate(window).LocalAddTransientWindow(transient_window); | |
805 } | |
806 | |
807 void WindowTreeClientImpl::OnTransientWindowRemoved( | |
808 uint32_t window_id, | |
809 uint32_t transient_window_id) { | |
810 Window* window = GetWindowByServerId(window_id); | |
811 Window* transient_window = GetWindowByServerId(transient_window_id); | |
812 // window or transient_window or both may be null if a local delete occurs | |
813 // with an in flight delete from the server. | |
814 if (window && transient_window) | |
815 WindowPrivate(window).LocalRemoveTransientWindow(transient_window); | |
816 } | |
817 | |
818 void WindowTreeClientImpl::OnWindowHierarchyChanged( | |
819 Id window_id, | |
820 Id old_parent_id, | |
821 Id new_parent_id, | |
822 mojo::Array<mojom::WindowDataPtr> windows) { | |
823 Window* initial_parent = | |
824 windows.size() ? GetWindowByServerId(windows[0]->parent_id) : NULL; | |
825 | |
826 const bool was_window_known = GetWindowByServerId(window_id) != nullptr; | |
827 | |
828 BuildWindowTree(this, windows, initial_parent); | |
829 | |
830 // If the window was not known, then BuildWindowTree() will have created it | |
831 // and parented the window. | |
832 if (!was_window_known) | |
833 return; | |
834 | |
835 Window* new_parent = GetWindowByServerId(new_parent_id); | |
836 Window* old_parent = GetWindowByServerId(old_parent_id); | |
837 Window* window = GetWindowByServerId(window_id); | |
838 if (new_parent) | |
839 WindowPrivate(new_parent).LocalAddChild(window); | |
840 else | |
841 WindowPrivate(old_parent).LocalRemoveChild(window); | |
842 } | |
843 | |
844 void WindowTreeClientImpl::OnWindowReordered(Id window_id, | |
845 Id relative_window_id, | |
846 mojom::OrderDirection direction) { | |
847 Window* window = GetWindowByServerId(window_id); | |
848 Window* relative_window = GetWindowByServerId(relative_window_id); | |
849 if (window && relative_window) | |
850 WindowPrivate(window).LocalReorder(relative_window, direction); | |
851 } | |
852 | |
853 void WindowTreeClientImpl::OnWindowDeleted(Id window_id) { | |
854 Window* window = GetWindowByServerId(window_id); | |
855 if (window) | |
856 WindowPrivate(window).LocalDestroy(); | |
857 } | |
858 | |
859 Window* WindowTreeClientImpl::GetCaptureWindow() { | |
860 return capture_window_; | |
861 } | |
862 | |
863 void WindowTreeClientImpl::OnWindowVisibilityChanged(Id window_id, | |
864 bool visible) { | |
865 Window* window = GetWindowByServerId(window_id); | |
866 if (!window) | |
867 return; | |
868 | |
869 InFlightVisibleChange new_change(window, visible); | |
870 if (ApplyServerChangeToExistingInFlightChange(new_change)) | |
871 return; | |
872 | |
873 WindowPrivate(window).LocalSetVisible(visible); | |
874 } | |
875 | |
876 void WindowTreeClientImpl::OnWindowOpacityChanged(Id window_id, | |
877 float old_opacity, | |
878 float new_opacity) { | |
879 Window* window = GetWindowByServerId(window_id); | |
880 if (!window) | |
881 return; | |
882 | |
883 InFlightOpacityChange new_change(window, new_opacity); | |
884 if (ApplyServerChangeToExistingInFlightChange(new_change)) | |
885 return; | |
886 | |
887 WindowPrivate(window).LocalSetOpacity(new_opacity); | |
888 } | |
889 | |
890 void WindowTreeClientImpl::OnWindowParentDrawnStateChanged(Id window_id, | |
891 bool drawn) { | |
892 Window* window = GetWindowByServerId(window_id); | |
893 if (window) | |
894 WindowPrivate(window).LocalSetParentDrawn(drawn); | |
895 } | |
896 | |
897 void WindowTreeClientImpl::OnWindowSharedPropertyChanged( | |
898 Id window_id, | |
899 const mojo::String& name, | |
900 mojo::Array<uint8_t> new_data) { | |
901 Window* window = GetWindowByServerId(window_id); | |
902 if (!window) | |
903 return; | |
904 | |
905 InFlightPropertyChange new_change(window, name, new_data); | |
906 if (ApplyServerChangeToExistingInFlightChange(new_change)) | |
907 return; | |
908 | |
909 WindowPrivate(window).LocalSetSharedProperty(name, std::move(new_data)); | |
910 } | |
911 | |
912 void WindowTreeClientImpl::OnWindowInputEvent(uint32_t event_id, | |
913 Id window_id, | |
914 mojom::EventPtr event, | |
915 uint32_t event_observer_id) { | |
916 std::unique_ptr<ui::Event> ui_event = event.To<std::unique_ptr<ui::Event>>(); | |
917 Window* window = GetWindowByServerId(window_id); // May be null. | |
918 | |
919 // Non-zero event_observer_id means it matched an event observer on the | |
920 // server. | |
921 if (event_observer_id != 0 && has_event_observer_ && | |
922 event_observer_id == event_observer_id_) | |
923 delegate_->OnEventObserved(*ui_event, window); | |
924 | |
925 if (!window || !window->input_event_handler_) { | |
926 tree_->OnWindowInputEventAck(event_id, mojom::EventResult::UNHANDLED); | |
927 return; | |
928 } | |
929 | |
930 std::unique_ptr<base::Callback<void(mojom::EventResult)>> ack_callback( | |
931 new base::Callback<void(mojom::EventResult)>( | |
932 base::Bind(&mojom::WindowTree::OnWindowInputEventAck, | |
933 base::Unretained(tree_), event_id))); | |
934 window->input_event_handler_->OnWindowInputEvent( | |
935 window, *event.To<std::unique_ptr<ui::Event>>().get(), &ack_callback); | |
936 | |
937 // The handler did not take ownership of the callback, so we send the ack, | |
938 // marking the event as not consumed. | |
939 if (ack_callback) | |
940 ack_callback->Run(mojom::EventResult::UNHANDLED); | |
941 } | |
942 | |
943 void WindowTreeClientImpl::OnEventObserved(mojom::EventPtr event, | |
944 uint32_t event_observer_id) { | |
945 if (has_event_observer_ && event_observer_id == event_observer_id_) { | |
946 std::unique_ptr<ui::Event> ui_event = | |
947 event.To<std::unique_ptr<ui::Event>>(); | |
948 delegate_->OnEventObserved(*ui_event, nullptr /* target */); | |
949 } | |
950 } | |
951 | |
952 void WindowTreeClientImpl::OnWindowFocused(Id focused_window_id) { | |
953 Window* focused_window = GetWindowByServerId(focused_window_id); | |
954 InFlightFocusChange new_change(this, focused_window); | |
955 if (ApplyServerChangeToExistingInFlightChange(new_change)) | |
956 return; | |
957 | |
958 LocalSetFocus(focused_window); | |
959 } | |
960 | |
961 void WindowTreeClientImpl::OnWindowPredefinedCursorChanged( | |
962 Id window_id, | |
963 mojom::Cursor cursor) { | |
964 Window* window = GetWindowByServerId(window_id); | |
965 if (!window) | |
966 return; | |
967 | |
968 InFlightPredefinedCursorChange new_change(window, cursor); | |
969 if (ApplyServerChangeToExistingInFlightChange(new_change)) | |
970 return; | |
971 | |
972 WindowPrivate(window).LocalSetPredefinedCursor(cursor); | |
973 } | |
974 | |
975 void WindowTreeClientImpl::OnChangeCompleted(uint32_t change_id, bool success) { | |
976 std::unique_ptr<InFlightChange> change(std::move(in_flight_map_[change_id])); | |
977 in_flight_map_.erase(change_id); | |
978 if (!change) | |
979 return; | |
980 | |
981 if (!success) | |
982 change->ChangeFailed(); | |
983 | |
984 InFlightChange* next_change = GetOldestInFlightChangeMatching(*change); | |
985 if (next_change) { | |
986 if (!success) | |
987 next_change->SetRevertValueFrom(*change); | |
988 } else if (!success) { | |
989 change->Revert(); | |
990 } | |
991 } | |
992 | |
993 void WindowTreeClientImpl::GetWindowManager( | |
994 mojo::AssociatedInterfaceRequest<WindowManager> internal) { | |
995 window_manager_internal_.reset( | |
996 new mojo::AssociatedBinding<mojom::WindowManager>(this, | |
997 std::move(internal))); | |
998 } | |
999 | |
1000 void WindowTreeClientImpl::RequestClose(uint32_t window_id) { | |
1001 Window* window = GetWindowByServerId(window_id); | |
1002 if (!window || !IsRoot(window)) | |
1003 return; | |
1004 | |
1005 FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(window).observers(), | |
1006 OnRequestClose(window)); | |
1007 } | |
1008 | |
1009 void WindowTreeClientImpl::WmSetBounds(uint32_t change_id, | |
1010 Id window_id, | |
1011 const gfx::Rect& transit_bounds) { | |
1012 Window* window = GetWindowByServerId(window_id); | |
1013 bool result = false; | |
1014 if (window) { | |
1015 DCHECK(window_manager_delegate_); | |
1016 gfx::Rect bounds = transit_bounds; | |
1017 result = window_manager_delegate_->OnWmSetBounds(window, &bounds); | |
1018 if (result) { | |
1019 // If the resulting bounds differ return false. Returning false ensures | |
1020 // the client applies the bounds we set below. | |
1021 result = bounds == transit_bounds; | |
1022 window->SetBounds(bounds); | |
1023 } | |
1024 } | |
1025 if (window_manager_internal_client_) | |
1026 window_manager_internal_client_->WmResponse(change_id, result); | |
1027 } | |
1028 | |
1029 void WindowTreeClientImpl::WmSetProperty(uint32_t change_id, | |
1030 Id window_id, | |
1031 const mojo::String& name, | |
1032 mojo::Array<uint8_t> transit_data) { | |
1033 Window* window = GetWindowByServerId(window_id); | |
1034 bool result = false; | |
1035 if (window) { | |
1036 DCHECK(window_manager_delegate_); | |
1037 std::unique_ptr<std::vector<uint8_t>> data; | |
1038 if (!transit_data.is_null()) { | |
1039 data.reset( | |
1040 new std::vector<uint8_t>(transit_data.To<std::vector<uint8_t>>())); | |
1041 } | |
1042 result = window_manager_delegate_->OnWmSetProperty(window, name, &data); | |
1043 if (result) { | |
1044 // If the resulting bounds differ return false. Returning false ensures | |
1045 // the client applies the bounds we set below. | |
1046 window->SetSharedPropertyInternal(name, data.get()); | |
1047 } | |
1048 } | |
1049 if (window_manager_internal_client_) | |
1050 window_manager_internal_client_->WmResponse(change_id, result); | |
1051 } | |
1052 | |
1053 void WindowTreeClientImpl::WmCreateTopLevelWindow( | |
1054 uint32_t change_id, | |
1055 ClientSpecificId requesting_client_id, | |
1056 mojo::Map<mojo::String, mojo::Array<uint8_t>> transport_properties) { | |
1057 std::map<std::string, std::vector<uint8_t>> properties = | |
1058 transport_properties.To<std::map<std::string, std::vector<uint8_t>>>(); | |
1059 Window* window = | |
1060 window_manager_delegate_->OnWmCreateTopLevelWindow(&properties); | |
1061 embedded_windows_[requesting_client_id].insert(window); | |
1062 if (window_manager_internal_client_) { | |
1063 window_manager_internal_client_->OnWmCreatedTopLevelWindow( | |
1064 change_id, server_id(window)); | |
1065 } | |
1066 } | |
1067 | |
1068 void WindowTreeClientImpl::WmClientJankinessChanged(ClientSpecificId client_id, | |
1069 bool janky) { | |
1070 if (window_manager_delegate_) { | |
1071 auto it = embedded_windows_.find(client_id); | |
1072 CHECK(it != embedded_windows_.end()); | |
1073 window_manager_delegate_->OnWmClientJankinessChanged( | |
1074 embedded_windows_[client_id], janky); | |
1075 } | |
1076 } | |
1077 | |
1078 void WindowTreeClientImpl::OnAccelerator(uint32_t id, mojom::EventPtr event) { | |
1079 window_manager_delegate_->OnAccelerator( | |
1080 id, *event.To<std::unique_ptr<ui::Event>>().get()); | |
1081 } | |
1082 | |
1083 void WindowTreeClientImpl::SetFrameDecorationValues( | |
1084 mojom::FrameDecorationValuesPtr values) { | |
1085 if (window_manager_internal_client_) { | |
1086 window_manager_internal_client_->WmSetFrameDecorationValues( | |
1087 std::move(values)); | |
1088 } | |
1089 } | |
1090 | |
1091 void WindowTreeClientImpl::SetNonClientCursor(Window* window, | |
1092 mus::mojom::Cursor cursor_id) { | |
1093 window_manager_internal_client_->WmSetNonClientCursor(server_id(window), | |
1094 cursor_id); | |
1095 } | |
1096 | |
1097 void WindowTreeClientImpl::AddAccelerator( | |
1098 uint32_t id, | |
1099 mojom::EventMatcherPtr event_matcher, | |
1100 const base::Callback<void(bool)>& callback) { | |
1101 if (window_manager_internal_client_) { | |
1102 window_manager_internal_client_->AddAccelerator( | |
1103 id, std::move(event_matcher), callback); | |
1104 } | |
1105 } | |
1106 | |
1107 void WindowTreeClientImpl::RemoveAccelerator(uint32_t id) { | |
1108 if (window_manager_internal_client_) { | |
1109 window_manager_internal_client_->RemoveAccelerator(id); | |
1110 } | |
1111 } | |
1112 | |
1113 void WindowTreeClientImpl::AddActivationParent(Window* window) { | |
1114 if (window_manager_internal_client_) | |
1115 window_manager_internal_client_->AddActivationParent(server_id(window)); | |
1116 } | |
1117 | |
1118 void WindowTreeClientImpl::RemoveActivationParent(Window* window) { | |
1119 if (window_manager_internal_client_) | |
1120 window_manager_internal_client_->RemoveActivationParent(server_id(window)); | |
1121 } | |
1122 | |
1123 void WindowTreeClientImpl::ActivateNextWindow() { | |
1124 if (window_manager_internal_client_) | |
1125 window_manager_internal_client_->ActivateNextWindow(); | |
1126 } | |
1127 | |
1128 void WindowTreeClientImpl::SetUnderlaySurfaceOffsetAndExtendedHitArea( | |
1129 Window* window, | |
1130 const gfx::Vector2d& offset, | |
1131 const gfx::Insets& hit_area) { | |
1132 if (window_manager_internal_client_) { | |
1133 window_manager_internal_client_->SetUnderlaySurfaceOffsetAndExtendedHitArea( | |
1134 server_id(window), offset.x(), offset.y(), hit_area); | |
1135 } | |
1136 } | |
1137 | |
1138 } // namespace mus | |
OLD | NEW |