OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/event_dispatcher.h" | 5 #include "components/mus/ws/event_dispatcher.h" |
6 | 6 |
7 #include "components/mus/public/cpp/event_matcher.h" | 7 #include "components/mus/public/cpp/event_matcher.h" |
8 #include "components/mus/ws/event_dispatcher_delegate.h" | 8 #include "components/mus/ws/event_dispatcher_delegate.h" |
9 #include "components/mus/ws/server_window.h" | 9 #include "components/mus/ws/server_window.h" |
10 #include "components/mus/ws/test_server_window_delegate.h" | 10 #include "components/mus/ws/test_server_window_delegate.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 mojo::EventPtr GetAndClearLastDispatchedEvent() { | 29 mojo::EventPtr GetAndClearLastDispatchedEvent() { |
30 return last_dispatched_event_.Pass(); | 30 return last_dispatched_event_.Pass(); |
31 } | 31 } |
32 | 32 |
33 uint32_t GetAndClearLastAccelerator() { | 33 uint32_t GetAndClearLastAccelerator() { |
34 uint32_t return_value = last_accelerator_; | 34 uint32_t return_value = last_accelerator_; |
35 last_accelerator_ = 0; | 35 last_accelerator_ = 0; |
36 return return_value; | 36 return return_value; |
37 } | 37 } |
38 | 38 |
| 39 ServerWindow* GetAndClearLastTarget() { |
| 40 ServerWindow* result = last_target_; |
| 41 last_target_ = nullptr; |
| 42 return result; |
| 43 } |
39 ServerWindow* last_target() { return last_target_; } | 44 ServerWindow* last_target() { return last_target_; } |
40 | 45 |
41 bool GetAndClearLastInNonclientArea() { | 46 bool GetAndClearLastInNonclientArea() { |
42 const bool result = last_in_nonclient_area_; | 47 const bool result = last_in_nonclient_area_; |
43 last_in_nonclient_area_ = false; | 48 last_in_nonclient_area_ = false; |
44 return result; | 49 return result; |
45 } | 50 } |
46 | 51 |
| 52 ServerWindow* GetAndClearLastFocusedWindow() { |
| 53 ServerWindow* result = focused_window_; |
| 54 focused_window_ = nullptr; |
| 55 return result; |
| 56 } |
| 57 |
47 private: | 58 private: |
48 // EventDispatcherDelegate: | 59 // EventDispatcherDelegate: |
49 void OnAccelerator(uint32_t accelerator, mojo::EventPtr event) override { | 60 void OnAccelerator(uint32_t accelerator, mojo::EventPtr event) override { |
50 EXPECT_EQ(0u, last_accelerator_); | 61 EXPECT_EQ(0u, last_accelerator_); |
51 last_accelerator_ = accelerator; | 62 last_accelerator_ = accelerator; |
52 } | 63 } |
53 void SetFocusedWindowFromEventDispatcher(ServerWindow* window) override { | 64 void SetFocusedWindowFromEventDispatcher(ServerWindow* window) override { |
54 focused_window_ = window; | 65 focused_window_ = window; |
55 } | 66 } |
56 ServerWindow* GetFocusedWindowForEventDispatcher() override { | 67 ServerWindow* GetFocusedWindowForEventDispatcher() override { |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 // Press in the client area and verify target/client area. | 346 // Press in the client area and verify target/client area. |
336 const ui::MouseEvent press_event2( | 347 const ui::MouseEvent press_event2( |
337 ui::ET_MOUSE_PRESSED, gfx::PointF(21.f, 22.f), gfx::PointF(21.f, 22.f), | 348 ui::ET_MOUSE_PRESSED, gfx::PointF(21.f, 22.f), gfx::PointF(21.f, 22.f), |
338 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 349 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
339 dispatcher.OnEvent( | 350 dispatcher.OnEvent( |
340 mojo::Event::From(static_cast<const ui::Event&>(press_event2))); | 351 mojo::Event::From(static_cast<const ui::Event&>(press_event2))); |
341 ASSERT_EQ(&child, event_dispatcher_delegate.last_target()); | 352 ASSERT_EQ(&child, event_dispatcher_delegate.last_target()); |
342 EXPECT_FALSE(event_dispatcher_delegate.GetAndClearLastInNonclientArea()); | 353 EXPECT_FALSE(event_dispatcher_delegate.GetAndClearLastInNonclientArea()); |
343 } | 354 } |
344 | 355 |
| 356 TEST(EventDispatcherTest, DontFocusOnSecondDown) { |
| 357 TestServerWindowDelegate window_delegate; |
| 358 ServerWindow root(&window_delegate, WindowId(1, 2)); |
| 359 window_delegate.set_root_window(&root); |
| 360 root.SetVisible(true); |
| 361 |
| 362 ServerWindow child1(&window_delegate, WindowId(1, 3)); |
| 363 root.Add(&child1); |
| 364 child1.SetVisible(true); |
| 365 |
| 366 ServerWindow child2(&window_delegate, WindowId(1, 4)); |
| 367 root.Add(&child2); |
| 368 child2.SetVisible(true); |
| 369 |
| 370 root.SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 371 child1.SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 372 child2.SetBounds(gfx::Rect(50, 51, 11, 12)); |
| 373 |
| 374 TestEventDispatcherDelegate event_dispatcher_delegate(&root); |
| 375 EventDispatcher dispatcher(&event_dispatcher_delegate); |
| 376 dispatcher.set_root(&root); |
| 377 |
| 378 // Press on child1. First press event should change focus. |
| 379 const ui::MouseEvent press_event( |
| 380 ui::ET_MOUSE_PRESSED, gfx::PointF(12.f, 12.f), gfx::PointF(12.f, 12.f), |
| 381 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 382 dispatcher.OnEvent( |
| 383 mojo::Event::From(static_cast<const ui::Event&>(press_event))); |
| 384 EXPECT_EQ(&child1, event_dispatcher_delegate.last_target()); |
| 385 EXPECT_EQ(&child1, event_dispatcher_delegate.GetAndClearLastFocusedWindow()); |
| 386 |
| 387 // Press (with a different pointer id) on child2. Event should go to child2, |
| 388 // but focus should not change. |
| 389 const ui::TouchEvent touch_event( |
| 390 ui::ET_TOUCH_PRESSED, gfx::PointF(53.f, 54.f), 2, base::TimeDelta()); |
| 391 dispatcher.OnEvent( |
| 392 mojo::Event::From(static_cast<const ui::Event&>(touch_event))); |
| 393 EXPECT_EQ(&child2, event_dispatcher_delegate.last_target()); |
| 394 EXPECT_EQ(nullptr, event_dispatcher_delegate.GetAndClearLastFocusedWindow()); |
| 395 } |
| 396 |
| 397 TEST(EventDispatcherTest, TwoPointersActive) { |
| 398 TestServerWindowDelegate window_delegate; |
| 399 ServerWindow root(&window_delegate, WindowId(1, 2)); |
| 400 window_delegate.set_root_window(&root); |
| 401 root.SetVisible(true); |
| 402 |
| 403 ServerWindow child1(&window_delegate, WindowId(1, 3)); |
| 404 root.Add(&child1); |
| 405 child1.SetVisible(true); |
| 406 |
| 407 ServerWindow child2(&window_delegate, WindowId(1, 4)); |
| 408 root.Add(&child2); |
| 409 child2.SetVisible(true); |
| 410 |
| 411 root.SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 412 child1.SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 413 child2.SetBounds(gfx::Rect(50, 51, 11, 12)); |
| 414 |
| 415 TestEventDispatcherDelegate event_dispatcher_delegate(&root); |
| 416 EventDispatcher dispatcher(&event_dispatcher_delegate); |
| 417 dispatcher.set_root(&root); |
| 418 |
| 419 // Press on child1. |
| 420 const ui::TouchEvent touch_event1( |
| 421 ui::ET_TOUCH_PRESSED, gfx::PointF(12.f, 13.f), 1, base::TimeDelta()); |
| 422 dispatcher.OnEvent( |
| 423 mojo::Event::From(static_cast<const ui::Event&>(touch_event1))); |
| 424 EXPECT_EQ(&child1, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 425 |
| 426 // Drag over child2, child1 should get the drag. |
| 427 const ui::TouchEvent drag_event1(ui::ET_TOUCH_MOVED, gfx::PointF(53.f, 54.f), |
| 428 1, base::TimeDelta()); |
| 429 dispatcher.OnEvent( |
| 430 mojo::Event::From(static_cast<const ui::Event&>(drag_event1))); |
| 431 EXPECT_EQ(&child1, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 432 |
| 433 // Press on child2 with a different touch id. |
| 434 const ui::TouchEvent touch_event2( |
| 435 ui::ET_TOUCH_PRESSED, gfx::PointF(54.f, 55.f), 2, base::TimeDelta()); |
| 436 dispatcher.OnEvent( |
| 437 mojo::Event::From(static_cast<const ui::Event&>(touch_event2))); |
| 438 EXPECT_EQ(&child2, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 439 |
| 440 // Drag over child1 with id 2, child2 should continue to get the drag. |
| 441 const ui::TouchEvent drag_event2(ui::ET_TOUCH_MOVED, gfx::PointF(13.f, 14.f), |
| 442 2, base::TimeDelta()); |
| 443 dispatcher.OnEvent( |
| 444 mojo::Event::From(static_cast<const ui::Event&>(drag_event2))); |
| 445 EXPECT_EQ(&child2, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 446 |
| 447 // Drag again with id 1, child1 should continue to get it. |
| 448 dispatcher.OnEvent( |
| 449 mojo::Event::From(static_cast<const ui::Event&>(drag_event1))); |
| 450 EXPECT_EQ(&child1, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 451 |
| 452 // Release touch id 1, and click on 2. 2 should get it. |
| 453 const ui::TouchEvent touch_release( |
| 454 ui::ET_TOUCH_RELEASED, gfx::PointF(54.f, 55.f), 1, base::TimeDelta()); |
| 455 dispatcher.OnEvent( |
| 456 mojo::Event::From(static_cast<const ui::Event&>(touch_release))); |
| 457 EXPECT_EQ(&child1, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 458 const ui::TouchEvent touch_event3( |
| 459 ui::ET_TOUCH_PRESSED, gfx::PointF(54.f, 55.f), 2, base::TimeDelta()); |
| 460 dispatcher.OnEvent( |
| 461 mojo::Event::From(static_cast<const ui::Event&>(touch_event3))); |
| 462 EXPECT_EQ(&child2, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 463 } |
| 464 |
| 465 TEST(EventDispatcherTest, DestroyWindowWhileGettingEvents) { |
| 466 TestServerWindowDelegate window_delegate; |
| 467 ServerWindow root(&window_delegate, WindowId(1, 2)); |
| 468 window_delegate.set_root_window(&root); |
| 469 root.SetVisible(true); |
| 470 |
| 471 scoped_ptr<ServerWindow> child( |
| 472 new ServerWindow(&window_delegate, WindowId(1, 3))); |
| 473 root.Add(child.get()); |
| 474 child->SetVisible(true); |
| 475 |
| 476 root.SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 477 child->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 478 |
| 479 TestEventDispatcherDelegate event_dispatcher_delegate(&root); |
| 480 EventDispatcher dispatcher(&event_dispatcher_delegate); |
| 481 dispatcher.set_root(&root); |
| 482 |
| 483 // Press on child. |
| 484 const ui::TouchEvent touch_event1( |
| 485 ui::ET_TOUCH_PRESSED, gfx::PointF(12.f, 13.f), 1, base::TimeDelta()); |
| 486 dispatcher.OnEvent( |
| 487 mojo::Event::From(static_cast<const ui::Event&>(touch_event1))); |
| 488 EXPECT_EQ(child.get(), event_dispatcher_delegate.GetAndClearLastTarget()); |
| 489 |
| 490 event_dispatcher_delegate.GetAndClearLastDispatchedEvent(); |
| 491 |
| 492 // Delete child, and continue the drag. Event should not be dispatched. |
| 493 child.reset(); |
| 494 |
| 495 const ui::TouchEvent drag_event1(ui::ET_TOUCH_MOVED, gfx::PointF(53.f, 54.f), |
| 496 1, base::TimeDelta()); |
| 497 dispatcher.OnEvent( |
| 498 mojo::Event::From(static_cast<const ui::Event&>(drag_event1))); |
| 499 EXPECT_EQ(nullptr, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 500 EXPECT_EQ(nullptr, |
| 501 event_dispatcher_delegate.GetAndClearLastDispatchedEvent().get()); |
| 502 } |
| 503 |
345 } // namespace ws | 504 } // namespace ws |
346 } // namespace mus | 505 } // namespace mus |
OLD | NEW |