| 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 <string> | 5 #include <string> |
| 6 #include <vector> | 6 #include <vector> |
| 7 | 7 |
| 8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "components/mus/common/types.h" | 9 #include "components/mus/common/types.h" |
| 10 #include "components/mus/common/util.h" | 10 #include "components/mus/common/util.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 tracker_.OnWindowSharedPropertyChanged(window, name, new_data.Pass()); | 117 tracker_.OnWindowSharedPropertyChanged(window, name, new_data.Pass()); |
| 118 } | 118 } |
| 119 void OnWindowInputEvent(uint32_t event_id, | 119 void OnWindowInputEvent(uint32_t event_id, |
| 120 uint32_t window, | 120 uint32_t window, |
| 121 EventPtr event) override { | 121 EventPtr event) override { |
| 122 tracker_.OnWindowInputEvent(window, event.Pass()); | 122 tracker_.OnWindowInputEvent(window, event.Pass()); |
| 123 } | 123 } |
| 124 void OnWindowFocused(uint32_t focused_window_id) override { | 124 void OnWindowFocused(uint32_t focused_window_id) override { |
| 125 tracker_.OnWindowFocused(focused_window_id); | 125 tracker_.OnWindowFocused(focused_window_id); |
| 126 } | 126 } |
| 127 void OnWindowPredefinedCursorChanged(uint32 window_id, |
| 128 mojom::Cursor cursor_id) override { |
| 129 tracker_.OnWindowPredefinedCursorChanged(window_id, cursor_id); |
| 130 } |
| 127 void OnChangeCompleted(uint32_t change_id, bool success) override {} | 131 void OnChangeCompleted(uint32_t change_id, bool success) override {} |
| 128 void WmSetBounds(uint32_t change_id, | 132 void WmSetBounds(uint32_t change_id, |
| 129 Id window_id, | 133 Id window_id, |
| 130 mojo::RectPtr bounds) override {} | 134 mojo::RectPtr bounds) override {} |
| 131 void WmSetProperty(uint32_t change_id, | 135 void WmSetProperty(uint32_t change_id, |
| 132 Id window_id, | 136 Id window_id, |
| 133 const mojo::String& name, | 137 const mojo::String& name, |
| 134 mojo::Array<uint8_t> transit_data) override {} | 138 mojo::Array<uint8_t> transit_data) override {} |
| 135 | 139 |
| 136 TestChangeTracker tracker_; | 140 TestChangeTracker tracker_; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 mus::mojom::WindowTree::ACCESS_POLICY_EMBED_ROOT, | 217 mus::mojom::WindowTree::ACCESS_POLICY_EMBED_ROOT, |
| 214 mus::mojom::WindowTreeClientPtr())); | 218 mus::mojom::WindowTreeClientPtr())); |
| 215 } | 219 } |
| 216 DISALLOW_COPY_AND_ASSIGN(TestWindowTreeHostConnection); | 220 DISALLOW_COPY_AND_ASSIGN(TestWindowTreeHostConnection); |
| 217 }; | 221 }; |
| 218 | 222 |
| 219 // ----------------------------------------------------------------------------- | 223 // ----------------------------------------------------------------------------- |
| 220 // Empty implementation of DisplayManager. | 224 // Empty implementation of DisplayManager. |
| 221 class TestDisplayManager : public DisplayManager { | 225 class TestDisplayManager : public DisplayManager { |
| 222 public: | 226 public: |
| 223 TestDisplayManager() {} | 227 explicit TestDisplayManager(int32_t* cursor_id_storage) |
| 228 : cursor_id_storage_(cursor_id_storage) {} |
| 224 ~TestDisplayManager() override {} | 229 ~TestDisplayManager() override {} |
| 225 | 230 |
| 226 // DisplayManager: | 231 // DisplayManager: |
| 227 void Init(DisplayManagerDelegate* delegate) override { | 232 void Init(DisplayManagerDelegate* delegate) override { |
| 228 // It is necessary to tell the delegate about the ViewportMetrics to make | 233 // It is necessary to tell the delegate about the ViewportMetrics to make |
| 229 // sure that the WindowTreeHostConnection is correctly initialized (and a | 234 // sure that the WindowTreeHostConnection is correctly initialized (and a |
| 230 // root-window is created). | 235 // root-window is created). |
| 231 mojom::ViewportMetrics metrics; | 236 mojom::ViewportMetrics metrics; |
| 232 metrics.size_in_pixels = mojo::Size::From(gfx::Size(400, 300)); | 237 metrics.size_in_pixels = mojo::Size::From(gfx::Size(400, 300)); |
| 233 metrics.device_pixel_ratio = 1.f; | 238 metrics.device_pixel_ratio = 1.f; |
| 234 delegate->OnViewportMetricsChanged(mojom::ViewportMetrics(), metrics); | 239 delegate->OnViewportMetricsChanged(mojom::ViewportMetrics(), metrics); |
| 235 } | 240 } |
| 236 void SchedulePaint(const ServerWindow* window, | 241 void SchedulePaint(const ServerWindow* window, |
| 237 const gfx::Rect& bounds) override {} | 242 const gfx::Rect& bounds) override {} |
| 238 void SetViewportSize(const gfx::Size& size) override {} | 243 void SetViewportSize(const gfx::Size& size) override {} |
| 239 void SetTitle(const base::string16& title) override {} | 244 void SetTitle(const base::string16& title) override {} |
| 245 void SetCursorById(int32_t cursor) override { *cursor_id_storage_ = cursor; } |
| 240 const mojom::ViewportMetrics& GetViewportMetrics() override { | 246 const mojom::ViewportMetrics& GetViewportMetrics() override { |
| 241 return display_metrices_; | 247 return display_metrices_; |
| 242 } | 248 } |
| 243 void UpdateTextInputState(const ui::TextInputState& state) override {} | 249 void UpdateTextInputState(const ui::TextInputState& state) override {} |
| 244 void SetImeVisibility(bool visible) override {} | 250 void SetImeVisibility(bool visible) override {} |
| 245 bool IsFramePending() const override { return false; } | 251 bool IsFramePending() const override { return false; } |
| 246 | 252 |
| 247 private: | 253 private: |
| 248 mojom::ViewportMetrics display_metrices_; | 254 mojom::ViewportMetrics display_metrices_; |
| 249 | 255 |
| 256 int32_t* cursor_id_storage_; |
| 257 |
| 250 DISALLOW_COPY_AND_ASSIGN(TestDisplayManager); | 258 DISALLOW_COPY_AND_ASSIGN(TestDisplayManager); |
| 251 }; | 259 }; |
| 252 | 260 |
| 253 // Factory that dispenses TestDisplayManagers. | 261 // Factory that dispenses TestDisplayManagers. |
| 254 class TestDisplayManagerFactory : public DisplayManagerFactory { | 262 class TestDisplayManagerFactory : public DisplayManagerFactory { |
| 255 public: | 263 public: |
| 256 TestDisplayManagerFactory() {} | 264 explicit TestDisplayManagerFactory(int32_t* cursor_id_storage) |
| 265 : cursor_id_storage_(cursor_id_storage) {} |
| 257 ~TestDisplayManagerFactory() {} | 266 ~TestDisplayManagerFactory() {} |
| 258 DisplayManager* CreateDisplayManager( | 267 DisplayManager* CreateDisplayManager( |
| 259 mojo::ApplicationImpl* app_impl, | 268 mojo::ApplicationImpl* app_impl, |
| 260 const scoped_refptr<GpuState>& gpu_state, | 269 const scoped_refptr<GpuState>& gpu_state, |
| 261 const scoped_refptr<mus::SurfacesState>& surfaces_state) override { | 270 const scoped_refptr<mus::SurfacesState>& surfaces_state) override { |
| 262 return new TestDisplayManager(); | 271 return new TestDisplayManager(cursor_id_storage_); |
| 263 } | 272 } |
| 264 | 273 |
| 265 private: | 274 private: |
| 275 int32_t* cursor_id_storage_; |
| 276 |
| 266 DISALLOW_COPY_AND_ASSIGN(TestDisplayManagerFactory); | 277 DISALLOW_COPY_AND_ASSIGN(TestDisplayManagerFactory); |
| 267 }; | 278 }; |
| 268 | 279 |
| 269 EventPtr CreatePointerDownEvent(int x, int y) { | 280 EventPtr CreatePointerDownEvent(int x, int y) { |
| 270 EventPtr event(Event::New()); | 281 EventPtr event(Event::New()); |
| 271 event->action = mus::mojom::EVENT_TYPE_POINTER_DOWN; | 282 event->action = mus::mojom::EVENT_TYPE_POINTER_DOWN; |
| 272 event->pointer_data = PointerData::New(); | 283 event->pointer_data = PointerData::New(); |
| 273 event->pointer_data->pointer_id = 1u; | 284 event->pointer_data->pointer_id = 1u; |
| 274 event->pointer_data->location = LocationData::New(); | 285 event->pointer_data->location = LocationData::New(); |
| 275 event->pointer_data->location->x = x; | 286 event->pointer_data->location->x = x; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 295 event->action = mus::mojom::EVENT_TYPE_POINTER_MOVE; | 306 event->action = mus::mojom::EVENT_TYPE_POINTER_MOVE; |
| 296 event->pointer_data = PointerData::New(); | 307 event->pointer_data = PointerData::New(); |
| 297 event->pointer_data->pointer_id = std::numeric_limits<uint32_t>::max(); | 308 event->pointer_data->pointer_id = std::numeric_limits<uint32_t>::max(); |
| 298 event->pointer_data->location = LocationData::New(); | 309 event->pointer_data->location = LocationData::New(); |
| 299 event->pointer_data->location->x = x; | 310 event->pointer_data->location->x = x; |
| 300 event->pointer_data->location->y = y; | 311 event->pointer_data->location->y = y; |
| 301 event->pointer_data->kind = mojom::POINTER_KIND_MOUSE; | 312 event->pointer_data->kind = mojom::POINTER_KIND_MOUSE; |
| 302 return event.Pass(); | 313 return event.Pass(); |
| 303 } | 314 } |
| 304 | 315 |
| 316 EventPtr CreateMouseDownEvent(int x, int y) { |
| 317 EventPtr event = CreatePointerDownEvent(x, y); |
| 318 event->flags = static_cast<mus::mojom::EventFlags>( |
| 319 event->flags | mojom::EVENT_FLAGS_LEFT_MOUSE_BUTTON); |
| 320 event->pointer_data->kind = mojom::POINTER_KIND_MOUSE; |
| 321 return event.Pass(); |
| 322 } |
| 323 |
| 324 EventPtr CreateMouseUpEvent(int x, int y) { |
| 325 EventPtr event = CreatePointerUpEvent(x, y); |
| 326 event->flags = static_cast<mus::mojom::EventFlags>( |
| 327 event->flags | mojom::EVENT_FLAGS_LEFT_MOUSE_BUTTON); |
| 328 event->pointer_data->kind = mojom::POINTER_KIND_MOUSE; |
| 329 return event.Pass(); |
| 330 } |
| 331 |
| 305 } // namespace | 332 } // namespace |
| 306 | 333 |
| 307 // ----------------------------------------------------------------------------- | 334 // ----------------------------------------------------------------------------- |
| 308 | 335 |
| 309 class WindowTreeTest : public testing::Test { | 336 class WindowTreeTest : public testing::Test { |
| 310 public: | 337 public: |
| 311 WindowTreeTest() : wm_client_(nullptr) {} | 338 WindowTreeTest() |
| 339 : wm_client_(nullptr), |
| 340 cursor_id_(0), |
| 341 display_manager_factory_(&cursor_id_) {} |
| 312 ~WindowTreeTest() override {} | 342 ~WindowTreeTest() override {} |
| 313 | 343 |
| 314 // WindowTreeImpl for the window manager. | 344 // WindowTreeImpl for the window manager. |
| 315 WindowTreeImpl* wm_connection() { | 345 WindowTreeImpl* wm_connection() { |
| 316 return connection_manager_->GetConnection(1); | 346 return connection_manager_->GetConnection(1); |
| 317 } | 347 } |
| 318 | 348 |
| 319 TestWindowTreeClient* last_window_tree_client() { | 349 TestWindowTreeClient* last_window_tree_client() { |
| 320 return delegate_.last_client(); | 350 return delegate_.last_client(); |
| 321 } | 351 } |
| 322 | 352 |
| 323 TestClientConnection* last_client_connection() { | 353 TestClientConnection* last_client_connection() { |
| 324 return delegate_.last_connection(); | 354 return delegate_.last_connection(); |
| 325 } | 355 } |
| 326 | 356 |
| 327 ConnectionManager* connection_manager() { return connection_manager_.get(); } | 357 ConnectionManager* connection_manager() { return connection_manager_.get(); } |
| 328 | 358 |
| 329 TestWindowTreeClient* wm_client() { return wm_client_; } | 359 TestWindowTreeClient* wm_client() { return wm_client_; } |
| 360 int32_t cursor_id() { return cursor_id_; } |
| 330 | 361 |
| 331 TestWindowTreeHostConnection* host_connection() { return host_connection_; } | 362 TestWindowTreeHostConnection* host_connection() { return host_connection_; } |
| 332 | 363 |
| 333 void DispatchEventWithoutAck(mojom::EventPtr event) { | 364 void DispatchEventWithoutAck(mojom::EventPtr event) { |
| 334 host_connection()->window_tree_host()->OnEvent(event.Pass()); | 365 host_connection()->window_tree_host()->OnEvent(event.Pass()); |
| 335 } | 366 } |
| 336 | 367 |
| 337 void AckPreviousEvent() { | 368 void AckPreviousEvent() { |
| 338 host_connection() | 369 host_connection() |
| 339 ->window_tree_host() | 370 ->window_tree_host() |
| 340 ->tree_awaiting_input_ack_->OnWindowInputEventAck(0); | 371 ->tree_awaiting_input_ack_->OnWindowInputEventAck(0); |
| 341 } | 372 } |
| 342 | 373 |
| 343 void DispatchEventAndAckImmediately(mojom::EventPtr event) { | 374 void DispatchEventAndAckImmediately(mojom::EventPtr event) { |
| 344 DispatchEventWithoutAck(event.Pass()); | 375 DispatchEventWithoutAck(event.Pass()); |
| 345 AckPreviousEvent(); | 376 AckPreviousEvent(); |
| 346 } | 377 } |
| 347 | 378 |
| 379 // Embeds a child window to the root window. Shared setup between several of |
| 380 // the unit tests. |
| 381 void SetupEventTargeting(TestWindowTreeClient** out_client, |
| 382 ServerWindow** out_window); |
| 383 |
| 348 protected: | 384 protected: |
| 349 // testing::Test: | 385 // testing::Test: |
| 350 void SetUp() override { | 386 void SetUp() override { |
| 351 DisplayManager::set_factory_for_testing(&display_manager_factory_); | 387 DisplayManager::set_factory_for_testing(&display_manager_factory_); |
| 352 // TODO(fsamuel): This is probably broken. We need a root. | 388 // TODO(fsamuel): This is probably broken. We need a root. |
| 353 connection_manager_.reset( | 389 connection_manager_.reset( |
| 354 new ConnectionManager(&delegate_, scoped_refptr<SurfacesState>())); | 390 new ConnectionManager(&delegate_, scoped_refptr<SurfacesState>())); |
| 355 WindowTreeHostImpl* host = new WindowTreeHostImpl( | 391 WindowTreeHostImpl* host = new WindowTreeHostImpl( |
| 356 mus::mojom::WindowTreeHostClientPtr(), connection_manager_.get(), | 392 mus::mojom::WindowTreeHostClientPtr(), connection_manager_.get(), |
| 357 nullptr, scoped_refptr<GpuState>(), scoped_refptr<mus::SurfacesState>(), | 393 nullptr, scoped_refptr<GpuState>(), scoped_refptr<mus::SurfacesState>(), |
| 358 nullptr); | 394 nullptr); |
| 359 // TODO(fsamuel): This is way too magical. We need to find a better way to | 395 // TODO(fsamuel): This is way too magical. We need to find a better way to |
| 360 // manage lifetime. | 396 // manage lifetime. |
| 361 host_connection_ = new TestWindowTreeHostConnection( | 397 host_connection_ = new TestWindowTreeHostConnection( |
| 362 make_scoped_ptr(host), connection_manager_.get()); | 398 make_scoped_ptr(host), connection_manager_.get()); |
| 363 host->Init(host_connection_); | 399 host->Init(host_connection_); |
| 364 wm_client_ = delegate_.last_client(); | 400 wm_client_ = delegate_.last_client(); |
| 365 } | 401 } |
| 366 | 402 |
| 367 private: | 403 private: |
| 368 // TestWindowTreeClient that is used for the WM connection. | 404 // TestWindowTreeClient that is used for the WM connection. |
| 369 TestWindowTreeClient* wm_client_; | 405 TestWindowTreeClient* wm_client_; |
| 406 int32_t cursor_id_; |
| 370 TestDisplayManagerFactory display_manager_factory_; | 407 TestDisplayManagerFactory display_manager_factory_; |
| 371 TestConnectionManagerDelegate delegate_; | 408 TestConnectionManagerDelegate delegate_; |
| 372 TestWindowTreeHostConnection* host_connection_; | 409 TestWindowTreeHostConnection* host_connection_; |
| 373 scoped_ptr<ConnectionManager> connection_manager_; | 410 scoped_ptr<ConnectionManager> connection_manager_; |
| 374 base::MessageLoop message_loop_; | 411 base::MessageLoop message_loop_; |
| 375 | 412 |
| 376 DISALLOW_COPY_AND_ASSIGN(WindowTreeTest); | 413 DISALLOW_COPY_AND_ASSIGN(WindowTreeTest); |
| 377 }; | 414 }; |
| 378 | 415 |
| 416 void WindowTreeTest::SetupEventTargeting(TestWindowTreeClient** out_client, |
| 417 ServerWindow** out_window) { |
| 418 const WindowId embed_window_id(wm_connection()->id(), 1); |
| 419 EXPECT_TRUE( |
| 420 wm_connection()->NewWindow(embed_window_id, ServerWindow::Properties())); |
| 421 EXPECT_TRUE(wm_connection()->SetWindowVisibility(embed_window_id, true)); |
| 422 EXPECT_TRUE( |
| 423 wm_connection()->AddWindow(*(wm_connection()->root()), embed_window_id)); |
| 424 host_connection()->window_tree_host()->root_window()->SetBounds( |
| 425 gfx::Rect(0, 0, 100, 100)); |
| 426 mojom::WindowTreeClientPtr client; |
| 427 mojo::InterfaceRequest<mojom::WindowTreeClient> client_request = |
| 428 GetProxy(&client); |
| 429 wm_client()->Bind(client_request.Pass()); |
| 430 ConnectionSpecificId connection_id = 0; |
| 431 wm_connection()->Embed(embed_window_id, client.Pass(), |
| 432 mojom::WindowTree::ACCESS_POLICY_DEFAULT, |
| 433 &connection_id); |
| 434 WindowTreeImpl* connection1 = |
| 435 connection_manager()->GetConnectionWithRoot(embed_window_id); |
| 436 ASSERT_TRUE(connection1 != nullptr); |
| 437 ASSERT_NE(connection1, wm_connection()); |
| 438 |
| 439 connection_manager() |
| 440 ->GetWindow(embed_window_id) |
| 441 ->SetBounds(gfx::Rect(0, 0, 50, 50)); |
| 442 |
| 443 const WindowId child1(connection1->id(), 1); |
| 444 EXPECT_TRUE(connection1->NewWindow(child1, ServerWindow::Properties())); |
| 445 EXPECT_TRUE(connection1->AddWindow(embed_window_id, child1)); |
| 446 connection1->GetHost()->AddActivationParent( |
| 447 WindowIdToTransportId(embed_window_id)); |
| 448 |
| 449 ServerWindow* v1 = connection1->GetWindow(child1); |
| 450 v1->SetVisible(true); |
| 451 v1->SetBounds(gfx::Rect(20, 20, 20, 20)); |
| 452 EnableHitTest(v1); |
| 453 |
| 454 TestWindowTreeClient* embed_connection = last_window_tree_client(); |
| 455 embed_connection->tracker()->changes()->clear(); |
| 456 wm_client()->tracker()->changes()->clear(); |
| 457 |
| 458 *out_client = embed_connection; |
| 459 *out_window = v1; |
| 460 } |
| 461 |
| 379 // Verifies focus correctly changes on pointer events. | 462 // Verifies focus correctly changes on pointer events. |
| 380 TEST_F(WindowTreeTest, FocusOnPointer) { | 463 TEST_F(WindowTreeTest, FocusOnPointer) { |
| 381 const WindowId embed_window_id(wm_connection()->id(), 1); | 464 const WindowId embed_window_id(wm_connection()->id(), 1); |
| 382 EXPECT_TRUE( | 465 EXPECT_TRUE( |
| 383 wm_connection()->NewWindow(embed_window_id, ServerWindow::Properties())); | 466 wm_connection()->NewWindow(embed_window_id, ServerWindow::Properties())); |
| 384 EXPECT_TRUE(wm_connection()->SetWindowVisibility(embed_window_id, true)); | 467 EXPECT_TRUE(wm_connection()->SetWindowVisibility(embed_window_id, true)); |
| 385 EXPECT_TRUE( | 468 EXPECT_TRUE( |
| 386 wm_connection()->AddWindow(*(wm_connection()->root()), embed_window_id)); | 469 wm_connection()->AddWindow(*(wm_connection()->root()), embed_window_id)); |
| 387 host_connection()->window_tree_host()->root_window()->SetBounds( | 470 host_connection()->window_tree_host()->root_window()->SetBounds( |
| 388 gfx::Rect(0, 0, 100, 100)); | 471 gfx::Rect(0, 0, 100, 100)); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 DispatchEventAndAckImmediately(CreatePointerDownEvent(61, 22)); | 540 DispatchEventAndAckImmediately(CreatePointerDownEvent(61, 22)); |
| 458 EXPECT_EQ(v1, host_connection()->window_tree_host()->GetFocusedWindow()); | 541 EXPECT_EQ(v1, host_connection()->window_tree_host()->GetFocusedWindow()); |
| 459 ASSERT_EQ(wm_client()->tracker()->changes()->size(), 1u) | 542 ASSERT_EQ(wm_client()->tracker()->changes()->size(), 1u) |
| 460 << SingleChangeToDescription(*wm_client()->tracker()->changes()); | 543 << SingleChangeToDescription(*wm_client()->tracker()->changes()); |
| 461 EXPECT_EQ("InputEvent window=0,2 event_action=4", | 544 EXPECT_EQ("InputEvent window=0,2 event_action=4", |
| 462 ChangesToDescription1(*wm_client()->tracker()->changes())[0]); | 545 ChangesToDescription1(*wm_client()->tracker()->changes())[0]); |
| 463 EXPECT_TRUE(connection1_client->tracker()->changes()->empty()); | 546 EXPECT_TRUE(connection1_client->tracker()->changes()->empty()); |
| 464 } | 547 } |
| 465 | 548 |
| 466 TEST_F(WindowTreeTest, BasicInputEventTarget) { | 549 TEST_F(WindowTreeTest, BasicInputEventTarget) { |
| 467 const WindowId embed_window_id(wm_connection()->id(), 1); | 550 TestWindowTreeClient* embed_connection = nullptr; |
| 468 EXPECT_TRUE( | 551 ServerWindow* out_window = nullptr; |
| 469 wm_connection()->NewWindow(embed_window_id, ServerWindow::Properties())); | 552 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_connection, &out_window)); |
| 470 EXPECT_TRUE(wm_connection()->SetWindowVisibility(embed_window_id, true)); | |
| 471 EXPECT_TRUE( | |
| 472 wm_connection()->AddWindow(*(wm_connection()->root()), embed_window_id)); | |
| 473 host_connection()->window_tree_host()->root_window()->SetBounds( | |
| 474 gfx::Rect(0, 0, 100, 100)); | |
| 475 mojom::WindowTreeClientPtr client; | |
| 476 mojo::InterfaceRequest<mojom::WindowTreeClient> client_request = | |
| 477 GetProxy(&client); | |
| 478 wm_client()->Bind(client_request.Pass()); | |
| 479 ConnectionSpecificId connection_id = 0; | |
| 480 wm_connection()->Embed(embed_window_id, | |
| 481 client.Pass(), | |
| 482 mojom::WindowTree::ACCESS_POLICY_DEFAULT, | |
| 483 &connection_id); | |
| 484 WindowTreeImpl* connection1 = | |
| 485 connection_manager()->GetConnectionWithRoot(embed_window_id); | |
| 486 ASSERT_TRUE(connection1 != nullptr); | |
| 487 ASSERT_NE(connection1, wm_connection()); | |
| 488 | |
| 489 connection_manager() | |
| 490 ->GetWindow(embed_window_id) | |
| 491 ->SetBounds(gfx::Rect(0, 0, 50, 50)); | |
| 492 | |
| 493 const WindowId child1(connection1->id(), 1); | |
| 494 EXPECT_TRUE(connection1->NewWindow(child1, ServerWindow::Properties())); | |
| 495 EXPECT_TRUE(connection1->AddWindow(embed_window_id, child1)); | |
| 496 connection1->GetHost()->AddActivationParent( | |
| 497 WindowIdToTransportId(embed_window_id)); | |
| 498 | |
| 499 ServerWindow* v1 = connection1->GetWindow(child1); | |
| 500 v1->SetVisible(true); | |
| 501 v1->SetBounds(gfx::Rect(20, 20, 20, 20)); | |
| 502 EnableHitTest(v1); | |
| 503 | |
| 504 TestWindowTreeClient* embed_connection = last_window_tree_client(); | |
| 505 embed_connection->tracker()->changes()->clear(); | |
| 506 wm_client()->tracker()->changes()->clear(); | |
| 507 | 553 |
| 508 // Send an event to |v1|. |embed_connection| should get the event, not | 554 // Send an event to |v1|. |embed_connection| should get the event, not |
| 509 // |wm_client|, since |v1| lives inside an embedded window. | 555 // |wm_client|, since |v1| lives inside an embedded window. |
| 510 DispatchEventAndAckImmediately(CreatePointerDownEvent(21, 22)); | 556 DispatchEventAndAckImmediately(CreatePointerDownEvent(21, 22)); |
| 511 ASSERT_EQ(1u, wm_client()->tracker()->changes()->size()); | 557 ASSERT_EQ(1u, wm_client()->tracker()->changes()->size()); |
| 512 EXPECT_EQ("Focused id=2,1", | 558 EXPECT_EQ("Focused id=2,1", |
| 513 ChangesToDescription1(*wm_client()->tracker()->changes())[0]); | 559 ChangesToDescription1(*wm_client()->tracker()->changes())[0]); |
| 514 ASSERT_EQ(2u, embed_connection->tracker()->changes()->size()); | 560 ASSERT_EQ(2u, embed_connection->tracker()->changes()->size()); |
| 515 EXPECT_EQ("Focused id=2,1", | 561 EXPECT_EQ("Focused id=2,1", |
| 516 ChangesToDescription1(*embed_connection->tracker()->changes())[0]); | 562 ChangesToDescription1(*embed_connection->tracker()->changes())[0]); |
| 517 EXPECT_EQ("InputEvent window=2,1 event_action=4", | 563 EXPECT_EQ("InputEvent window=2,1 event_action=4", |
| 518 ChangesToDescription1(*embed_connection->tracker()->changes())[1]); | 564 ChangesToDescription1(*embed_connection->tracker()->changes())[1]); |
| 519 } | 565 } |
| 520 | 566 |
| 567 TEST_F(WindowTreeTest, CursorChangesWhenMouseOverWindowAndWindowSetsCursor) { |
| 568 TestWindowTreeClient* embed_connection = nullptr; |
| 569 ServerWindow* out_window = nullptr; |
| 570 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_connection, &out_window)); |
| 571 |
| 572 // Like in BasicInputEventTarget, we send a pointer down event to be |
| 573 // dispatched. This is only to place the mouse cursor over that window though. |
| 574 DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22)); |
| 575 |
| 576 out_window->SetPredefinedCursor(mojom::Cursor::CURSOR_IBEAM); |
| 577 |
| 578 // Because the cursor is over the window when SetCursor was called, we should |
| 579 // have immediately changed the cursor. |
| 580 EXPECT_EQ(mojom::Cursor::CURSOR_IBEAM, cursor_id()); |
| 581 } |
| 582 |
| 583 TEST_F(WindowTreeTest, CursorChangesWhenEnteringWindowWithDifferentCursor) { |
| 584 TestWindowTreeClient* embed_connection = nullptr; |
| 585 ServerWindow* out_window = nullptr; |
| 586 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_connection, &out_window)); |
| 587 |
| 588 // Let's create a pointer event outside the window and then move the pointer |
| 589 // inside. |
| 590 DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5)); |
| 591 out_window->SetPredefinedCursor(mojom::Cursor::CURSOR_IBEAM); |
| 592 EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id()); |
| 593 |
| 594 DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22)); |
| 595 EXPECT_EQ(mojom::Cursor::CURSOR_IBEAM, cursor_id()); |
| 596 } |
| 597 |
| 598 TEST_F(WindowTreeTest, TouchesDontChangeCursor) { |
| 599 TestWindowTreeClient* embed_connection = nullptr; |
| 600 ServerWindow* out_window = nullptr; |
| 601 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_connection, &out_window)); |
| 602 |
| 603 // Let's create a pointer event outside the window and then move the pointer |
| 604 // inside. |
| 605 DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5)); |
| 606 out_window->SetPredefinedCursor(mojom::Cursor::CURSOR_IBEAM); |
| 607 EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id()); |
| 608 |
| 609 // With a touch event, we shouldn't update the cursor. |
| 610 DispatchEventAndAckImmediately(CreatePointerDownEvent(21, 22)); |
| 611 EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id()); |
| 612 } |
| 613 |
| 614 TEST_F(WindowTreeTest, DragOutsideWindow) { |
| 615 TestWindowTreeClient* embed_connection = nullptr; |
| 616 ServerWindow* out_window = nullptr; |
| 617 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_connection, &out_window)); |
| 618 |
| 619 // Start with the cursor outside the window. Setting the cursor shouldn't |
| 620 // change the cursor. |
| 621 DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5)); |
| 622 out_window->SetPredefinedCursor(mojom::Cursor::CURSOR_IBEAM); |
| 623 EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id()); |
| 624 |
| 625 // Move the pointer to the inside of the window |
| 626 DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22)); |
| 627 EXPECT_EQ(mojom::Cursor::CURSOR_IBEAM, cursor_id()); |
| 628 |
| 629 // Start the drag. |
| 630 DispatchEventAndAckImmediately(CreateMouseDownEvent(21, 22)); |
| 631 EXPECT_EQ(mojom::Cursor::CURSOR_IBEAM, cursor_id()); |
| 632 |
| 633 // Move the cursor (mouse is still down) outside the window. |
| 634 DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5)); |
| 635 EXPECT_EQ(mojom::Cursor::CURSOR_IBEAM, cursor_id()); |
| 636 |
| 637 // Release the cursor. We should now adapt the cursor of the window |
| 638 // underneath the pointer. |
| 639 DispatchEventAndAckImmediately(CreateMouseUpEvent(5, 5)); |
| 640 EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id()); |
| 641 } |
| 642 |
| 643 // TODO(erg): Add tests for when programmatic changes to the window hierarchy |
| 644 // would cause the window that supplies the cursor to change. |
| 645 |
| 521 TEST_F(WindowTreeTest, EventAck) { | 646 TEST_F(WindowTreeTest, EventAck) { |
| 522 const WindowId embed_window_id(wm_connection()->id(), 1); | 647 const WindowId embed_window_id(wm_connection()->id(), 1); |
| 523 EXPECT_TRUE( | 648 EXPECT_TRUE( |
| 524 wm_connection()->NewWindow(embed_window_id, ServerWindow::Properties())); | 649 wm_connection()->NewWindow(embed_window_id, ServerWindow::Properties())); |
| 525 EXPECT_TRUE(wm_connection()->SetWindowVisibility(embed_window_id, true)); | 650 EXPECT_TRUE(wm_connection()->SetWindowVisibility(embed_window_id, true)); |
| 526 EXPECT_TRUE( | 651 EXPECT_TRUE( |
| 527 wm_connection()->AddWindow(*(wm_connection()->root()), embed_window_id)); | 652 wm_connection()->AddWindow(*(wm_connection()->root()), embed_window_id)); |
| 528 host_connection()->window_tree_host()->root_window()->SetBounds( | 653 host_connection()->window_tree_host()->root_window()->SetBounds( |
| 529 gfx::Rect(0, 0, 100, 100)); | 654 gfx::Rect(0, 0, 100, 100)); |
| 530 | 655 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 542 // Ack the first event. That should trigger the dispatch of the second event. | 667 // Ack the first event. That should trigger the dispatch of the second event. |
| 543 AckPreviousEvent(); | 668 AckPreviousEvent(); |
| 544 ASSERT_EQ(1u, wm_client()->tracker()->changes()->size()); | 669 ASSERT_EQ(1u, wm_client()->tracker()->changes()->size()); |
| 545 EXPECT_EQ("InputEvent window=0,2 event_action=5", | 670 EXPECT_EQ("InputEvent window=0,2 event_action=5", |
| 546 ChangesToDescription1(*wm_client()->tracker()->changes())[0]); | 671 ChangesToDescription1(*wm_client()->tracker()->changes())[0]); |
| 547 } | 672 } |
| 548 | 673 |
| 549 } // namespace ws | 674 } // namespace ws |
| 550 | 675 |
| 551 } // namespace mus | 676 } // namespace mus |
| OLD | NEW |