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.
5 #include "ui/aura/window_targeter.h"
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"
15 // Always returns the same window.
16 class StaticWindowTargeter
: public ui::EventTargeter
{
18 explicit StaticWindowTargeter(aura::Window
* window
)
20 ~StaticWindowTargeter() override
{}
24 ui::EventTarget
* FindTargetForLocatedEvent(ui::EventTarget
* root
,
25 ui::LocatedEvent
* event
) override
{
31 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter
);
34 class WindowTargeterTest
: public test::AuraTestBase
{
36 WindowTargeterTest() {}
37 ~WindowTargeterTest() override
{}
39 Window
* root_window() { return AuraTestBase::root_window(); }
42 gfx::RectF
GetEffectiveVisibleBoundsInRootWindow(Window
* window
) {
43 gfx::RectF bounds
= gfx::Rect(window
->bounds().size());
44 Window
* root
= window
->GetRootWindow();
45 CHECK(window
->layer());
47 gfx::Transform transform
;
48 if (!window
->layer()->GetTargetTransformRelativeTo(root
->layer(), &transform
))
50 transform
.TransformRect(&bounds
);
54 TEST_F(WindowTargeterTest
, Basic
) {
55 test::TestWindowDelegate delegate
;
56 scoped_ptr
<Window
> window(CreateNormalWindow(1, root_window(), &delegate
));
57 Window
* one
= CreateNormalWindow(2, window
.get(), &delegate
);
58 Window
* two
= CreateNormalWindow(3, window
.get(), &delegate
);
60 window
->SetBounds(gfx::Rect(0, 0, 100, 100));
61 one
->SetBounds(gfx::Rect(0, 0, 500, 100));
62 two
->SetBounds(gfx::Rect(501, 0, 500, 1000));
64 root_window()->Show();
66 ui::test::TestEventHandler handler
;
67 one
->AddPreTargetHandler(&handler
);
69 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
,
74 DispatchEventUsingWindowDispatcher(&press
);
75 EXPECT_EQ(1, handler
.num_mouse_events());
78 DispatchEventUsingWindowDispatcher(&press
);
79 EXPECT_EQ(1, handler
.num_mouse_events());
81 one
->RemovePreTargetHandler(&handler
);
84 TEST_F(WindowTargeterTest
, ScopedWindowTargeter
) {
85 test::TestWindowDelegate delegate
;
86 scoped_ptr
<Window
> window(CreateNormalWindow(1, root_window(), &delegate
));
87 Window
* child
= CreateNormalWindow(2, window
.get(), &delegate
);
89 window
->SetBounds(gfx::Rect(30, 30, 100, 100));
90 child
->SetBounds(gfx::Rect(20, 20, 50, 50));
91 root_window()->Show();
93 ui::EventTarget
* root
= root_window();
94 ui::EventTargeter
* targeter
= root
->GetEventTargeter();
96 gfx::Point
event_location(60, 60);
98 ui::MouseEvent
mouse(ui::ET_MOUSE_MOVED
, event_location
, event_location
,
99 ui::EF_NONE
, ui::EF_NONE
);
100 EXPECT_EQ(child
, targeter
->FindTargetForEvent(root
, &mouse
));
103 // Install a targeter on |window| so that the events never reach the child.
104 scoped_ptr
<ScopedWindowTargeter
> scoped_targeter(
105 new ScopedWindowTargeter(window
.get(), scoped_ptr
<ui::EventTargeter
>(
106 new StaticWindowTargeter(window
.get()))));
108 ui::MouseEvent
mouse(ui::ET_MOUSE_MOVED
, event_location
, event_location
,
109 ui::EF_NONE
, ui::EF_NONE
);
110 EXPECT_EQ(window
.get(), targeter
->FindTargetForEvent(root
, &mouse
));
112 scoped_targeter
.reset();
114 ui::MouseEvent
mouse(ui::ET_MOUSE_MOVED
, event_location
, event_location
,
115 ui::EF_NONE
, ui::EF_NONE
);
116 EXPECT_EQ(child
, targeter
->FindTargetForEvent(root
, &mouse
));
120 // Test that ScopedWindowTargeter does not crash if the window for which it
121 // replaces the targeter gets destroyed before it does.
122 TEST_F(WindowTargeterTest
, ScopedWindowTargeterWindowDestroyed
) {
123 test::TestWindowDelegate delegate
;
124 scoped_ptr
<Window
> window(CreateNormalWindow(1, root_window(), &delegate
));
125 scoped_ptr
<ScopedWindowTargeter
> scoped_targeter(
126 new ScopedWindowTargeter(window
.get(), scoped_ptr
<ui::EventTargeter
>(
127 new StaticWindowTargeter(window
.get()))));
130 scoped_targeter
.reset();
135 TEST_F(WindowTargeterTest
, TargetTransformedWindow
) {
136 root_window()->Show();
138 test::TestWindowDelegate delegate
;
139 scoped_ptr
<Window
> window(CreateNormalWindow(2, root_window(), &delegate
));
141 const gfx::Rect
window_bounds(100, 20, 400, 80);
142 window
->SetBounds(window_bounds
);
144 ui::EventTarget
* root_target
= root_window();
145 ui::EventTargeter
* targeter
= root_target
->GetEventTargeter();
146 gfx::Point
event_location(490, 50);
148 ui::MouseEvent
mouse(ui::ET_MOUSE_MOVED
, event_location
, event_location
,
149 ui::EF_NONE
, ui::EF_NONE
);
150 EXPECT_EQ(window
.get(), targeter
->FindTargetForEvent(root_target
, &mouse
));
153 // Scale |window| by 50%. This should move it away from underneath
154 // |event_location|, so an event in that location will not be targeted to it.
155 gfx::Transform transform
;
156 transform
.Scale(0.5, 0.5);
157 window
->SetTransform(transform
);
158 EXPECT_EQ(gfx::RectF(100, 20, 200, 40).ToString(),
159 GetEffectiveVisibleBoundsInRootWindow(window
.get()).ToString());
161 ui::MouseEvent
mouse(ui::ET_MOUSE_MOVED
, event_location
, event_location
,
162 ui::EF_NONE
, ui::EF_NONE
);
163 EXPECT_EQ(root_window(), targeter
->FindTargetForEvent(root_target
, &mouse
));
166 transform
= gfx::Transform();
167 transform
.Translate(200, 10);
168 transform
.Scale(0.5, 0.5);
169 window
->SetTransform(transform
);
170 EXPECT_EQ(gfx::RectF(300, 30, 200, 40).ToString(),
171 GetEffectiveVisibleBoundsInRootWindow(window
.get()).ToString());
173 ui::MouseEvent
mouse(ui::ET_MOUSE_MOVED
, event_location
, event_location
,
174 ui::EF_NONE
, ui::EF_NONE
);
175 EXPECT_EQ(window
.get(), targeter
->FindTargetForEvent(root_target
, &mouse
));