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