Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: ui/aura/mus/window_tree_client.cc

Issue 2468493002: Fix bug in keeping capture in sync during destruction (Closed)
Patch Set: feedback Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/aura/mus/window_tree_client.h ('k') | ui/aura/mus/window_tree_client_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/aura/mus/window_tree_client.h" 5 #include "ui/aura/mus/window_tree_client.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/auto_reset.h" 13 #include "base/auto_reset.h"
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "services/service_manager/public/cpp/connector.h" 16 #include "services/service_manager/public/cpp/connector.h"
17 #include "services/ui/public/interfaces/window_manager_window_tree_factory.mojom .h" 17 #include "services/ui/public/interfaces/window_manager_window_tree_factory.mojom .h"
18 #include "ui/aura/client/aura_constants.h" 18 #include "ui/aura/client/aura_constants.h"
19 #include "ui/aura/client/capture_client.h"
20 #include "ui/aura/client/drag_drop_client.h" 19 #include "ui/aura/client/drag_drop_client.h"
21 #include "ui/aura/client/focus_client.h" 20 #include "ui/aura/client/focus_client.h"
22 #include "ui/aura/client/transient_window_client.h" 21 #include "ui/aura/client/transient_window_client.h"
22 #include "ui/aura/mus/capture_synchronizer.h"
23 #include "ui/aura/mus/drag_drop_controller_mus.h" 23 #include "ui/aura/mus/drag_drop_controller_mus.h"
24 #include "ui/aura/mus/in_flight_change.h" 24 #include "ui/aura/mus/in_flight_change.h"
25 #include "ui/aura/mus/input_method_mus.h" 25 #include "ui/aura/mus/input_method_mus.h"
26 #include "ui/aura/mus/property_converter.h" 26 #include "ui/aura/mus/property_converter.h"
27 #include "ui/aura/mus/surface_id_handler.h" 27 #include "ui/aura/mus/surface_id_handler.h"
28 #include "ui/aura/mus/window_manager_delegate.h" 28 #include "ui/aura/mus/window_manager_delegate.h"
29 #include "ui/aura/mus/window_mus.h" 29 #include "ui/aura/mus/window_mus.h"
30 #include "ui/aura/mus/window_port_mus.h" 30 #include "ui/aura/mus/window_port_mus.h"
31 #include "ui/aura/mus/window_tree_client_delegate.h" 31 #include "ui/aura/mus/window_tree_client_delegate.h"
32 #include "ui/aura/mus/window_tree_client_observer.h" 32 #include "ui/aura/mus/window_tree_client_observer.h"
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 delegate_(delegate), 145 delegate_(delegate),
146 window_manager_delegate_(window_manager_delegate), 146 window_manager_delegate_(window_manager_delegate),
147 binding_(this), 147 binding_(this),
148 tree_(nullptr), 148 tree_(nullptr),
149 in_destructor_(false), 149 in_destructor_(false),
150 weak_factory_(this) { 150 weak_factory_(this) {
151 // Allow for a null request in tests. 151 // Allow for a null request in tests.
152 if (request.is_pending()) 152 if (request.is_pending())
153 binding_.Bind(std::move(request)); 153 binding_.Bind(std::move(request));
154 delegate_->GetFocusClient()->AddObserver(this); 154 delegate_->GetFocusClient()->AddObserver(this);
155 delegate_->GetCaptureClient()->AddObserver(this);
156 client::GetTransientWindowClient()->AddObserver(this); 155 client::GetTransientWindowClient()->AddObserver(this);
157 if (window_manager_delegate) 156 if (window_manager_delegate)
158 window_manager_delegate->SetWindowManagerClient(this); 157 window_manager_delegate->SetWindowManagerClient(this);
159 } 158 }
160 159
161 WindowTreeClient::~WindowTreeClient() { 160 WindowTreeClient::~WindowTreeClient() {
162 in_destructor_ = true; 161 in_destructor_ = true;
163 162
164 for (WindowTreeClientObserver& observer : observers_) 163 for (WindowTreeClientObserver& observer : observers_)
165 observer.OnWillDestroyClient(this); 164 observer.OnWillDestroyClient(this);
(...skipping 14 matching lines...) Expand all
180 179
181 // Delete the non-owned windows last. In the typical case these are roots. The 180 // Delete the non-owned windows last. In the typical case these are roots. The
182 // exception is the window manager and embed roots, which may know about 181 // exception is the window manager and embed roots, which may know about
183 // other random windows that it doesn't own. 182 // other random windows that it doesn't own.
184 while (!tracker.windows().empty()) 183 while (!tracker.windows().empty())
185 delete tracker.windows().front(); 184 delete tracker.windows().front();
186 185
187 for (WindowTreeClientObserver& observer : observers_) 186 for (WindowTreeClientObserver& observer : observers_)
188 observer.OnDidDestroyClient(this); 187 observer.OnDidDestroyClient(this);
189 188
189 capture_synchronizer_.reset();
190
190 client::GetTransientWindowClient()->RemoveObserver(this); 191 client::GetTransientWindowClient()->RemoveObserver(this);
191 delegate_->GetCaptureClient()->RemoveObserver(this);
192 delegate_->GetFocusClient()->RemoveObserver(this); 192 delegate_->GetFocusClient()->RemoveObserver(this);
193 } 193 }
194 194
195 void WindowTreeClient::ConnectViaWindowTreeFactory( 195 void WindowTreeClient::ConnectViaWindowTreeFactory(
196 service_manager::Connector* connector) { 196 service_manager::Connector* connector) {
197 // The client id doesn't really matter, we use 101 purely for debugging. 197 // The client id doesn't really matter, we use 101 purely for debugging.
198 client_id_ = 101; 198 client_id_ = 101;
199 199
200 ui::mojom::WindowTreeFactoryPtr factory; 200 ui::mojom::WindowTreeFactoryPtr factory;
201 connector->ConnectToInterface("service:ui", &factory); 201 connector->ConnectToInterface("service:ui", &factory);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 if (!focus_client) 339 if (!focus_client)
340 return; 340 return;
341 341
342 DCHECK(!setting_focus_); 342 DCHECK(!setting_focus_);
343 base::AutoReset<bool> focus_reset(&setting_focus_, true); 343 base::AutoReset<bool> focus_reset(&setting_focus_, true);
344 base::AutoReset<WindowMus*> window_setting_focus_to_reset( 344 base::AutoReset<WindowMus*> window_setting_focus_to_reset(
345 &window_setting_focus_to_, window); 345 &window_setting_focus_to_, window);
346 focus_client->FocusWindow(window ? window->GetWindow() : nullptr); 346 focus_client->FocusWindow(window ? window->GetWindow() : nullptr);
347 } 347 }
348 348
349 void WindowTreeClient::SetCaptureFromServer(WindowMus* window) {
350 // In order for us to get here we had to have exposed a window, which implies
351 // we got a client.
352 DCHECK(tree_);
353 if (capture_window_ == window)
354 return;
355 DCHECK(!setting_capture_);
356 base::AutoReset<bool> capture_reset(&setting_capture_, true);
357 base::AutoReset<WindowMus*> window_setting_capture_to_reset(
358 &window_setting_capture_to_, window);
359 delegate_->GetCaptureClient()->SetCapture(window ? window->GetWindow()
360 : nullptr);
361 }
362
363 InFlightChange* WindowTreeClient::GetOldestInFlightChangeMatching( 349 InFlightChange* WindowTreeClient::GetOldestInFlightChangeMatching(
364 const InFlightChange& change) { 350 const InFlightChange& change) {
365 for (const auto& pair : in_flight_map_) { 351 for (const auto& pair : in_flight_map_) {
366 if (pair.second->window() == change.window() && 352 if (pair.second->window() == change.window() &&
367 pair.second->change_type() == change.change_type() && 353 pair.second->change_type() == change.change_type() &&
368 pair.second->Matches(change)) { 354 pair.second->Matches(change)) {
369 return pair.second.get(); 355 return pair.second.get();
370 } 356 }
371 } 357 }
372 return nullptr; 358 return nullptr;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 window_mus->SetBoundsFromServer(window_data->bounds); 477 window_mus->SetBoundsFromServer(window_data->bounds);
492 if (parent) 478 if (parent)
493 parent->AddChildFromServer(window_port_mus_ptr); 479 parent->AddChildFromServer(window_port_mus_ptr);
494 if (window_data->visible) 480 if (window_data->visible)
495 window_mus->SetVisibleFromServer(true); 481 window_mus->SetVisibleFromServer(true);
496 return window_port_mus_ptr; 482 return window_port_mus_ptr;
497 } 483 }
498 484
499 void WindowTreeClient::SetWindowTree(ui::mojom::WindowTreePtr window_tree_ptr) { 485 void WindowTreeClient::SetWindowTree(ui::mojom::WindowTreePtr window_tree_ptr) {
500 tree_ptr_ = std::move(window_tree_ptr); 486 tree_ptr_ = std::move(window_tree_ptr);
501 tree_ = tree_ptr_.get(); 487 WindowTreeConnectionEstablished(tree_ptr_.get());
502
503 drag_drop_controller_ = base::MakeUnique<DragDropControllerMus>(this, tree_);
504
505 tree_ptr_->GetCursorLocationMemory( 488 tree_ptr_->GetCursorLocationMemory(
506 base::Bind(&WindowTreeClient::OnReceivedCursorLocationMemory, 489 base::Bind(&WindowTreeClient::OnReceivedCursorLocationMemory,
507 weak_factory_.GetWeakPtr())); 490 weak_factory_.GetWeakPtr()));
508 491
509 tree_ptr_.set_connection_error_handler(base::Bind( 492 tree_ptr_.set_connection_error_handler(base::Bind(
510 &WindowTreeClient::OnConnectionLost, weak_factory_.GetWeakPtr())); 493 &WindowTreeClient::OnConnectionLost, weak_factory_.GetWeakPtr()));
511 494
512 if (window_manager_delegate_) { 495 if (window_manager_delegate_) {
513 tree_ptr_->GetWindowManagerClient(GetProxy(&window_manager_internal_client_, 496 tree_ptr_->GetWindowManagerClient(GetProxy(&window_manager_internal_client_,
514 tree_ptr_.associated_group())); 497 tree_ptr_.associated_group()));
515 } 498 }
516 } 499 }
517 500
501 void WindowTreeClient::WindowTreeConnectionEstablished(
502 ui::mojom::WindowTree* window_tree) {
503 tree_ = window_tree;
504
505 drag_drop_controller_ = base::MakeUnique<DragDropControllerMus>(this, tree_);
506 capture_synchronizer_ = base::MakeUnique<CaptureSynchronizer>(
507 this, tree_, delegate_->GetCaptureClient());
508 }
509
518 void WindowTreeClient::OnConnectionLost() { 510 void WindowTreeClient::OnConnectionLost() {
519 delegate_->OnLostConnection(this); 511 delegate_->OnLostConnection(this);
520 } 512 }
521 513
522 bool WindowTreeClient::HandleInternalPropertyChanged(WindowMus* window, 514 bool WindowTreeClient::HandleInternalPropertyChanged(WindowMus* window,
523 const void* key) { 515 const void* key) {
524 if (key != client::kModalKey) 516 if (key != client::kModalKey)
525 return false; 517 return false;
526 518
527 if (window->GetWindow()->GetProperty(client::kModalKey) == 519 if (window->GetWindow()->GetProperty(client::kModalKey) ==
(...skipping 12 matching lines...) Expand all
540 } 532 }
541 533
542 void WindowTreeClient::OnEmbedImpl(ui::mojom::WindowTree* window_tree, 534 void WindowTreeClient::OnEmbedImpl(ui::mojom::WindowTree* window_tree,
543 ClientSpecificId client_id, 535 ClientSpecificId client_id,
544 ui::mojom::WindowDataPtr root_data, 536 ui::mojom::WindowDataPtr root_data,
545 int64_t display_id, 537 int64_t display_id,
546 Id focused_window_id, 538 Id focused_window_id,
547 bool drawn) { 539 bool drawn) {
548 // WARNING: this is only called if WindowTreeClient was created as the 540 // WARNING: this is only called if WindowTreeClient was created as the
549 // result of an embedding. 541 // result of an embedding.
550 tree_ = window_tree;
551 client_id_ = client_id; 542 client_id_ = client_id;
543 WindowTreeConnectionEstablished(window_tree);
552 544
553 DCHECK(roots_.empty()); 545 DCHECK(roots_.empty());
554 Window* root = CreateWindowTreeHost(RootWindowType::EMBED, root_data, 546 Window* root = CreateWindowTreeHost(RootWindowType::EMBED, root_data,
555 display_id, nullptr); 547 display_id, nullptr);
556 // TODO: needs to deal with drawn and display_id. 548 // TODO: needs to deal with drawn and display_id.
557 549
558 SetFocusFromServer(GetWindowByServerId(focused_window_id)); 550 SetFocusFromServer(GetWindowByServerId(focused_window_id));
559 551
560 delegate_->OnEmbed(root); 552 delegate_->OnEmbed(root);
561 } 553 }
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 delete window; 960 delete window;
969 } 961 }
970 962
971 void WindowTreeClient::OnCaptureChanged(Id new_capture_window_id, 963 void WindowTreeClient::OnCaptureChanged(Id new_capture_window_id,
972 Id old_capture_window_id) { 964 Id old_capture_window_id) {
973 WindowMus* new_capture_window = GetWindowByServerId(new_capture_window_id); 965 WindowMus* new_capture_window = GetWindowByServerId(new_capture_window_id);
974 WindowMus* lost_capture_window = GetWindowByServerId(old_capture_window_id); 966 WindowMus* lost_capture_window = GetWindowByServerId(old_capture_window_id);
975 if (!new_capture_window && !lost_capture_window) 967 if (!new_capture_window && !lost_capture_window)
976 return; 968 return;
977 969
978 InFlightCaptureChange change(this, new_capture_window); 970 InFlightCaptureChange change(this, capture_synchronizer_.get(),
971 new_capture_window);
979 if (ApplyServerChangeToExistingInFlightChange(change)) 972 if (ApplyServerChangeToExistingInFlightChange(change))
980 return; 973 return;
981 974
982 SetCaptureFromServer(new_capture_window); 975 capture_synchronizer_->SetCaptureFromServer(new_capture_window);
983 } 976 }
984 977
985 void WindowTreeClient::OnTopLevelCreated(uint32_t change_id, 978 void WindowTreeClient::OnTopLevelCreated(uint32_t change_id,
986 ui::mojom::WindowDataPtr data, 979 ui::mojom::WindowDataPtr data,
987 int64_t display_id, 980 int64_t display_id,
988 bool drawn) { 981 bool drawn) {
989 // The server ack'd the top level window we created and supplied the state 982 // The server ack'd the top level window we created and supplied the state
990 // of the window at the time the server created it. For properties we do not 983 // of the window at the time the server created it. For properties we do not
991 // have changes in flight for we can update them immediately. For properties 984 // have changes in flight for we can update them immediately. For properties
992 // with changes in flight we set the revert value from the server. 985 // with changes in flight we set the revert value from the server.
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 if (window && relative_window && parent && 1128 if (window && relative_window && parent &&
1136 parent == WindowMus::Get(relative_window->GetWindow()->parent())) { 1129 parent == WindowMus::Get(relative_window->GetWindow()->parent())) {
1137 parent->ReorderFromServer(window, relative_window, direction); 1130 parent->ReorderFromServer(window, relative_window, direction);
1138 } 1131 }
1139 } 1132 }
1140 1133
1141 void WindowTreeClient::OnWindowDeleted(Id window_id) { 1134 void WindowTreeClient::OnWindowDeleted(Id window_id) {
1142 delete GetWindowByServerId(window_id)->GetWindow(); 1135 delete GetWindowByServerId(window_id)->GetWindow();
1143 } 1136 }
1144 1137
1145 Window* WindowTreeClient::GetCaptureWindow() {
1146 return capture_window_ ? capture_window_->GetWindow() : nullptr;
1147 }
1148
1149 void WindowTreeClient::OnWindowVisibilityChanged(Id window_id, bool visible) { 1138 void WindowTreeClient::OnWindowVisibilityChanged(Id window_id, bool visible) {
1150 WindowMus* window = GetWindowByServerId(window_id); 1139 WindowMus* window = GetWindowByServerId(window_id);
1151 if (!window) 1140 if (!window)
1152 return; 1141 return;
1153 1142
1154 InFlightVisibleChange new_change(this, window, visible); 1143 InFlightVisibleChange new_change(this, window, visible);
1155 if (ApplyServerChangeToExistingInFlightChange(new_change)) 1144 if (ApplyServerChangeToExistingInFlightChange(new_change))
1156 return; 1145 return;
1157 1146
1158 SetWindowVisibleFromServer(window, visible); 1147 SetWindowVisibleFromServer(window, visible);
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1611 return; 1600 return;
1612 } 1601 }
1613 1602
1614 const uint32_t change_id = ScheduleInFlightChange( 1603 const uint32_t change_id = ScheduleInFlightChange(
1615 base::MakeUnique<InFlightFocusChange>(this, focused_window_)); 1604 base::MakeUnique<InFlightFocusChange>(this, focused_window_));
1616 focused_window_ = gained_focus_mus; 1605 focused_window_ = gained_focus_mus;
1617 tree_->SetFocus(change_id, focused_window_ ? focused_window_->server_id() 1606 tree_->SetFocus(change_id, focused_window_ ? focused_window_->server_id()
1618 : kInvalidServerId); 1607 : kInvalidServerId);
1619 } 1608 }
1620 1609
1621 void WindowTreeClient::OnCaptureChanged(Window* lost_capture,
1622 Window* gained_capture) {
1623 WindowMus* gained_capture_mus = WindowMus::Get(gained_capture);
1624 if (setting_capture_ && gained_capture_mus == window_setting_capture_to_) {
1625 capture_window_ = gained_capture_mus;
1626 return;
1627 }
1628
1629 const uint32_t change_id = ScheduleInFlightChange(
1630 base::MakeUnique<InFlightCaptureChange>(this, capture_window_));
1631 WindowMus* old_capture_window = capture_window_;
1632 capture_window_ = gained_capture_mus;
1633 if (capture_window_)
1634 tree_->SetCapture(change_id, capture_window_->server_id());
1635 else
1636 tree_->ReleaseCapture(change_id, old_capture_window->server_id());
1637 }
1638
1639 void WindowTreeClient::SetRootWindowBounds(Window* window, gfx::Rect* bounds) { 1610 void WindowTreeClient::SetRootWindowBounds(Window* window, gfx::Rect* bounds) {
1640 WindowTreeHostMus* window_tree_host = GetWindowTreeHostMus(window); 1611 WindowTreeHostMus* window_tree_host = GetWindowTreeHostMus(window);
1641 switch (window_tree_host->root_window_type()) { 1612 switch (window_tree_host->root_window_type()) {
1642 case RootWindowType::EMBED: 1613 case RootWindowType::EMBED:
1643 NOTREACHED(); 1614 NOTREACHED();
1644 return; 1615 return;
1645 case RootWindowType::TOP_LEVEL: 1616 case RootWindowType::TOP_LEVEL:
1646 // Top level requests are always in display coordinates. 1617 // Top level requests are always in display coordinates.
1647 break; 1618 break;
1648 case RootWindowType::DISPLAY: { 1619 case RootWindowType::DISPLAY: {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 ScheduleInFlightChange(base::MakeUnique<CrashInFlightChange>( 1658 ScheduleInFlightChange(base::MakeUnique<CrashInFlightChange>(
1688 child_mus, ChangeType::REMOVE_TRANSIENT_WINDOW_FROM_PARENT)); 1659 child_mus, ChangeType::REMOVE_TRANSIENT_WINDOW_FROM_PARENT));
1689 tree_->RemoveTransientWindowFromParent(change_id, child_mus->server_id()); 1660 tree_->RemoveTransientWindowFromParent(change_id, child_mus->server_id());
1690 } 1661 }
1691 1662
1692 uint32_t WindowTreeClient::CreateChangeIdForDrag(WindowMus* window) { 1663 uint32_t WindowTreeClient::CreateChangeIdForDrag(WindowMus* window) {
1693 return ScheduleInFlightChange( 1664 return ScheduleInFlightChange(
1694 base::MakeUnique<InFlightDragChange>(window, ChangeType::DRAG_LOOP)); 1665 base::MakeUnique<InFlightDragChange>(window, ChangeType::DRAG_LOOP));
1695 } 1666 }
1696 1667
1668 uint32_t WindowTreeClient::CreateChangeIdForCapture(WindowMus* window) {
1669 return ScheduleInFlightChange(base::MakeUnique<InFlightCaptureChange>(
1670 this, capture_synchronizer_.get(), window));
1671 }
1672
1697 } // namespace aura 1673 } // namespace aura
OLDNEW
« no previous file with comments | « ui/aura/mus/window_tree_client.h ('k') | ui/aura/mus/window_tree_client_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698