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