| OLD | NEW |
| 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 "components/mus/ws/window_tree.h" | 5 #include "components/mus/ws/window_tree.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 DISALLOW_COPY_AND_ASSIGN(TargetedEvent); | 65 DISALLOW_COPY_AND_ASSIGN(TargetedEvent); |
| 66 }; | 66 }; |
| 67 | 67 |
| 68 WindowTree::WindowTree(ConnectionManager* connection_manager, | 68 WindowTree::WindowTree(ConnectionManager* connection_manager, |
| 69 ServerWindow* root, | 69 ServerWindow* root, |
| 70 uint32_t policy_bitmask) | 70 uint32_t policy_bitmask) |
| 71 : connection_manager_(connection_manager), | 71 : connection_manager_(connection_manager), |
| 72 id_(connection_manager_->GetAndAdvanceNextConnectionId()), | 72 id_(connection_manager_->GetAndAdvanceNextConnectionId()), |
| 73 next_window_id_(1), | 73 next_window_id_(1), |
| 74 event_ack_id_(0), | 74 event_ack_id_(0), |
| 75 event_source_display_(nullptr), | |
| 76 is_embed_root_(false), | 75 is_embed_root_(false), |
| 77 window_manager_internal_(nullptr) { | 76 window_manager_internal_(nullptr) { |
| 78 if (root) | 77 if (root) |
| 79 roots_.insert(root); | 78 roots_.insert(root); |
| 80 // TODO(sky): pass in type rather than inferring it. | 79 // TODO(sky): pass in type rather than inferring it. |
| 81 if (root && root->id().connection_id == kInvalidConnectionId) { | 80 if (root && root->id().connection_id == kInvalidConnectionId) { |
| 82 access_policy_.reset(new WindowManagerAccessPolicy(id_, this)); | 81 access_policy_.reset(new WindowManagerAccessPolicy(id_, this)); |
| 83 is_embed_root_ = true; | 82 is_embed_root_ = true; |
| 84 } else { | 83 } else { |
| 85 access_policy_.reset(new DefaultAccessPolicy(id_, this)); | 84 access_policy_.reset(new DefaultAccessPolicy(id_, this)); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 const ClientWindowId& id) const { | 150 const ClientWindowId& id) const { |
| 152 auto iter = client_id_to_window_id_map_.find(id); | 151 auto iter = client_id_to_window_id_map_.find(id); |
| 153 return iter == client_id_to_window_id_map_.end() ? nullptr | 152 return iter == client_id_to_window_id_map_.end() ? nullptr |
| 154 : GetWindow(iter->second); | 153 : GetWindow(iter->second); |
| 155 } | 154 } |
| 156 | 155 |
| 157 const Display* WindowTree::GetDisplay(const ServerWindow* window) const { | 156 const Display* WindowTree::GetDisplay(const ServerWindow* window) const { |
| 158 return window ? display_manager()->GetDisplayContaining(window) : nullptr; | 157 return window ? display_manager()->GetDisplayContaining(window) : nullptr; |
| 159 } | 158 } |
| 160 | 159 |
| 160 const WindowManagerState* WindowTree::GetWindowManagerState( |
| 161 const ServerWindow* window) const { |
| 162 return window |
| 163 ? display_manager() |
| 164 ->GetWindowManagerAndDisplay(window) |
| 165 .window_manager_state |
| 166 : nullptr; |
| 167 } |
| 168 |
| 161 void WindowTree::OnWindowDestroyingTreeImpl(WindowTree* tree) { | 169 void WindowTree::OnWindowDestroyingTreeImpl(WindowTree* tree) { |
| 170 if (event_source_wms_ && event_source_wms_->tree() == tree) |
| 171 event_source_wms_ = nullptr; |
| 172 |
| 162 // Notify our client if |tree| was embedded in any of our views. | 173 // Notify our client if |tree| was embedded in any of our views. |
| 163 for (const auto* tree_root : tree->roots_) { | 174 for (const auto* tree_root : tree->roots_) { |
| 164 const bool owns_tree_root = tree_root->id().connection_id == id_; | 175 const bool owns_tree_root = tree_root->id().connection_id == id_; |
| 165 if (owns_tree_root || (is_embed_root_ && IsWindowKnown(tree_root))) { | 176 if (owns_tree_root || (is_embed_root_ && IsWindowKnown(tree_root))) { |
| 166 client()->OnEmbeddedAppDisconnected( | 177 client()->OnEmbeddedAppDisconnected( |
| 167 ClientWindowIdForWindow(tree_root).id); | 178 ClientWindowIdForWindow(tree_root).id); |
| 168 } | 179 } |
| 169 } | 180 } |
| 170 } | 181 } |
| 171 | 182 |
| 172 void WindowTree::OnWillDestroyDisplay(Display* display) { | |
| 173 if (event_source_display_ == display) | |
| 174 event_source_display_ = nullptr; | |
| 175 } | |
| 176 | |
| 177 void WindowTree::NotifyChangeCompleted( | 183 void WindowTree::NotifyChangeCompleted( |
| 178 uint32_t change_id, | 184 uint32_t change_id, |
| 179 mojom::WindowManagerErrorCode error_code) { | 185 mojom::WindowManagerErrorCode error_code) { |
| 180 client()->OnChangeCompleted( | 186 client()->OnChangeCompleted( |
| 181 change_id, error_code == mojom::WindowManagerErrorCode::SUCCESS); | 187 change_id, error_code == mojom::WindowManagerErrorCode::SUCCESS); |
| 182 } | 188 } |
| 183 | 189 |
| 190 bool WindowTree::SetCapture(const ClientWindowId& client_window_id) { |
| 191 ServerWindow* window = GetWindowByClientId(client_window_id); |
| 192 WindowManagerState* wms = GetWindowManagerState(window); |
| 193 ServerWindow* current_capture_window = wms ? wms->capture_window() : nullptr; |
| 194 if (window && wms && wms->IsActive() && |
| 195 access_policy_->CanSetCapture(window) && |
| 196 (!current_capture_window || |
| 197 access_policy_->CanSetCapture(current_capture_window)) && |
| 198 event_ack_id_) { |
| 199 wms->SetCapture(window, !HasRoot(window)); |
| 200 return true; |
| 201 } |
| 202 return false; |
| 203 } |
| 204 |
| 184 bool WindowTree::NewWindow( | 205 bool WindowTree::NewWindow( |
| 185 const ClientWindowId& client_window_id, | 206 const ClientWindowId& client_window_id, |
| 186 const std::map<std::string, std::vector<uint8_t>>& properties) { | 207 const std::map<std::string, std::vector<uint8_t>>& properties) { |
| 187 if (!IsValidIdForNewWindow(client_window_id)) | 208 if (!IsValidIdForNewWindow(client_window_id)) |
| 188 return false; | 209 return false; |
| 189 const WindowId window_id = GenerateNewWindowId(); | 210 const WindowId window_id = GenerateNewWindowId(); |
| 190 DCHECK(!GetWindow(window_id)); | 211 DCHECK(!GetWindow(window_id)); |
| 191 ServerWindow* window = | 212 ServerWindow* window = |
| 192 connection_manager_->CreateServerWindow(window_id, properties); | 213 connection_manager_->CreateServerWindow(window_id, properties); |
| 193 created_window_map_[window_id] = window; | 214 created_window_map_[window_id] = window; |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 870 } | 891 } |
| 871 | 892 |
| 872 void WindowTree::DispatchInputEventImpl(ServerWindow* target, | 893 void WindowTree::DispatchInputEventImpl(ServerWindow* target, |
| 873 mojom::EventPtr event) { | 894 mojom::EventPtr event) { |
| 874 DCHECK(!event_ack_id_); | 895 DCHECK(!event_ack_id_); |
| 875 // We do not want to create a sequential id for each event, because that can | 896 // We do not want to create a sequential id for each event, because that can |
| 876 // leak some information to the client. So instead, manufacture the id from | 897 // leak some information to the client. So instead, manufacture the id from |
| 877 // the event pointer. | 898 // the event pointer. |
| 878 event_ack_id_ = | 899 event_ack_id_ = |
| 879 0x1000000 | (reinterpret_cast<uintptr_t>(event.get()) & 0xffffff); | 900 0x1000000 | (reinterpret_cast<uintptr_t>(event.get()) & 0xffffff); |
| 880 event_source_display_ = GetDisplay(target); | 901 event_source_wms_ = GetWindowManagerState(target); |
| 881 // Should only get events from windows attached to a host. | 902 // Should only get events from windows attached to a host. |
| 882 DCHECK(event_source_display_); | 903 DCHECK(event_source_wms_); |
| 883 client()->OnWindowInputEvent( | 904 client()->OnWindowInputEvent( |
| 884 event_ack_id_, ClientWindowIdForWindow(target).id, std::move(event)); | 905 event_ack_id_, ClientWindowIdForWindow(target).id, std::move(event)); |
| 885 } | 906 } |
| 886 | 907 |
| 887 void WindowTree::NewWindow( | 908 void WindowTree::NewWindow( |
| 888 uint32_t change_id, | 909 uint32_t change_id, |
| 889 Id transport_window_id, | 910 Id transport_window_id, |
| 890 mojo::Map<mojo::String, mojo::Array<uint8_t>> transport_properties) { | 911 mojo::Map<mojo::String, mojo::Array<uint8_t>> transport_properties) { |
| 891 std::map<std::string, std::vector<uint8_t>> properties; | 912 std::map<std::string, std::vector<uint8_t>> properties; |
| 892 if (!transport_properties.is_null()) { | 913 if (!transport_properties.is_null()) { |
| 893 properties = | 914 properties = |
| 894 transport_properties.To<std::map<std::string, std::vector<uint8_t>>>(); | 915 transport_properties.To<std::map<std::string, std::vector<uint8_t>>>(); |
| 895 } | 916 } |
| 896 client()->OnChangeCompleted( | 917 client()->OnChangeCompleted( |
| 897 change_id, NewWindow(ClientWindowId(transport_window_id), properties)); | 918 change_id, NewWindow(ClientWindowId(transport_window_id), properties)); |
| 898 } | 919 } |
| 899 | 920 |
| 900 void WindowTree::NewTopLevelWindow( | 921 void WindowTree::NewTopLevelWindow( |
| 901 uint32_t change_id, | 922 uint32_t change_id, |
| 902 Id transport_window_id, | 923 Id transport_window_id, |
| 903 mojo::Map<mojo::String, mojo::Array<uint8_t>> transport_properties) { | 924 mojo::Map<mojo::String, mojo::Array<uint8_t>> transport_properties) { |
| 904 DCHECK(!waiting_for_top_level_window_info_); | 925 DCHECK(!waiting_for_top_level_window_info_); |
| 905 const ClientWindowId client_window_id(transport_window_id); | 926 const ClientWindowId client_window_id(transport_window_id); |
| 906 Display* display = display_manager()->GetActiveDisplay(); | 927 // TODO(sky): need a way for client to provide context to figure out display. |
| 907 // TODO(sky): need a way for client to provide context. | 928 // TODO(sky): get WMS for user_id for this connection. |
| 929 Display* display = display_manager()->displays().empty() |
| 930 ? nullptr |
| 931 : *(display_manager()->displays().begin()); |
| 908 WindowManagerState* wms = | 932 WindowManagerState* wms = |
| 909 display ? display->GetFirstWindowManagerState() : nullptr; | 933 display ? display->GetFirstWindowManagerState() : nullptr; |
| 910 if (!wms || wms->tree() == this || !IsValidIdForNewWindow(client_window_id)) { | 934 if (!wms || wms->tree() == this || !IsValidIdForNewWindow(client_window_id)) { |
| 911 client()->OnChangeCompleted(change_id, false); | 935 client()->OnChangeCompleted(change_id, false); |
| 912 return; | 936 return; |
| 913 } | 937 } |
| 914 | 938 |
| 915 // The server creates the real window. Any further messages from the client | 939 // The server creates the real window. Any further messages from the client |
| 916 // may try to alter the window. Pause incoming messages so that we know we | 940 // may try to alter the window. Pause incoming messages so that we know we |
| 917 // can't get a message for a window before the window is created. Once the | 941 // can't get a message for a window before the window is created. Once the |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1004 | 1028 |
| 1005 void WindowTree::GetWindowTree( | 1029 void WindowTree::GetWindowTree( |
| 1006 Id window_id, | 1030 Id window_id, |
| 1007 const Callback<void(Array<mojom::WindowDataPtr>)>& callback) { | 1031 const Callback<void(Array<mojom::WindowDataPtr>)>& callback) { |
| 1008 std::vector<const ServerWindow*> windows( | 1032 std::vector<const ServerWindow*> windows( |
| 1009 GetWindowTree(ClientWindowId(window_id))); | 1033 GetWindowTree(ClientWindowId(window_id))); |
| 1010 callback.Run(WindowsToWindowDatas(windows)); | 1034 callback.Run(WindowsToWindowDatas(windows)); |
| 1011 } | 1035 } |
| 1012 | 1036 |
| 1013 void WindowTree::SetCapture(uint32_t change_id, Id window_id) { | 1037 void WindowTree::SetCapture(uint32_t change_id, Id window_id) { |
| 1014 ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id)); | 1038 client()->OnChangeCompleted(change_id, SetCapture(ClientWindowId(window_id))); |
| 1015 Display* display = GetDisplay(window); | |
| 1016 ServerWindow* current_capture_window = | |
| 1017 display ? display->GetCaptureWindow() : nullptr; | |
| 1018 bool success = window && access_policy_->CanSetCapture(window) && display && | |
| 1019 (!current_capture_window || | |
| 1020 access_policy_->CanSetCapture(current_capture_window)) && | |
| 1021 event_ack_id_; | |
| 1022 if (success) { | |
| 1023 Operation op(this, connection_manager_, OperationType::SET_CAPTURE); | |
| 1024 display->SetCapture(window, !HasRoot(window)); | |
| 1025 } | |
| 1026 client()->OnChangeCompleted(change_id, success); | |
| 1027 } | 1039 } |
| 1028 | 1040 |
| 1029 void WindowTree::ReleaseCapture(uint32_t change_id, Id window_id) { | 1041 void WindowTree::ReleaseCapture(uint32_t change_id, Id window_id) { |
| 1030 ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id)); | 1042 ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id)); |
| 1031 Display* display = GetDisplay(window); | 1043 WindowManagerState* wms = GetWindowManagerState(window); |
| 1032 ServerWindow* current_capture_window = | 1044 ServerWindow* current_capture_window = wms ? wms->capture_window() : nullptr; |
| 1033 display ? display->GetCaptureWindow() : nullptr; | 1045 bool success = window && wms && wms->IsActive() && |
| 1034 bool success = window && display && | |
| 1035 (!current_capture_window || | 1046 (!current_capture_window || |
| 1036 access_policy_->CanSetCapture(current_capture_window)) && | 1047 access_policy_->CanSetCapture(current_capture_window)) && |
| 1037 window == current_capture_window; | 1048 window == current_capture_window; |
| 1038 if (success) { | 1049 if (success) { |
| 1039 Operation op(this, connection_manager_, OperationType::RELEASE_CAPTURE); | 1050 Operation op(this, connection_manager_, OperationType::RELEASE_CAPTURE); |
| 1040 display->SetCapture(nullptr, false); | 1051 wms->SetCapture(nullptr, false); |
| 1041 } | 1052 } |
| 1042 client()->OnChangeCompleted(change_id, success); | 1053 client()->OnChangeCompleted(change_id, success); |
| 1043 } | 1054 } |
| 1044 | 1055 |
| 1045 void WindowTree::SetWindowBounds(uint32_t change_id, | 1056 void WindowTree::SetWindowBounds(uint32_t change_id, |
| 1046 Id window_id, | 1057 Id window_id, |
| 1047 mojo::RectPtr bounds) { | 1058 mojo::RectPtr bounds) { |
| 1048 ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id)); | 1059 ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id)); |
| 1049 if (window && ShouldRouteToWindowManager(window)) { | 1060 if (window && ShouldRouteToWindowManager(window)) { |
| 1050 const uint32_t wm_change_id = | 1061 const uint32_t wm_change_id = |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1145 } | 1156 } |
| 1146 } | 1157 } |
| 1147 | 1158 |
| 1148 void WindowTree::OnWindowInputEventAck(uint32_t event_id) { | 1159 void WindowTree::OnWindowInputEventAck(uint32_t event_id) { |
| 1149 if (event_ack_id_ == 0 || event_id != event_ack_id_) { | 1160 if (event_ack_id_ == 0 || event_id != event_ack_id_) { |
| 1150 // TODO(sad): Something bad happened. Kill the client? | 1161 // TODO(sad): Something bad happened. Kill the client? |
| 1151 NOTIMPLEMENTED() << "Wrong event acked."; | 1162 NOTIMPLEMENTED() << "Wrong event acked."; |
| 1152 } | 1163 } |
| 1153 event_ack_id_ = 0; | 1164 event_ack_id_ = 0; |
| 1154 | 1165 |
| 1155 Display* event_source_display = event_source_display_; | 1166 WindowManagerState* event_source_wms = event_source_wms_; |
| 1156 event_source_display_ = nullptr; | 1167 event_source_wms_ = nullptr; |
| 1157 if (event_source_display) | 1168 if (event_source_wms) |
| 1158 event_source_display->OnEventAck(this); | 1169 event_source_wms->OnEventAck(this); |
| 1159 | 1170 |
| 1160 if (!event_queue_.empty()) { | 1171 if (!event_queue_.empty()) { |
| 1161 DCHECK(!event_ack_id_); | 1172 DCHECK(!event_ack_id_); |
| 1162 ServerWindow* target = nullptr; | 1173 ServerWindow* target = nullptr; |
| 1163 mojom::EventPtr event; | 1174 mojom::EventPtr event; |
| 1164 do { | 1175 do { |
| 1165 scoped_ptr<TargetedEvent> targeted_event = | 1176 scoped_ptr<TargetedEvent> targeted_event = |
| 1166 std::move(event_queue_.front()); | 1177 std::move(event_queue_.front()); |
| 1167 event_queue_.pop(); | 1178 event_queue_.pop(); |
| 1168 target = targeted_event->target(); | 1179 target = targeted_event->target(); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1246 return; | 1257 return; |
| 1247 } | 1258 } |
| 1248 window_manager_internal_client_binding_.reset( | 1259 window_manager_internal_client_binding_.reset( |
| 1249 new mojo::AssociatedBinding<mojom::WindowManagerClient>( | 1260 new mojo::AssociatedBinding<mojom::WindowManagerClient>( |
| 1250 this, std::move(internal))); | 1261 this, std::move(internal))); |
| 1251 } | 1262 } |
| 1252 | 1263 |
| 1253 void WindowTree::AddAccelerator(uint32_t id, | 1264 void WindowTree::AddAccelerator(uint32_t id, |
| 1254 mojom::EventMatcherPtr event_matcher, | 1265 mojom::EventMatcherPtr event_matcher, |
| 1255 const AddAcceleratorCallback& callback) { | 1266 const AddAcceleratorCallback& callback) { |
| 1256 Display* host = GetDisplayForWindowManager(); | 1267 WindowManagerState* wms = GetWindowManagerStateForWindowManager(); |
| 1257 const bool success = | 1268 const bool success = |
| 1258 host && | 1269 wms->event_dispatcher()->AddAccelerator(id, std::move(event_matcher)); |
| 1259 host->event_dispatcher()->AddAccelerator(id, std::move(event_matcher)); | |
| 1260 callback.Run(success); | 1270 callback.Run(success); |
| 1261 } | 1271 } |
| 1262 | 1272 |
| 1263 void WindowTree::RemoveAccelerator(uint32_t id) { | 1273 void WindowTree::RemoveAccelerator(uint32_t id) { |
| 1264 Display* host = GetDisplayForWindowManager(); | 1274 WindowManagerState* wms = GetWindowManagerStateForWindowManager(); |
| 1265 if (!host) | 1275 wms->event_dispatcher()->RemoveAccelerator(id); |
| 1266 return; | |
| 1267 host->event_dispatcher()->RemoveAccelerator(id); | |
| 1268 } | 1276 } |
| 1269 | 1277 |
| 1270 void WindowTree::AddActivationParent(Id transport_window_id) { | 1278 void WindowTree::AddActivationParent(Id transport_window_id) { |
| 1271 Display* host = GetDisplayForWindowManager(); | 1279 Display* host = GetDisplayForWindowManager(); |
| 1272 if (!host) | 1280 if (!host) |
| 1273 return; | 1281 return; |
| 1274 ServerWindow* window = | 1282 ServerWindow* window = |
| 1275 GetWindowByClientId(ClientWindowId(transport_window_id)); | 1283 GetWindowByClientId(ClientWindowId(transport_window_id)); |
| 1276 if (window) | 1284 if (window) |
| 1277 host->AddActivationParent(window); | 1285 host->AddActivationParent(window); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1371 | 1379 |
| 1372 for (const auto* root : roots_) { | 1380 for (const auto* root : roots_) { |
| 1373 if (root->Contains(window)) | 1381 if (root->Contains(window)) |
| 1374 return true; | 1382 return true; |
| 1375 } | 1383 } |
| 1376 return false; | 1384 return false; |
| 1377 } | 1385 } |
| 1378 | 1386 |
| 1379 } // namespace ws | 1387 } // namespace ws |
| 1380 } // namespace mus | 1388 } // namespace mus |
| OLD | NEW |