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 virtual ~StaticWindowTargeter() {}
24 virtual ui::EventTarget
* FindTargetForLocatedEvent(
25 ui::EventTarget
* root
,
26 ui::LocatedEvent
* event
) OVERRIDE
{
32 DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter
);
35 class WindowTargeterTest
: public test::AuraTestBase
{
37 WindowTargeterTest() {}
38 virtual ~WindowTargeterTest() {}
40 Window
* root_window() { return AuraTestBase::root_window(); }
43 gfx::RectF
GetEffectiveVisibleBoundsInRootWindow(Window
* window
) {
44 gfx::RectF bounds
= gfx::Rect(window
->bounds().size());
45 Window
* root
= window
->GetRootWindow();
46 CHECK(window
->layer());
48 gfx::Transform transform
;
49 if (!window
->layer()->GetTargetTransformRelativeTo(root
->layer(), &transform
))
51 transform
.TransformRect(&bounds
);
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
);
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));
65 root_window()->Show();
67 ui::test::TestEventHandler handler
;
68 one
->AddPreTargetHandler(&handler
);
70 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
,
75 DispatchEventUsingWindowDispatcher(&press
);
76 EXPECT_EQ(1, handler
.num_mouse_events());
79 DispatchEventUsingWindowDispatcher(&press
);
80 EXPECT_EQ(1, handler
.num_mouse_events());
82 one
->RemovePreTargetHandler(&handler
);
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
);
90 window
->SetBounds(gfx::Rect(30, 30, 100, 100));
91 child
->SetBounds(gfx::Rect(20, 20, 50, 50));
92 root_window()->Show();
94 ui::EventTarget
* root
= root_window();
95 ui::EventTargeter
* targeter
= root
->GetEventTargeter();
97 gfx::Point
event_location(60, 60);
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
));
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()))));
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
));
113 scoped_targeter
.reset();
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
));
121 TEST_F(WindowTargeterTest
, TargetTransformedWindow
) {
122 root_window()->Show();
124 test::TestWindowDelegate delegate
;
125 scoped_ptr
<Window
> window(CreateNormalWindow(2, root_window(), &delegate
));
127 const gfx::Rect
window_bounds(100, 20, 400, 80);
128 window
->SetBounds(window_bounds
);
130 ui::EventTarget
* root_target
= root_window();
131 ui::EventTargeter
* targeter
= root_target
->GetEventTargeter();
132 gfx::Point
event_location(490, 50);
134 ui::MouseEvent
mouse(ui::ET_MOUSE_MOVED
, event_location
, event_location
,
135 ui::EF_NONE
, ui::EF_NONE
);
136 EXPECT_EQ(window
.get(), targeter
->FindTargetForEvent(root_target
, &mouse
));
139 // Scale |window| by 50%. This should move it away from underneath
140 // |event_location|, so an event in that location will not be targeted to it.
141 gfx::Transform transform
;
142 transform
.Scale(0.5, 0.5);
143 window
->SetTransform(transform
);
144 EXPECT_EQ(gfx::RectF(100, 20, 200, 40).ToString(),
145 GetEffectiveVisibleBoundsInRootWindow(window
.get()).ToString());
147 ui::MouseEvent
mouse(ui::ET_MOUSE_MOVED
, event_location
, event_location
,
148 ui::EF_NONE
, ui::EF_NONE
);
149 EXPECT_EQ(root_window(), targeter
->FindTargetForEvent(root_target
, &mouse
));
152 transform
= gfx::Transform();
153 transform
.Translate(200, 10);
154 transform
.Scale(0.5, 0.5);
155 window
->SetTransform(transform
);
156 EXPECT_EQ(gfx::RectF(300, 30, 200, 40).ToString(),
157 GetEffectiveVisibleBoundsInRootWindow(window
.get()).ToString());
159 ui::MouseEvent
mouse(ui::ET_MOUSE_MOVED
, event_location
, event_location
,
160 ui::EF_NONE
, ui::EF_NONE
);
161 EXPECT_EQ(window
.get(), targeter
->FindTargetForEvent(root_target
, &mouse
));