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 mojom::EventPtr GetAndClearLastDispatchedEvent() { | 29 mojom::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, mojom::EventPtr event) override { | 60 void OnAccelerator(uint32_t accelerator, mojom::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 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 // Press in the client area and verify target/client area. | 345 // Press in the client area and verify target/client area. |
335 const ui::MouseEvent press_event2( | 346 const ui::MouseEvent press_event2( |
336 ui::ET_MOUSE_PRESSED, gfx::PointF(21.f, 22.f), gfx::PointF(21.f, 22.f), | 347 ui::ET_MOUSE_PRESSED, gfx::PointF(21.f, 22.f), gfx::PointF(21.f, 22.f), |
337 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 348 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
338 dispatcher.OnEvent( | 349 dispatcher.OnEvent( |
339 mojom::Event::From(static_cast<const ui::Event&>(press_event2))); | 350 mojom::Event::From(static_cast<const ui::Event&>(press_event2))); |
340 ASSERT_EQ(&child, event_dispatcher_delegate.last_target()); | 351 ASSERT_EQ(&child, event_dispatcher_delegate.last_target()); |
341 EXPECT_FALSE(event_dispatcher_delegate.GetAndClearLastInNonclientArea()); | 352 EXPECT_FALSE(event_dispatcher_delegate.GetAndClearLastInNonclientArea()); |
342 } | 353 } |
343 | 354 |
| 355 TEST(EventDispatcherTest, DontFocusOnSecondDown) { |
| 356 TestServerWindowDelegate window_delegate; |
| 357 ServerWindow root(&window_delegate, WindowId(1, 2)); |
| 358 window_delegate.set_root_window(&root); |
| 359 root.SetVisible(true); |
| 360 |
| 361 ServerWindow child1(&window_delegate, WindowId(1, 3)); |
| 362 root.Add(&child1); |
| 363 child1.SetVisible(true); |
| 364 |
| 365 ServerWindow child2(&window_delegate, WindowId(1, 4)); |
| 366 root.Add(&child2); |
| 367 child2.SetVisible(true); |
| 368 |
| 369 root.SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 370 child1.SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 371 child2.SetBounds(gfx::Rect(50, 51, 11, 12)); |
| 372 |
| 373 TestEventDispatcherDelegate event_dispatcher_delegate(&root); |
| 374 EventDispatcher dispatcher(&event_dispatcher_delegate); |
| 375 dispatcher.set_root(&root); |
| 376 |
| 377 // Press on child1. First press event should change focus. |
| 378 const ui::MouseEvent press_event( |
| 379 ui::ET_MOUSE_PRESSED, gfx::PointF(12.f, 12.f), gfx::PointF(12.f, 12.f), |
| 380 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 381 dispatcher.OnEvent( |
| 382 mojom::Event::From(static_cast<const ui::Event&>(press_event))); |
| 383 EXPECT_EQ(&child1, event_dispatcher_delegate.last_target()); |
| 384 EXPECT_EQ(&child1, event_dispatcher_delegate.GetAndClearLastFocusedWindow()); |
| 385 |
| 386 // Press (with a different pointer id) on child2. Event should go to child2, |
| 387 // but focus should not change. |
| 388 const ui::TouchEvent touch_event( |
| 389 ui::ET_TOUCH_PRESSED, gfx::PointF(53.f, 54.f), 2, base::TimeDelta()); |
| 390 dispatcher.OnEvent( |
| 391 mojom::Event::From(static_cast<const ui::Event&>(touch_event))); |
| 392 EXPECT_EQ(&child2, event_dispatcher_delegate.last_target()); |
| 393 EXPECT_EQ(nullptr, event_dispatcher_delegate.GetAndClearLastFocusedWindow()); |
| 394 } |
| 395 |
| 396 TEST(EventDispatcherTest, TwoPointersActive) { |
| 397 TestServerWindowDelegate window_delegate; |
| 398 ServerWindow root(&window_delegate, WindowId(1, 2)); |
| 399 window_delegate.set_root_window(&root); |
| 400 root.SetVisible(true); |
| 401 |
| 402 ServerWindow child1(&window_delegate, WindowId(1, 3)); |
| 403 root.Add(&child1); |
| 404 child1.SetVisible(true); |
| 405 |
| 406 ServerWindow child2(&window_delegate, WindowId(1, 4)); |
| 407 root.Add(&child2); |
| 408 child2.SetVisible(true); |
| 409 |
| 410 root.SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 411 child1.SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 412 child2.SetBounds(gfx::Rect(50, 51, 11, 12)); |
| 413 |
| 414 TestEventDispatcherDelegate event_dispatcher_delegate(&root); |
| 415 EventDispatcher dispatcher(&event_dispatcher_delegate); |
| 416 dispatcher.set_root(&root); |
| 417 |
| 418 // Press on child1. |
| 419 const ui::TouchEvent touch_event1( |
| 420 ui::ET_TOUCH_PRESSED, gfx::PointF(12.f, 13.f), 1, base::TimeDelta()); |
| 421 dispatcher.OnEvent( |
| 422 mojom::Event::From(static_cast<const ui::Event&>(touch_event1))); |
| 423 EXPECT_EQ(&child1, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 424 |
| 425 // Drag over child2, child1 should get the drag. |
| 426 const ui::TouchEvent drag_event1(ui::ET_TOUCH_MOVED, gfx::PointF(53.f, 54.f), |
| 427 1, base::TimeDelta()); |
| 428 dispatcher.OnEvent( |
| 429 mojom::Event::From(static_cast<const ui::Event&>(drag_event1))); |
| 430 EXPECT_EQ(&child1, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 431 |
| 432 // Press on child2 with a different touch id. |
| 433 const ui::TouchEvent touch_event2( |
| 434 ui::ET_TOUCH_PRESSED, gfx::PointF(54.f, 55.f), 2, base::TimeDelta()); |
| 435 dispatcher.OnEvent( |
| 436 mojom::Event::From(static_cast<const ui::Event&>(touch_event2))); |
| 437 EXPECT_EQ(&child2, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 438 |
| 439 // Drag over child1 with id 2, child2 should continue to get the drag. |
| 440 const ui::TouchEvent drag_event2(ui::ET_TOUCH_MOVED, gfx::PointF(13.f, 14.f), |
| 441 2, base::TimeDelta()); |
| 442 dispatcher.OnEvent( |
| 443 mojom::Event::From(static_cast<const ui::Event&>(drag_event2))); |
| 444 EXPECT_EQ(&child2, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 445 |
| 446 // Drag again with id 1, child1 should continue to get it. |
| 447 dispatcher.OnEvent( |
| 448 mojom::Event::From(static_cast<const ui::Event&>(drag_event1))); |
| 449 EXPECT_EQ(&child1, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 450 |
| 451 // Release touch id 1, and click on 2. 2 should get it. |
| 452 const ui::TouchEvent touch_release( |
| 453 ui::ET_TOUCH_RELEASED, gfx::PointF(54.f, 55.f), 1, base::TimeDelta()); |
| 454 dispatcher.OnEvent( |
| 455 mojom::Event::From(static_cast<const ui::Event&>(touch_release))); |
| 456 EXPECT_EQ(&child1, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 457 const ui::TouchEvent touch_event3( |
| 458 ui::ET_TOUCH_PRESSED, gfx::PointF(54.f, 55.f), 2, base::TimeDelta()); |
| 459 dispatcher.OnEvent( |
| 460 mojom::Event::From(static_cast<const ui::Event&>(touch_event3))); |
| 461 EXPECT_EQ(&child2, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 462 } |
| 463 |
| 464 TEST(EventDispatcherTest, DestroyWindowWhileGettingEvents) { |
| 465 TestServerWindowDelegate window_delegate; |
| 466 ServerWindow root(&window_delegate, WindowId(1, 2)); |
| 467 window_delegate.set_root_window(&root); |
| 468 root.SetVisible(true); |
| 469 |
| 470 scoped_ptr<ServerWindow> child( |
| 471 new ServerWindow(&window_delegate, WindowId(1, 3))); |
| 472 root.Add(child.get()); |
| 473 child->SetVisible(true); |
| 474 |
| 475 root.SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 476 child->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 477 |
| 478 TestEventDispatcherDelegate event_dispatcher_delegate(&root); |
| 479 EventDispatcher dispatcher(&event_dispatcher_delegate); |
| 480 dispatcher.set_root(&root); |
| 481 |
| 482 // Press on child. |
| 483 const ui::TouchEvent touch_event1( |
| 484 ui::ET_TOUCH_PRESSED, gfx::PointF(12.f, 13.f), 1, base::TimeDelta()); |
| 485 dispatcher.OnEvent( |
| 486 mojom::Event::From(static_cast<const ui::Event&>(touch_event1))); |
| 487 EXPECT_EQ(child.get(), event_dispatcher_delegate.GetAndClearLastTarget()); |
| 488 |
| 489 event_dispatcher_delegate.GetAndClearLastDispatchedEvent(); |
| 490 |
| 491 // Delete child, and continue the drag. Event should not be dispatched. |
| 492 child.reset(); |
| 493 |
| 494 const ui::TouchEvent drag_event1(ui::ET_TOUCH_MOVED, gfx::PointF(53.f, 54.f), |
| 495 1, base::TimeDelta()); |
| 496 dispatcher.OnEvent( |
| 497 mojom::Event::From(static_cast<const ui::Event&>(drag_event1))); |
| 498 EXPECT_EQ(nullptr, event_dispatcher_delegate.GetAndClearLastTarget()); |
| 499 EXPECT_EQ(nullptr, |
| 500 event_dispatcher_delegate.GetAndClearLastDispatchedEvent().get()); |
| 501 } |
| 502 |
344 } // namespace ws | 503 } // namespace ws |
345 } // namespace mus | 504 } // namespace mus |
OLD | NEW |