| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 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/ws/test_utils.h" | |
| 6 | |
| 7 #include "base/memory/ptr_util.h" | |
| 8 #include "cc/output/copy_output_request.h" | |
| 9 #include "components/mus/surfaces/surfaces_state.h" | |
| 10 #include "components/mus/ws/display_binding.h" | |
| 11 #include "components/mus/ws/display_manager.h" | |
| 12 #include "components/mus/ws/server_window_surface_manager_test_api.h" | |
| 13 #include "components/mus/ws/window_manager_access_policy.h" | |
| 14 #include "components/mus/ws/window_manager_window_tree_factory.h" | |
| 15 #include "services/shell/public/interfaces/connector.mojom.h" | |
| 16 #include "testing/gtest/include/gtest/gtest.h" | |
| 17 | |
| 18 namespace mus { | |
| 19 namespace ws { | |
| 20 namespace test { | |
| 21 namespace { | |
| 22 | |
| 23 // ----------------------------------------------------------------------------- | |
| 24 // Empty implementation of PlatformDisplay. | |
| 25 class TestPlatformDisplay : public PlatformDisplay { | |
| 26 public: | |
| 27 explicit TestPlatformDisplay(int32_t* cursor_id_storage) | |
| 28 : cursor_id_storage_(cursor_id_storage) { | |
| 29 display_metrics_.size_in_pixels = gfx::Size(400, 300); | |
| 30 display_metrics_.device_scale_factor = 1.f; | |
| 31 } | |
| 32 ~TestPlatformDisplay() override {} | |
| 33 | |
| 34 // PlatformDisplay: | |
| 35 void Init(PlatformDisplayDelegate* delegate) override { | |
| 36 // It is necessary to tell the delegate about the ViewportMetrics to make | |
| 37 // sure that the DisplayBinding is correctly initialized (and a root-window | |
| 38 // is created). | |
| 39 delegate->OnViewportMetricsChanged(ViewportMetrics(), display_metrics_); | |
| 40 } | |
| 41 void SchedulePaint(const ServerWindow* window, | |
| 42 const gfx::Rect& bounds) override {} | |
| 43 void SetViewportSize(const gfx::Size& size) override {} | |
| 44 void SetTitle(const base::string16& title) override {} | |
| 45 void SetCapture() override {} | |
| 46 void ReleaseCapture() override {} | |
| 47 void SetCursorById(int32_t cursor) override { *cursor_id_storage_ = cursor; } | |
| 48 mojom::Rotation GetRotation() override { return mojom::Rotation::VALUE_0; } | |
| 49 float GetDeviceScaleFactor() override { | |
| 50 return display_metrics_.device_scale_factor; | |
| 51 } | |
| 52 void UpdateTextInputState(const ui::TextInputState& state) override {} | |
| 53 void SetImeVisibility(bool visible) override {} | |
| 54 bool IsFramePending() const override { return false; } | |
| 55 void RequestCopyOfOutput( | |
| 56 std::unique_ptr<cc::CopyOutputRequest> output_request) override {} | |
| 57 int64_t GetDisplayId() const override { return 1; } | |
| 58 | |
| 59 private: | |
| 60 ViewportMetrics display_metrics_; | |
| 61 | |
| 62 int32_t* cursor_id_storage_; | |
| 63 | |
| 64 DISALLOW_COPY_AND_ASSIGN(TestPlatformDisplay); | |
| 65 }; | |
| 66 | |
| 67 ClientWindowId NextUnusedClientWindowId(WindowTree* tree) { | |
| 68 ClientWindowId client_id; | |
| 69 for (ClientSpecificId id = 1;; ++id) { | |
| 70 // Used the id of the client in the upper bits to simplify things. | |
| 71 const ClientWindowId client_id = | |
| 72 ClientWindowId(WindowIdToTransportId(WindowId(tree->id(), id))); | |
| 73 if (!tree->GetWindowByClientId(client_id)) | |
| 74 return client_id; | |
| 75 } | |
| 76 } | |
| 77 | |
| 78 } // namespace | |
| 79 | |
| 80 // WindowManagerWindowTreeFactorySetTestApi ------------------------------------ | |
| 81 | |
| 82 WindowManagerWindowTreeFactorySetTestApi:: | |
| 83 WindowManagerWindowTreeFactorySetTestApi( | |
| 84 WindowManagerWindowTreeFactorySet* | |
| 85 window_manager_window_tree_factory_set) | |
| 86 : window_manager_window_tree_factory_set_( | |
| 87 window_manager_window_tree_factory_set) {} | |
| 88 | |
| 89 WindowManagerWindowTreeFactorySetTestApi:: | |
| 90 ~WindowManagerWindowTreeFactorySetTestApi() {} | |
| 91 | |
| 92 void WindowManagerWindowTreeFactorySetTestApi::Add(const UserId& user_id) { | |
| 93 WindowManagerWindowTreeFactory* factory = | |
| 94 window_manager_window_tree_factory_set_->Add(user_id, nullptr); | |
| 95 factory->CreateWindowTree(nullptr, nullptr); | |
| 96 } | |
| 97 | |
| 98 // TestPlatformDisplayFactory ------------------------------------------------- | |
| 99 | |
| 100 TestPlatformDisplayFactory::TestPlatformDisplayFactory( | |
| 101 int32_t* cursor_id_storage) | |
| 102 : cursor_id_storage_(cursor_id_storage) {} | |
| 103 | |
| 104 TestPlatformDisplayFactory::~TestPlatformDisplayFactory() {} | |
| 105 | |
| 106 PlatformDisplay* TestPlatformDisplayFactory::CreatePlatformDisplay() { | |
| 107 return new TestPlatformDisplay(cursor_id_storage_); | |
| 108 } | |
| 109 | |
| 110 // WindowTreeTestApi --------------------------------------------------------- | |
| 111 | |
| 112 WindowTreeTestApi::WindowTreeTestApi(WindowTree* tree) : tree_(tree) {} | |
| 113 WindowTreeTestApi::~WindowTreeTestApi() {} | |
| 114 | |
| 115 void WindowTreeTestApi::SetEventObserver(mojom::EventMatcherPtr matcher, | |
| 116 uint32_t event_observer_id) { | |
| 117 tree_->SetEventObserver(std::move(matcher), event_observer_id); | |
| 118 } | |
| 119 | |
| 120 // DisplayTestApi ------------------------------------------------------------ | |
| 121 | |
| 122 DisplayTestApi::DisplayTestApi(Display* display) : display_(display) {} | |
| 123 DisplayTestApi::~DisplayTestApi() {} | |
| 124 | |
| 125 // EventDispatcherTestApi ---------------------------------------------------- | |
| 126 | |
| 127 bool EventDispatcherTestApi::IsWindowPointerTarget( | |
| 128 const ServerWindow* window) const { | |
| 129 for (const auto& pair : ed_->pointer_targets_) { | |
| 130 if (pair.second.window == window) | |
| 131 return true; | |
| 132 } | |
| 133 return false; | |
| 134 } | |
| 135 | |
| 136 int EventDispatcherTestApi::NumberPointerTargetsForWindow( | |
| 137 ServerWindow* window) { | |
| 138 int count = 0; | |
| 139 for (const auto& pair : ed_->pointer_targets_) | |
| 140 if (pair.second.window == window) | |
| 141 count++; | |
| 142 return count; | |
| 143 } | |
| 144 | |
| 145 // TestDisplayBinding --------------------------------------------------------- | |
| 146 | |
| 147 WindowTree* TestDisplayBinding::CreateWindowTree(ServerWindow* root) { | |
| 148 const uint32_t embed_flags = 0; | |
| 149 WindowTree* tree = window_server_->EmbedAtWindow( | |
| 150 root, shell::mojom::kRootUserID, mus::mojom::WindowTreeClientPtr(), | |
| 151 embed_flags, base::WrapUnique(new WindowManagerAccessPolicy)); | |
| 152 tree->ConfigureWindowManager(); | |
| 153 return tree; | |
| 154 } | |
| 155 | |
| 156 // TestWindowManager ---------------------------------------------------------- | |
| 157 | |
| 158 void TestWindowManager::WmCreateTopLevelWindow( | |
| 159 uint32_t change_id, | |
| 160 ClientSpecificId requesting_client_id, | |
| 161 mojo::Map<mojo::String, mojo::Array<uint8_t>> properties) { | |
| 162 got_create_top_level_window_ = true; | |
| 163 change_id_ = change_id; | |
| 164 } | |
| 165 | |
| 166 void TestWindowManager::WmClientJankinessChanged(ClientSpecificId client_id, | |
| 167 bool janky) {} | |
| 168 | |
| 169 void TestWindowManager::OnAccelerator(uint32_t id, | |
| 170 std::unique_ptr<ui::Event> event) { | |
| 171 on_accelerator_called_ = true; | |
| 172 on_accelerator_id_ = id; | |
| 173 } | |
| 174 | |
| 175 // TestWindowTreeClient ------------------------------------------------------- | |
| 176 | |
| 177 TestWindowTreeClient::TestWindowTreeClient() | |
| 178 : binding_(this), record_on_change_completed_(false) {} | |
| 179 TestWindowTreeClient::~TestWindowTreeClient() {} | |
| 180 | |
| 181 void TestWindowTreeClient::Bind( | |
| 182 mojo::InterfaceRequest<mojom::WindowTreeClient> request) { | |
| 183 binding_.Bind(std::move(request)); | |
| 184 } | |
| 185 | |
| 186 void TestWindowTreeClient::OnEmbed(uint16_t client_id, | |
| 187 mojom::WindowDataPtr root, | |
| 188 mus::mojom::WindowTreePtr tree, | |
| 189 int64_t display_id, | |
| 190 Id focused_window_id, | |
| 191 bool drawn) { | |
| 192 // TODO(sky): add test coverage of |focused_window_id|. | |
| 193 tracker_.OnEmbed(client_id, std::move(root), drawn); | |
| 194 } | |
| 195 | |
| 196 void TestWindowTreeClient::OnEmbeddedAppDisconnected(uint32_t window) { | |
| 197 tracker_.OnEmbeddedAppDisconnected(window); | |
| 198 } | |
| 199 | |
| 200 void TestWindowTreeClient::OnUnembed(Id window_id) { | |
| 201 tracker_.OnUnembed(window_id); | |
| 202 } | |
| 203 | |
| 204 void TestWindowTreeClient::OnLostCapture(Id window_id) {} | |
| 205 | |
| 206 void TestWindowTreeClient::OnTopLevelCreated(uint32_t change_id, | |
| 207 mojom::WindowDataPtr data, | |
| 208 int64_t display_id, | |
| 209 bool drawn) { | |
| 210 tracker_.OnTopLevelCreated(change_id, std::move(data), drawn); | |
| 211 } | |
| 212 | |
| 213 void TestWindowTreeClient::OnWindowBoundsChanged(uint32_t window, | |
| 214 const gfx::Rect& old_bounds, | |
| 215 const gfx::Rect& new_bounds) { | |
| 216 tracker_.OnWindowBoundsChanged(window, std::move(old_bounds), | |
| 217 std::move(new_bounds)); | |
| 218 } | |
| 219 | |
| 220 void TestWindowTreeClient::OnClientAreaChanged( | |
| 221 uint32_t window_id, | |
| 222 const gfx::Insets& new_client_area, | |
| 223 mojo::Array<gfx::Rect> new_additional_client_areas) {} | |
| 224 | |
| 225 void TestWindowTreeClient::OnTransientWindowAdded( | |
| 226 uint32_t window_id, | |
| 227 uint32_t transient_window_id) {} | |
| 228 | |
| 229 void TestWindowTreeClient::OnTransientWindowRemoved( | |
| 230 uint32_t window_id, | |
| 231 uint32_t transient_window_id) {} | |
| 232 | |
| 233 void TestWindowTreeClient::OnWindowHierarchyChanged( | |
| 234 uint32_t window, | |
| 235 uint32_t old_parent, | |
| 236 uint32_t new_parent, | |
| 237 mojo::Array<mojom::WindowDataPtr> windows) { | |
| 238 tracker_.OnWindowHierarchyChanged(window, old_parent, new_parent, | |
| 239 std::move(windows)); | |
| 240 } | |
| 241 | |
| 242 void TestWindowTreeClient::OnWindowReordered(uint32_t window_id, | |
| 243 uint32_t relative_window_id, | |
| 244 mojom::OrderDirection direction) { | |
| 245 tracker_.OnWindowReordered(window_id, relative_window_id, direction); | |
| 246 } | |
| 247 | |
| 248 void TestWindowTreeClient::OnWindowDeleted(uint32_t window) { | |
| 249 tracker_.OnWindowDeleted(window); | |
| 250 } | |
| 251 | |
| 252 void TestWindowTreeClient::OnWindowVisibilityChanged(uint32_t window, | |
| 253 bool visible) { | |
| 254 tracker_.OnWindowVisibilityChanged(window, visible); | |
| 255 } | |
| 256 | |
| 257 void TestWindowTreeClient::OnWindowOpacityChanged(uint32_t window, | |
| 258 float old_opacity, | |
| 259 float new_opacity) { | |
| 260 tracker_.OnWindowOpacityChanged(window, new_opacity); | |
| 261 } | |
| 262 | |
| 263 void TestWindowTreeClient::OnWindowParentDrawnStateChanged(uint32_t window, | |
| 264 bool drawn) { | |
| 265 tracker_.OnWindowParentDrawnStateChanged(window, drawn); | |
| 266 } | |
| 267 | |
| 268 void TestWindowTreeClient::OnWindowSharedPropertyChanged( | |
| 269 uint32_t window, | |
| 270 const mojo::String& name, | |
| 271 mojo::Array<uint8_t> new_data) { | |
| 272 tracker_.OnWindowSharedPropertyChanged(window, name, std::move(new_data)); | |
| 273 } | |
| 274 | |
| 275 void TestWindowTreeClient::OnWindowInputEvent(uint32_t event_id, | |
| 276 uint32_t window, | |
| 277 std::unique_ptr<ui::Event> event, | |
| 278 uint32_t event_observer_id) { | |
| 279 tracker_.OnWindowInputEvent(window, *event.get(), event_observer_id); | |
| 280 } | |
| 281 | |
| 282 void TestWindowTreeClient::OnEventObserved(std::unique_ptr<ui::Event> event, | |
| 283 uint32_t event_observer_id) { | |
| 284 tracker_.OnEventObserved(*event.get(), event_observer_id); | |
| 285 } | |
| 286 | |
| 287 void TestWindowTreeClient::OnWindowFocused(uint32_t focused_window_id) { | |
| 288 tracker_.OnWindowFocused(focused_window_id); | |
| 289 } | |
| 290 | |
| 291 void TestWindowTreeClient::OnWindowPredefinedCursorChanged( | |
| 292 uint32_t window_id, | |
| 293 mojom::Cursor cursor_id) { | |
| 294 tracker_.OnWindowPredefinedCursorChanged(window_id, cursor_id); | |
| 295 } | |
| 296 | |
| 297 void TestWindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) { | |
| 298 if (record_on_change_completed_) | |
| 299 tracker_.OnChangeCompleted(change_id, success); | |
| 300 } | |
| 301 | |
| 302 void TestWindowTreeClient::RequestClose(uint32_t window_id) {} | |
| 303 | |
| 304 void TestWindowTreeClient::GetWindowManager( | |
| 305 mojo::AssociatedInterfaceRequest<mojom::WindowManager> internal) {} | |
| 306 | |
| 307 // TestWindowTreeBinding ------------------------------------------------------ | |
| 308 | |
| 309 TestWindowTreeBinding::TestWindowTreeBinding(WindowTree* tree) | |
| 310 : WindowTreeBinding(&client_), tree_(tree) {} | |
| 311 TestWindowTreeBinding::~TestWindowTreeBinding() {} | |
| 312 | |
| 313 mojom::WindowManager* TestWindowTreeBinding::GetWindowManager() { | |
| 314 if (!window_manager_.get()) | |
| 315 window_manager_.reset(new TestWindowManager); | |
| 316 return window_manager_.get(); | |
| 317 } | |
| 318 void TestWindowTreeBinding::SetIncomingMethodCallProcessingPaused(bool paused) { | |
| 319 is_paused_ = paused; | |
| 320 } | |
| 321 | |
| 322 // TestWindowServerDelegate ---------------------------------------------- | |
| 323 | |
| 324 TestWindowServerDelegate::TestWindowServerDelegate() {} | |
| 325 TestWindowServerDelegate::~TestWindowServerDelegate() {} | |
| 326 | |
| 327 Display* TestWindowServerDelegate::AddDisplay() { | |
| 328 // Display manages its own lifetime. | |
| 329 Display* display = new Display(window_server_, PlatformDisplayInitParams()); | |
| 330 display->Init(nullptr); | |
| 331 return display; | |
| 332 } | |
| 333 | |
| 334 void TestWindowServerDelegate::OnNoMoreDisplays() { | |
| 335 got_on_no_more_displays_ = true; | |
| 336 } | |
| 337 | |
| 338 std::unique_ptr<WindowTreeBinding> | |
| 339 TestWindowServerDelegate::CreateWindowTreeBinding( | |
| 340 BindingType type, | |
| 341 ws::WindowServer* window_server, | |
| 342 ws::WindowTree* tree, | |
| 343 mojom::WindowTreeRequest* tree_request, | |
| 344 mojom::WindowTreeClientPtr* client) { | |
| 345 std::unique_ptr<TestWindowTreeBinding> binding( | |
| 346 new TestWindowTreeBinding(tree)); | |
| 347 bindings_.push_back(binding.get()); | |
| 348 return std::move(binding); | |
| 349 } | |
| 350 | |
| 351 void TestWindowServerDelegate::CreateDefaultDisplays() { | |
| 352 DCHECK(num_displays_to_create_); | |
| 353 DCHECK(window_server_); | |
| 354 | |
| 355 for (int i = 0; i < num_displays_to_create_; ++i) | |
| 356 AddDisplay(); | |
| 357 } | |
| 358 | |
| 359 bool TestWindowServerDelegate::IsTestConfig() const { | |
| 360 return true; | |
| 361 } | |
| 362 | |
| 363 // WindowEventTargetingHelper ------------------------------------------------ | |
| 364 | |
| 365 WindowEventTargetingHelper::WindowEventTargetingHelper() | |
| 366 : wm_client_(nullptr), | |
| 367 cursor_id_(0), | |
| 368 platform_display_factory_(&cursor_id_), | |
| 369 display_binding_(nullptr), | |
| 370 display_(nullptr), | |
| 371 surfaces_state_(new SurfacesState()), | |
| 372 window_server_(nullptr) { | |
| 373 PlatformDisplay::set_factory_for_testing(&platform_display_factory_); | |
| 374 window_server_.reset( | |
| 375 new WindowServer(&window_server_delegate_, surfaces_state_)); | |
| 376 PlatformDisplayInitParams display_init_params; | |
| 377 display_init_params.surfaces_state = surfaces_state_; | |
| 378 display_ = new Display(window_server_.get(), display_init_params); | |
| 379 display_binding_ = new TestDisplayBinding(window_server_.get()); | |
| 380 display_->Init(base::WrapUnique(display_binding_)); | |
| 381 wm_client_ = window_server_delegate_.last_client(); | |
| 382 wm_client_->tracker()->changes()->clear(); | |
| 383 } | |
| 384 | |
| 385 WindowEventTargetingHelper::~WindowEventTargetingHelper() {} | |
| 386 | |
| 387 ServerWindow* WindowEventTargetingHelper::CreatePrimaryTree( | |
| 388 const gfx::Rect& root_window_bounds, | |
| 389 const gfx::Rect& window_bounds) { | |
| 390 WindowTree* wm_tree = window_server_->GetTreeWithId(1); | |
| 391 const ClientWindowId embed_window_id( | |
| 392 WindowIdToTransportId(WindowId(wm_tree->id(), 1))); | |
| 393 EXPECT_TRUE(wm_tree->NewWindow(embed_window_id, ServerWindow::Properties())); | |
| 394 EXPECT_TRUE(wm_tree->SetWindowVisibility(embed_window_id, true)); | |
| 395 EXPECT_TRUE(wm_tree->AddWindow(FirstRootId(wm_tree), embed_window_id)); | |
| 396 display_->root_window()->SetBounds(root_window_bounds); | |
| 397 mojom::WindowTreeClientPtr client; | |
| 398 mojom::WindowTreeClientRequest client_request = GetProxy(&client); | |
| 399 wm_client_->Bind(std::move(client_request)); | |
| 400 const uint32_t embed_flags = 0; | |
| 401 wm_tree->Embed(embed_window_id, std::move(client), embed_flags); | |
| 402 ServerWindow* embed_window = wm_tree->GetWindowByClientId(embed_window_id); | |
| 403 WindowTree* tree1 = window_server_->GetTreeWithRoot(embed_window); | |
| 404 EXPECT_NE(nullptr, tree1); | |
| 405 EXPECT_NE(tree1, wm_tree); | |
| 406 WindowTreeTestApi(tree1).set_user_id(wm_tree->user_id()); | |
| 407 | |
| 408 embed_window->SetBounds(window_bounds); | |
| 409 | |
| 410 return embed_window; | |
| 411 } | |
| 412 | |
| 413 void WindowEventTargetingHelper::CreateSecondaryTree( | |
| 414 ServerWindow* embed_window, | |
| 415 const gfx::Rect& window_bounds, | |
| 416 TestWindowTreeClient** out_client, | |
| 417 WindowTree** window_tree, | |
| 418 ServerWindow** window) { | |
| 419 WindowTree* tree1 = window_server_->GetTreeWithRoot(embed_window); | |
| 420 ASSERT_TRUE(tree1 != nullptr); | |
| 421 const ClientWindowId child1_id( | |
| 422 WindowIdToTransportId(WindowId(tree1->id(), 1))); | |
| 423 EXPECT_TRUE(tree1->NewWindow(child1_id, ServerWindow::Properties())); | |
| 424 ServerWindow* child1 = tree1->GetWindowByClientId(child1_id); | |
| 425 ASSERT_TRUE(child1); | |
| 426 EXPECT_TRUE(tree1->AddWindow(ClientWindowIdForWindow(tree1, embed_window), | |
| 427 child1_id)); | |
| 428 tree1->GetDisplay(embed_window)->AddActivationParent(embed_window); | |
| 429 | |
| 430 child1->SetVisible(true); | |
| 431 child1->SetBounds(window_bounds); | |
| 432 EnableHitTest(child1); | |
| 433 | |
| 434 TestWindowTreeClient* embed_client = | |
| 435 window_server_delegate_.last_client(); | |
| 436 embed_client->tracker()->changes()->clear(); | |
| 437 wm_client_->tracker()->changes()->clear(); | |
| 438 | |
| 439 *out_client = embed_client; | |
| 440 *window_tree = tree1; | |
| 441 *window = child1; | |
| 442 } | |
| 443 | |
| 444 void WindowEventTargetingHelper::SetTaskRunner( | |
| 445 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { | |
| 446 message_loop_.SetTaskRunner(task_runner); | |
| 447 } | |
| 448 | |
| 449 // ---------------------------------------------------------------------------- | |
| 450 | |
| 451 ServerWindow* FirstRoot(WindowTree* tree) { | |
| 452 return tree->roots().size() == 1u | |
| 453 ? tree->GetWindow((*tree->roots().begin())->id()) | |
| 454 : nullptr; | |
| 455 } | |
| 456 | |
| 457 ClientWindowId FirstRootId(WindowTree* tree) { | |
| 458 ServerWindow* first_root = FirstRoot(tree); | |
| 459 return first_root ? ClientWindowIdForWindow(tree, first_root) | |
| 460 : ClientWindowId(); | |
| 461 } | |
| 462 | |
| 463 ClientWindowId ClientWindowIdForWindow(WindowTree* tree, | |
| 464 const ServerWindow* window) { | |
| 465 ClientWindowId client_window_id; | |
| 466 // If window isn't known we'll return 0, which should then error out. | |
| 467 tree->IsWindowKnown(window, &client_window_id); | |
| 468 return client_window_id; | |
| 469 } | |
| 470 | |
| 471 ServerWindow* NewWindowInTree(WindowTree* tree, ClientWindowId* client_id) { | |
| 472 return NewWindowInTreeWithParent(tree, FirstRoot(tree), client_id); | |
| 473 } | |
| 474 | |
| 475 ServerWindow* NewWindowInTreeWithParent(WindowTree* tree, | |
| 476 ServerWindow* parent, | |
| 477 ClientWindowId* client_id) { | |
| 478 if (!parent) | |
| 479 return nullptr; | |
| 480 ClientWindowId parent_client_id; | |
| 481 if (!tree->IsWindowKnown(parent, &parent_client_id)) | |
| 482 return nullptr; | |
| 483 ClientWindowId client_window_id = NextUnusedClientWindowId(tree); | |
| 484 if (!tree->NewWindow(client_window_id, ServerWindow::Properties())) | |
| 485 return nullptr; | |
| 486 if (!tree->SetWindowVisibility(client_window_id, true)) | |
| 487 return nullptr; | |
| 488 if (!tree->AddWindow(parent_client_id, client_window_id)) | |
| 489 return nullptr; | |
| 490 *client_id = client_window_id; | |
| 491 return tree->GetWindowByClientId(client_window_id); | |
| 492 } | |
| 493 | |
| 494 } // namespace test | |
| 495 } // namespace ws | |
| 496 } // namespace mus | |
| OLD | NEW |