blob: 86bd8d804da87ba7fddcd8fe1499db1175801425 [file] [log] [blame]
[email protected]8daeb412013-12-06 23:55:511// 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]95f642cb2014-01-31 01:35:417#include "ui/aura/scoped_window_targeter.h"
[email protected]8daeb412013-12-06 23:55:518#include "ui/aura/test/aura_test_base.h"
[email protected]8daeb412013-12-06 23:55:519#include "ui/aura/test/test_window_delegate.h"
10#include "ui/aura/window.h"
[email protected]cd9f71d2014-03-20 21:54:2111#include "ui/events/test/test_event_handler.h"
[email protected]8daeb412013-12-06 23:55:5112
13namespace aura {
14
[email protected]95f642cb2014-01-31 01:35:4115// Always returns the same window.
16class 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]8daeb412013-12-06 23:55:5135class WindowTargeterTest : public test::AuraTestBase {
36 public:
37 WindowTargeterTest() {}
38 virtual ~WindowTargeterTest() {}
39
40 Window* root_window() { return AuraTestBase::root_window(); }
41};
42
[email protected]e1850852014-02-20 16:11:2143gfx::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]8daeb412013-12-06 23:55:5155TEST_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]cd9f71d2014-03-20 21:54:2167 ui::test::TestEventHandler handler;
[email protected]8daeb412013-12-06 23:55:5168 one->AddPreTargetHandler(&handler);
69
70 ui::MouseEvent press(ui::ET_MOUSE_PRESSED,
71 gfx::Point(20, 20),
72 gfx::Point(20, 20),
[email protected]f58bbf1c2013-12-17 21:20:5073 ui::EF_NONE,
[email protected]8daeb412013-12-06 23:55:5174 ui::EF_NONE);
[email protected]5da34bd2014-01-31 08:24:4975 DispatchEventUsingWindowDispatcher(&press);
[email protected]8daeb412013-12-06 23:55:5176 EXPECT_EQ(1, handler.num_mouse_events());
77
78 handler.Reset();
[email protected]5da34bd2014-01-31 08:24:4979 DispatchEventUsingWindowDispatcher(&press);
[email protected]8daeb412013-12-06 23:55:5180 EXPECT_EQ(1, handler.num_mouse_events());
81
82 one->RemovePreTargetHandler(&handler);
83}
84
[email protected]95f642cb2014-01-31 01:35:4185TEST_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]9f3f2862014-07-26 18:32:50121// Test that ScopedWindowTargeter does not crash if the window for which it
122// replaces the targeter gets destroyed before it does.
123TEST_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]e1850852014-02-20 16:11:21136TEST_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]8daeb412013-12-06 23:55:51180} // namespace aura