[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 1 | // Copyright (c) 2013 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 "ui/aura/window_targeter.h" |
| 6 | |
[email protected] | 95f642cb | 2014-01-31 01:35:41 | [diff] [blame] | 7 | #include "ui/aura/scoped_window_targeter.h" |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 8 | #include "ui/aura/test/aura_test_base.h" |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 9 | #include "ui/aura/test/test_window_delegate.h" |
| 10 | #include "ui/aura/window.h" |
[email protected] | cd9f71d | 2014-03-20 21:54:21 | [diff] [blame] | 11 | #include "ui/events/test/test_event_handler.h" |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 12 | |
| 13 | namespace aura { |
| 14 | |
[email protected] | 95f642cb | 2014-01-31 01:35:41 | [diff] [blame] | 15 | // Always returns the same window. |
| 16 | class StaticWindowTargeter : public ui::EventTargeter { |
| 17 | public: |
| 18 | explicit StaticWindowTargeter(aura::Window* window) |
| 19 | : window_(window) {} |
| 20 | virtual ~StaticWindowTargeter() {} |
| 21 | |
| 22 | private: |
| 23 | // ui::EventTargeter: |
| 24 | virtual ui::EventTarget* FindTargetForLocatedEvent( |
| 25 | ui::EventTarget* root, |
| 26 | ui::LocatedEvent* event) OVERRIDE { |
| 27 | return window_; |
| 28 | } |
| 29 | |
| 30 | Window* window_; |
| 31 | |
| 32 | DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter); |
| 33 | }; |
| 34 | |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 35 | class WindowTargeterTest : public test::AuraTestBase { |
| 36 | public: |
| 37 | WindowTargeterTest() {} |
| 38 | virtual ~WindowTargeterTest() {} |
| 39 | |
| 40 | Window* root_window() { return AuraTestBase::root_window(); } |
| 41 | }; |
| 42 | |
[email protected] | e185085 | 2014-02-20 16:11:21 | [diff] [blame] | 43 | gfx::RectF GetEffectiveVisibleBoundsInRootWindow(Window* window) { |
| 44 | gfx::RectF bounds = gfx::Rect(window->bounds().size()); |
| 45 | Window* root = window->GetRootWindow(); |
| 46 | CHECK(window->layer()); |
| 47 | CHECK(root->layer()); |
| 48 | gfx::Transform transform; |
| 49 | if (!window->layer()->GetTargetTransformRelativeTo(root->layer(), &transform)) |
| 50 | return gfx::RectF(); |
| 51 | transform.TransformRect(&bounds); |
| 52 | return bounds; |
| 53 | } |
| 54 | |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 55 | TEST_F(WindowTargeterTest, Basic) { |
| 56 | test::TestWindowDelegate delegate; |
| 57 | scoped_ptr<Window> window(CreateNormalWindow(1, root_window(), &delegate)); |
| 58 | Window* one = CreateNormalWindow(2, window.get(), &delegate); |
| 59 | Window* two = CreateNormalWindow(3, window.get(), &delegate); |
| 60 | |
| 61 | window->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 62 | one->SetBounds(gfx::Rect(0, 0, 500, 100)); |
| 63 | two->SetBounds(gfx::Rect(501, 0, 500, 1000)); |
| 64 | |
| 65 | root_window()->Show(); |
| 66 | |
[email protected] | cd9f71d | 2014-03-20 21:54:21 | [diff] [blame] | 67 | ui::test::TestEventHandler handler; |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 68 | one->AddPreTargetHandler(&handler); |
| 69 | |
| 70 | ui::MouseEvent press(ui::ET_MOUSE_PRESSED, |
| 71 | gfx::Point(20, 20), |
| 72 | gfx::Point(20, 20), |
[email protected] | f58bbf1c | 2013-12-17 21:20:50 | [diff] [blame] | 73 | ui::EF_NONE, |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 74 | ui::EF_NONE); |
[email protected] | 5da34bd | 2014-01-31 08:24:49 | [diff] [blame] | 75 | DispatchEventUsingWindowDispatcher(&press); |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 76 | EXPECT_EQ(1, handler.num_mouse_events()); |
| 77 | |
| 78 | handler.Reset(); |
[email protected] | 5da34bd | 2014-01-31 08:24:49 | [diff] [blame] | 79 | DispatchEventUsingWindowDispatcher(&press); |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 80 | EXPECT_EQ(1, handler.num_mouse_events()); |
| 81 | |
| 82 | one->RemovePreTargetHandler(&handler); |
| 83 | } |
| 84 | |
[email protected] | 95f642cb | 2014-01-31 01:35:41 | [diff] [blame] | 85 | TEST_F(WindowTargeterTest, ScopedWindowTargeter) { |
| 86 | test::TestWindowDelegate delegate; |
| 87 | scoped_ptr<Window> window(CreateNormalWindow(1, root_window(), &delegate)); |
| 88 | Window* child = CreateNormalWindow(2, window.get(), &delegate); |
| 89 | |
| 90 | window->SetBounds(gfx::Rect(30, 30, 100, 100)); |
| 91 | child->SetBounds(gfx::Rect(20, 20, 50, 50)); |
| 92 | root_window()->Show(); |
| 93 | |
| 94 | ui::EventTarget* root = root_window(); |
| 95 | ui::EventTargeter* targeter = root->GetEventTargeter(); |
| 96 | |
| 97 | gfx::Point event_location(60, 60); |
| 98 | { |
| 99 | ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location, |
| 100 | ui::EF_NONE, ui::EF_NONE); |
| 101 | EXPECT_EQ(child, targeter->FindTargetForEvent(root, &mouse)); |
| 102 | } |
| 103 | |
| 104 | // Install a targeter on |window| so that the events never reach the child. |
| 105 | scoped_ptr<ScopedWindowTargeter> scoped_targeter( |
| 106 | new ScopedWindowTargeter(window.get(), scoped_ptr<ui::EventTargeter>( |
| 107 | new StaticWindowTargeter(window.get())))); |
| 108 | { |
| 109 | ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location, |
| 110 | ui::EF_NONE, ui::EF_NONE); |
| 111 | EXPECT_EQ(window.get(), targeter->FindTargetForEvent(root, &mouse)); |
| 112 | } |
| 113 | scoped_targeter.reset(); |
| 114 | { |
| 115 | ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location, |
| 116 | ui::EF_NONE, ui::EF_NONE); |
| 117 | EXPECT_EQ(child, targeter->FindTargetForEvent(root, &mouse)); |
| 118 | } |
| 119 | } |
| 120 | |
[email protected] | 9f3f286 | 2014-07-26 18:32:50 | [diff] [blame] | 121 | // Test that ScopedWindowTargeter does not crash if the window for which it |
| 122 | // replaces the targeter gets destroyed before it does. |
| 123 | TEST_F(WindowTargeterTest, ScopedWindowTargeterWindowDestroyed) { |
| 124 | test::TestWindowDelegate delegate; |
| 125 | scoped_ptr<Window> window(CreateNormalWindow(1, root_window(), &delegate)); |
| 126 | scoped_ptr<ScopedWindowTargeter> scoped_targeter( |
| 127 | new ScopedWindowTargeter(window.get(), scoped_ptr<ui::EventTargeter>( |
| 128 | new StaticWindowTargeter(window.get())))); |
| 129 | |
| 130 | window.reset(); |
| 131 | scoped_targeter.reset(); |
| 132 | |
| 133 | // We did not crash! |
| 134 | } |
| 135 | |
[email protected] | e185085 | 2014-02-20 16:11:21 | [diff] [blame] | 136 | TEST_F(WindowTargeterTest, TargetTransformedWindow) { |
| 137 | root_window()->Show(); |
| 138 | |
| 139 | test::TestWindowDelegate delegate; |
| 140 | scoped_ptr<Window> window(CreateNormalWindow(2, root_window(), &delegate)); |
| 141 | |
| 142 | const gfx::Rect window_bounds(100, 20, 400, 80); |
| 143 | window->SetBounds(window_bounds); |
| 144 | |
| 145 | ui::EventTarget* root_target = root_window(); |
| 146 | ui::EventTargeter* targeter = root_target->GetEventTargeter(); |
| 147 | gfx::Point event_location(490, 50); |
| 148 | { |
| 149 | ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location, |
| 150 | ui::EF_NONE, ui::EF_NONE); |
| 151 | EXPECT_EQ(window.get(), targeter->FindTargetForEvent(root_target, &mouse)); |
| 152 | } |
| 153 | |
| 154 | // Scale |window| by 50%. This should move it away from underneath |
| 155 | // |event_location|, so an event in that location will not be targeted to it. |
| 156 | gfx::Transform transform; |
| 157 | transform.Scale(0.5, 0.5); |
| 158 | window->SetTransform(transform); |
| 159 | EXPECT_EQ(gfx::RectF(100, 20, 200, 40).ToString(), |
| 160 | GetEffectiveVisibleBoundsInRootWindow(window.get()).ToString()); |
| 161 | { |
| 162 | ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location, |
| 163 | ui::EF_NONE, ui::EF_NONE); |
| 164 | EXPECT_EQ(root_window(), targeter->FindTargetForEvent(root_target, &mouse)); |
| 165 | } |
| 166 | |
| 167 | transform = gfx::Transform(); |
| 168 | transform.Translate(200, 10); |
| 169 | transform.Scale(0.5, 0.5); |
| 170 | window->SetTransform(transform); |
| 171 | EXPECT_EQ(gfx::RectF(300, 30, 200, 40).ToString(), |
| 172 | GetEffectiveVisibleBoundsInRootWindow(window.get()).ToString()); |
| 173 | { |
| 174 | ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location, |
| 175 | ui::EF_NONE, ui::EF_NONE); |
| 176 | EXPECT_EQ(window.get(), targeter->FindTargetForEvent(root_target, &mouse)); |
| 177 | } |
| 178 | } |
| 179 | |
[email protected] | 8daeb41 | 2013-12-06 23:55:51 | [diff] [blame] | 180 | } // namespace aura |