| 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" |
| 11 #include "mojo/converters/input_events/input_events_type_converters.h" | 11 #include "mojo/converters/input_events/input_events_type_converters.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 #include "ui/events/event.h" | 13 #include "ui/events/event.h" |
| 14 | 14 |
| 15 namespace mus { | 15 namespace mus { |
| 16 namespace ws { | 16 namespace ws { |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 class TestEventDispatcherDelegate : public EventDispatcherDelegate { | 19 class TestEventDispatcherDelegate : public EventDispatcherDelegate { |
| 20 public: | 20 public: |
| 21 explicit TestEventDispatcherDelegate(ServerWindow* root) | 21 explicit TestEventDispatcherDelegate(ServerWindow* root) |
| 22 : root_(root), | 22 : root_(root), |
| 23 focused_window_(nullptr), | 23 focused_window_(nullptr), |
| 24 last_target_(nullptr), | 24 last_target_(nullptr), |
| 25 last_accelerator_(0) {} | 25 last_accelerator_(0), |
| 26 last_in_nonclient_area_(false) {} |
| 26 ~TestEventDispatcherDelegate() override {} | 27 ~TestEventDispatcherDelegate() override {} |
| 27 | 28 |
| 28 mojo::EventPtr GetAndClearLastDispatchedEvent() { | 29 mojo::EventPtr GetAndClearLastDispatchedEvent() { |
| 29 return last_dispatched_event_.Pass(); | 30 return last_dispatched_event_.Pass(); |
| 30 } | 31 } |
| 31 | 32 |
| 32 uint32_t GetAndClearLastAccelerator() { | 33 uint32_t GetAndClearLastAccelerator() { |
| 33 uint32_t return_value = last_accelerator_; | 34 uint32_t return_value = last_accelerator_; |
| 34 last_accelerator_ = 0; | 35 last_accelerator_ = 0; |
| 35 return return_value; | 36 return return_value; |
| 36 } | 37 } |
| 37 | 38 |
| 38 ServerWindow* last_target() { return last_target_; } | 39 ServerWindow* last_target() { return last_target_; } |
| 39 | 40 |
| 41 bool GetAndClearLastInNonclientArea() { |
| 42 const bool result = last_in_nonclient_area_; |
| 43 last_in_nonclient_area_ = false; |
| 44 return result; |
| 45 } |
| 46 |
| 40 private: | 47 private: |
| 41 // EventDispatcherDelegate: | 48 // EventDispatcherDelegate: |
| 42 void OnAccelerator(uint32_t accelerator, mojo::EventPtr event) override { | 49 void OnAccelerator(uint32_t accelerator, mojo::EventPtr event) override { |
| 43 EXPECT_EQ(0u, last_accelerator_); | 50 EXPECT_EQ(0u, last_accelerator_); |
| 44 last_accelerator_ = accelerator; | 51 last_accelerator_ = accelerator; |
| 45 } | 52 } |
| 46 void SetFocusedWindowFromEventDispatcher(ServerWindow* window) override { | 53 void SetFocusedWindowFromEventDispatcher(ServerWindow* window) override { |
| 47 focused_window_ = window; | 54 focused_window_ = window; |
| 48 } | 55 } |
| 49 ServerWindow* GetFocusedWindowForEventDispatcher() override { | 56 ServerWindow* GetFocusedWindowForEventDispatcher() override { |
| 50 return focused_window_; | 57 return focused_window_; |
| 51 } | 58 } |
| 52 void DispatchInputEventToWindow(ServerWindow* target, | 59 void DispatchInputEventToWindow(ServerWindow* target, |
| 60 bool in_nonclient_area, |
| 53 mojo::EventPtr event) override { | 61 mojo::EventPtr event) override { |
| 54 last_target_ = target; | 62 last_target_ = target; |
| 55 last_dispatched_event_ = event.Pass(); | 63 last_dispatched_event_ = event.Pass(); |
| 64 last_in_nonclient_area_ = in_nonclient_area; |
| 56 } | 65 } |
| 57 | 66 |
| 58 ServerWindow* root_; | 67 ServerWindow* root_; |
| 59 ServerWindow* focused_window_; | 68 ServerWindow* focused_window_; |
| 60 ServerWindow* last_target_; | 69 ServerWindow* last_target_; |
| 61 mojo::EventPtr last_dispatched_event_; | 70 mojo::EventPtr last_dispatched_event_; |
| 62 uint32_t last_accelerator_; | 71 uint32_t last_accelerator_; |
| 72 bool last_in_nonclient_area_; |
| 63 | 73 |
| 64 DISALLOW_COPY_AND_ASSIGN(TestEventDispatcherDelegate); | 74 DISALLOW_COPY_AND_ASSIGN(TestEventDispatcherDelegate); |
| 65 }; | 75 }; |
| 66 | 76 |
| 67 struct MouseEventTest { | 77 struct MouseEventTest { |
| 68 ui::MouseEvent input_event; | 78 ui::MouseEvent input_event; |
| 69 ServerWindow* expected_target_window; | 79 ServerWindow* expected_target_window; |
| 70 gfx::Point expected_root_location; | 80 gfx::Point expected_root_location; |
| 71 gfx::Point expected_location; | 81 gfx::Point expected_location; |
| 72 }; | 82 }; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 83 ASSERT_EQ(test.expected_target_window, dispatcher_delegate->last_target()) | 93 ASSERT_EQ(test.expected_target_window, dispatcher_delegate->last_target()) |
| 84 << "Test " << i << " failed."; | 94 << "Test " << i << " failed."; |
| 85 | 95 |
| 86 mojo::EventPtr dispatched_event_mojo = | 96 mojo::EventPtr dispatched_event_mojo = |
| 87 dispatcher_delegate->GetAndClearLastDispatchedEvent(); | 97 dispatcher_delegate->GetAndClearLastDispatchedEvent(); |
| 88 ASSERT_TRUE(dispatched_event_mojo.get()) << "Test " << i << " failed."; | 98 ASSERT_TRUE(dispatched_event_mojo.get()) << "Test " << i << " failed."; |
| 89 scoped_ptr<ui::Event> dispatched_event( | 99 scoped_ptr<ui::Event> dispatched_event( |
| 90 dispatched_event_mojo.To<scoped_ptr<ui::Event>>()); | 100 dispatched_event_mojo.To<scoped_ptr<ui::Event>>()); |
| 91 ASSERT_TRUE(dispatched_event.get()) << "Test " << i << " failed."; | 101 ASSERT_TRUE(dispatched_event.get()) << "Test " << i << " failed."; |
| 92 ASSERT_TRUE(dispatched_event->IsMouseEvent()) << "Test " << i << " failed."; | 102 ASSERT_TRUE(dispatched_event->IsMouseEvent()) << "Test " << i << " failed."; |
| 103 EXPECT_FALSE(dispatcher_delegate->GetAndClearLastInNonclientArea()) |
| 104 << "Test " << i << " failed."; |
| 93 ui::MouseEvent* dispatched_mouse_event = | 105 ui::MouseEvent* dispatched_mouse_event = |
| 94 static_cast<ui::MouseEvent*>(dispatched_event.get()); | 106 static_cast<ui::MouseEvent*>(dispatched_event.get()); |
| 95 EXPECT_EQ(test.expected_root_location, | 107 EXPECT_EQ(test.expected_root_location, |
| 96 dispatched_mouse_event->root_location()) | 108 dispatched_mouse_event->root_location()) |
| 97 << "Test " << i << " failed."; | 109 << "Test " << i << " failed."; |
| 98 EXPECT_EQ(test.expected_location, dispatched_mouse_event->location()) | 110 EXPECT_EQ(test.expected_location, dispatched_mouse_event->location()) |
| 99 << "Test " << i << " failed."; | 111 << "Test " << i << " failed."; |
| 100 } | 112 } |
| 101 } | 113 } |
| 102 | 114 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::PointF(50.f, 50.f), | 273 {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::PointF(50.f, 50.f), |
| 262 gfx::PointF(50.f, 50.f), base::TimeDelta(), | 274 gfx::PointF(50.f, 50.f), base::TimeDelta(), |
| 263 ui::EF_LEFT_MOUSE_BUTTON, 0), | 275 ui::EF_LEFT_MOUSE_BUTTON, 0), |
| 264 &child, gfx::Point(50, 50), gfx::Point(40, 40)}, | 276 &child, gfx::Point(50, 50), gfx::Point(40, 40)}, |
| 265 | 277 |
| 266 }; | 278 }; |
| 267 RunMouseEventTests(&dispatcher, &event_dispatcher_delegate, tests, | 279 RunMouseEventTests(&dispatcher, &event_dispatcher_delegate, tests, |
| 268 arraysize(tests)); | 280 arraysize(tests)); |
| 269 } | 281 } |
| 270 | 282 |
| 271 TEST(EventDispatcherTest, MoveWindow) { | 283 TEST(EventDispatcherTest, ClientAreaGoesToOwner) { |
| 272 TestServerWindowDelegate window_delegate; | 284 TestServerWindowDelegate window_delegate; |
| 273 ServerWindow root(&window_delegate, WindowId(1, 2)); | 285 ServerWindow root(&window_delegate, WindowId(1, 2)); |
| 274 window_delegate.set_root_window(&root); | 286 window_delegate.set_root_window(&root); |
| 275 root.SetVisible(true); | 287 root.SetVisible(true); |
| 276 | 288 |
| 277 ServerWindow child(&window_delegate, WindowId(1, 3)); | 289 ServerWindow child(&window_delegate, WindowId(1, 3)); |
| 278 root.Add(&child); | 290 root.Add(&child); |
| 279 child.SetVisible(true); | 291 child.SetVisible(true); |
| 280 | 292 |
| 281 root.SetBounds(gfx::Rect(0, 0, 100, 100)); | 293 root.SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 282 child.SetBounds(gfx::Rect(10, 10, 20, 20)); | 294 child.SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 283 | 295 |
| 284 root.set_is_draggable_window_container(true); | |
| 285 child.SetClientArea(gfx::Rect(5, 5, 10, 10)); | 296 child.SetClientArea(gfx::Rect(5, 5, 10, 10)); |
| 286 | 297 |
| 287 TestEventDispatcherDelegate event_dispatcher_delegate(&root); | 298 TestEventDispatcherDelegate event_dispatcher_delegate(&root); |
| 288 EventDispatcher dispatcher(&event_dispatcher_delegate); | 299 EventDispatcher dispatcher(&event_dispatcher_delegate); |
| 289 dispatcher.set_root(&root); | 300 dispatcher.set_root(&root); |
| 290 | 301 |
| 291 // Start move loop by sending mouse event over non-client area. | 302 // Start move loop by sending mouse event over non-client area. |
| 292 const ui::MouseEvent press_event( | 303 const ui::MouseEvent press_event( |
| 293 ui::ET_MOUSE_PRESSED, gfx::PointF(12.f, 12.f), gfx::PointF(12.f, 12.f), | 304 ui::ET_MOUSE_PRESSED, gfx::PointF(12.f, 12.f), gfx::PointF(12.f, 12.f), |
| 294 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 305 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 295 dispatcher.OnEvent( | 306 dispatcher.OnEvent( |
| 296 mojo::Event::From(static_cast<const ui::Event&>(press_event))); | 307 mojo::Event::From(static_cast<const ui::Event&>(press_event))); |
| 297 | 308 |
| 298 // The event should not have been dispatched to the delegate. | 309 // Events should target child and be in the non-client area. |
| 299 ASSERT_EQ(nullptr, event_dispatcher_delegate.last_target()); | 310 ASSERT_EQ(&child, event_dispatcher_delegate.last_target()); |
| 311 EXPECT_TRUE(event_dispatcher_delegate.GetAndClearLastInNonclientArea()); |
| 300 | 312 |
| 301 // Move the mouse 5,6 pixels and verify window moved. | 313 // Move the mouse 5,6 pixels and target is the same. |
| 302 const ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, gfx::PointF(17.f, 18.f), | 314 const ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, gfx::PointF(17.f, 18.f), |
| 303 gfx::PointF(17.f, 18.f), base::TimeDelta(), | 315 gfx::PointF(17.f, 18.f), base::TimeDelta(), |
| 304 ui::EF_LEFT_MOUSE_BUTTON, 0); | 316 ui::EF_LEFT_MOUSE_BUTTON, 0); |
| 305 dispatcher.OnEvent( | 317 dispatcher.OnEvent( |
| 306 mojo::Event::From(static_cast<const ui::Event&>(move_event))); | 318 mojo::Event::From(static_cast<const ui::Event&>(move_event))); |
| 307 | 319 |
| 308 // The event should not have been dispatched to the delegate. | 320 // Still same target. |
| 309 ASSERT_EQ(nullptr, event_dispatcher_delegate.last_target()); | 321 ASSERT_EQ(&child, event_dispatcher_delegate.last_target()); |
| 310 | 322 EXPECT_TRUE(event_dispatcher_delegate.GetAndClearLastInNonclientArea()); |
| 311 EXPECT_EQ(gfx::Rect(15, 16, 20, 20), child.bounds()); | |
| 312 | 323 |
| 313 // Release the mouse. | 324 // Release the mouse. |
| 314 const ui::MouseEvent release_event( | 325 const ui::MouseEvent release_event( |
| 315 ui::ET_MOUSE_RELEASED, gfx::PointF(17.f, 18.f), gfx::PointF(17.f, 18.f), | 326 ui::ET_MOUSE_RELEASED, gfx::PointF(17.f, 18.f), gfx::PointF(17.f, 18.f), |
| 316 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 327 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 317 dispatcher.OnEvent( | 328 dispatcher.OnEvent( |
| 318 mojo::Event::From(static_cast<const ui::Event&>(release_event))); | 329 mojo::Event::From(static_cast<const ui::Event&>(release_event))); |
| 319 | 330 |
| 320 // The event should not have been dispatched to the delegate. | 331 // The event should not have been dispatched to the delegate. |
| 321 ASSERT_EQ(nullptr, event_dispatcher_delegate.last_target()); | 332 ASSERT_EQ(&child, event_dispatcher_delegate.last_target()); |
| 333 EXPECT_TRUE(event_dispatcher_delegate.GetAndClearLastInNonclientArea()); |
| 322 | 334 |
| 323 // Press in the client area and verify the window gets it. | 335 // Press in the client area and verify target/client area. |
| 324 const ui::MouseEvent press_event2( | 336 const ui::MouseEvent press_event2( |
| 325 ui::ET_MOUSE_PRESSED, gfx::PointF(21.f, 22.f), gfx::PointF(21.f, 22.f), | 337 ui::ET_MOUSE_PRESSED, gfx::PointF(21.f, 22.f), gfx::PointF(21.f, 22.f), |
| 326 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 338 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 327 dispatcher.OnEvent( | 339 dispatcher.OnEvent( |
| 328 mojo::Event::From(static_cast<const ui::Event&>(press_event2))); | 340 mojo::Event::From(static_cast<const ui::Event&>(press_event2))); |
| 329 ASSERT_EQ(&child, event_dispatcher_delegate.last_target()); | 341 ASSERT_EQ(&child, event_dispatcher_delegate.last_target()); |
| 330 } | 342 EXPECT_FALSE(event_dispatcher_delegate.GetAndClearLastInNonclientArea()); |
| 331 | |
| 332 TEST(EventDispatcherTest, DestroyWindowWhileMoving) { | |
| 333 TestServerWindowDelegate window_delegate; | |
| 334 ServerWindow root(&window_delegate, WindowId(1, 2)); | |
| 335 window_delegate.set_root_window(&root); | |
| 336 root.SetVisible(true); | |
| 337 | |
| 338 scoped_ptr<ServerWindow> child( | |
| 339 new ServerWindow(&window_delegate, WindowId(1, 3))); | |
| 340 root.Add(child.get()); | |
| 341 child->SetVisible(true); | |
| 342 | |
| 343 root.SetBounds(gfx::Rect(0, 0, 100, 100)); | |
| 344 child->SetBounds(gfx::Rect(10, 10, 20, 20)); | |
| 345 | |
| 346 root.set_is_draggable_window_container(true); | |
| 347 child->SetClientArea(gfx::Rect(5, 5, 10, 10)); | |
| 348 | |
| 349 TestEventDispatcherDelegate event_dispatcher_delegate(&root); | |
| 350 EventDispatcher dispatcher(&event_dispatcher_delegate); | |
| 351 dispatcher.set_root(&root); | |
| 352 | |
| 353 // Start move loop by sending mouse event over non-client area. | |
| 354 const ui::MouseEvent press_event( | |
| 355 ui::ET_MOUSE_PRESSED, gfx::PointF(12.f, 12.f), gfx::PointF(12.f, 12.f), | |
| 356 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | |
| 357 dispatcher.OnEvent( | |
| 358 mojo::Event::From(static_cast<const ui::Event&>(press_event))); | |
| 359 | |
| 360 // The event should not have been dispatched to the delegate. | |
| 361 ASSERT_EQ(nullptr, event_dispatcher_delegate.last_target()); | |
| 362 | |
| 363 // Destroy the child, no events should be propagated until after the release. | |
| 364 child.reset(); | |
| 365 | |
| 366 const ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, gfx::PointF(17.f, 18.f), | |
| 367 gfx::PointF(17.f, 18.f), base::TimeDelta(), | |
| 368 ui::EF_LEFT_MOUSE_BUTTON, 0); | |
| 369 dispatcher.OnEvent( | |
| 370 mojo::Event::From(static_cast<const ui::Event&>(move_event))); | |
| 371 ASSERT_EQ(nullptr, event_dispatcher_delegate.last_target()); | |
| 372 | |
| 373 const ui::MouseEvent release_event( | |
| 374 ui::ET_MOUSE_RELEASED, gfx::PointF(17.f, 18.f), gfx::PointF(17.f, 18.f), | |
| 375 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | |
| 376 dispatcher.OnEvent( | |
| 377 mojo::Event::From(static_cast<const ui::Event&>(release_event))); | |
| 378 ASSERT_EQ(nullptr, event_dispatcher_delegate.last_target()); | |
| 379 | |
| 380 const ui::MouseEvent press_event2( | |
| 381 ui::ET_MOUSE_PRESSED, gfx::PointF(21.f, 22.f), gfx::PointF(21.f, 22.f), | |
| 382 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | |
| 383 dispatcher.OnEvent( | |
| 384 mojo::Event::From(static_cast<const ui::Event&>(press_event2))); | |
| 385 ASSERT_EQ(&root, event_dispatcher_delegate.last_target()); | |
| 386 } | 343 } |
| 387 | 344 |
| 388 } // namespace ws | 345 } // namespace ws |
| 389 } // namespace mus | 346 } // namespace mus |
| OLD | NEW |