| OLD | NEW |
| (Empty) |
| 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 | |
| 7 #include "ui/aura/scoped_window_targeter.h" | |
| 8 #include "ui/aura/test/aura_test_base.h" | |
| 9 #include "ui/aura/test/test_window_delegate.h" | |
| 10 #include "ui/aura/window.h" | |
| 11 #include "ui/events/test/test_event_handler.h" | |
| 12 | |
| 13 namespace aura { | |
| 14 | |
| 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 | |
| 35 class WindowTargeterTest : public test::AuraTestBase { | |
| 36 public: | |
| 37 WindowTargeterTest() {} | |
| 38 virtual ~WindowTargeterTest() {} | |
| 39 | |
| 40 Window* root_window() { return AuraTestBase::root_window(); } | |
| 41 }; | |
| 42 | |
| 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 | |
| 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 | |
| 67 ui::test::TestEventHandler handler; | |
| 68 one->AddPreTargetHandler(&handler); | |
| 69 | |
| 70 ui::MouseEvent press(ui::ET_MOUSE_PRESSED, | |
| 71 gfx::Point(20, 20), | |
| 72 gfx::Point(20, 20), | |
| 73 ui::EF_NONE, | |
| 74 ui::EF_NONE); | |
| 75 DispatchEventUsingWindowDispatcher(&press); | |
| 76 EXPECT_EQ(1, handler.num_mouse_events()); | |
| 77 | |
| 78 handler.Reset(); | |
| 79 DispatchEventUsingWindowDispatcher(&press); | |
| 80 EXPECT_EQ(1, handler.num_mouse_events()); | |
| 81 | |
| 82 one->RemovePreTargetHandler(&handler); | |
| 83 } | |
| 84 | |
| 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 | |
| 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 | |
| 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 | |
| 180 } // namespace aura | |
| OLD | NEW |