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.
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/events/event.h"
9 #include "ui/events/event_targeter.h"
10 #include "ui/events/test/events_test_utils.h"
11 #include "ui/events/test/test_event_handler.h"
12 #include "ui/events/test/test_event_processor.h"
13 #include "ui/events/test/test_event_target.h"
15 typedef std::vector
<std::string
> HandlerSequenceRecorder
;
20 class EventProcessorTest
: public testing::Test
{
22 EventProcessorTest() {}
23 virtual ~EventProcessorTest() {}
26 virtual void SetUp() OVERRIDE
{
27 processor_
.SetRoot(scoped_ptr
<EventTarget
>(new TestEventTarget()));
28 root()->SetEventTargeter(make_scoped_ptr(new EventTargeter()));
31 TestEventTarget
* root() {
32 return static_cast<TestEventTarget
*>(processor_
.GetRootTarget());
35 void DispatchEvent(Event
* event
) {
36 processor_
.OnEventFromSource(event
);
40 TestEventProcessor processor_
;
42 DISALLOW_COPY_AND_ASSIGN(EventProcessorTest
);
45 TEST_F(EventProcessorTest
, Basic
) {
46 scoped_ptr
<TestEventTarget
> child(new TestEventTarget());
47 root()->AddChild(child
.Pass());
49 MouseEvent
mouse(ET_MOUSE_MOVED
, gfx::Point(10, 10), gfx::Point(10, 10),
51 DispatchEvent(&mouse
);
52 EXPECT_TRUE(root()->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED
));
53 EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED
));
55 root()->RemoveChild(root()->child_at(0));
56 DispatchEvent(&mouse
);
57 EXPECT_TRUE(root()->DidReceiveEvent(ET_MOUSE_MOVED
));
61 class BoundsEventTargeter
: public EventTargeter
{
63 virtual ~BoundsEventTargeter() {}
66 virtual bool SubtreeShouldBeExploredForEvent(
67 EventTarget
* target
, const LocatedEvent
& event
) OVERRIDE
{
68 T
* t
= static_cast<T
*>(target
);
69 return (t
->bounds().Contains(event
.location()));
73 class BoundsTestTarget
: public TestEventTarget
{
76 virtual ~BoundsTestTarget() {}
78 void set_bounds(gfx::Rect rect
) { bounds_
= rect
; }
79 gfx::Rect
bounds() const { return bounds_
; }
81 static void ConvertPointToTarget(BoundsTestTarget
* source
,
82 BoundsTestTarget
* target
,
83 gfx::Point
* location
) {
85 if (source
->Contains(target
)) {
86 for (; target
&& target
!= source
;
87 target
= static_cast<BoundsTestTarget
*>(target
->parent())) {
88 vector
+= target
->bounds().OffsetFromOrigin();
91 } else if (target
->Contains(source
)) {
92 for (; source
&& source
!= target
;
93 source
= static_cast<BoundsTestTarget
*>(source
->parent())) {
94 vector
+= source
->bounds().OffsetFromOrigin();
104 virtual void ConvertEventToTarget(EventTarget
* target
,
105 LocatedEvent
* event
) OVERRIDE
{
106 event
->ConvertLocationToTarget(this,
107 static_cast<BoundsTestTarget
*>(target
));
112 DISALLOW_COPY_AND_ASSIGN(BoundsTestTarget
);
115 TEST_F(EventProcessorTest
, Bounds
) {
116 scoped_ptr
<BoundsTestTarget
> parent(new BoundsTestTarget());
117 scoped_ptr
<BoundsTestTarget
> child(new BoundsTestTarget());
118 scoped_ptr
<BoundsTestTarget
> grandchild(new BoundsTestTarget());
120 parent
->set_bounds(gfx::Rect(0, 0, 30, 30));
121 child
->set_bounds(gfx::Rect(5, 5, 20, 20));
122 grandchild
->set_bounds(gfx::Rect(5, 5, 5, 5));
124 child
->AddChild(scoped_ptr
<TestEventTarget
>(grandchild
.Pass()));
125 parent
->AddChild(scoped_ptr
<TestEventTarget
>(child
.Pass()));
126 root()->AddChild(scoped_ptr
<TestEventTarget
>(parent
.Pass()));
128 ASSERT_EQ(1u, root()->child_count());
129 ASSERT_EQ(1u, root()->child_at(0)->child_count());
130 ASSERT_EQ(1u, root()->child_at(0)->child_at(0)->child_count());
132 TestEventTarget
* parent_r
= root()->child_at(0);
133 TestEventTarget
* child_r
= parent_r
->child_at(0);
134 TestEventTarget
* grandchild_r
= child_r
->child_at(0);
136 // Dispatch a mouse event that falls on the parent, but not on the child. When
137 // the default event-targeter used, the event will still reach |grandchild|,
138 // because the default targeter does not look at the bounds.
139 MouseEvent
mouse(ET_MOUSE_MOVED
, gfx::Point(1, 1), gfx::Point(1, 1), EF_NONE
,
141 DispatchEvent(&mouse
);
142 EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED
));
143 EXPECT_FALSE(parent_r
->DidReceiveEvent(ET_MOUSE_MOVED
));
144 EXPECT_FALSE(child_r
->DidReceiveEvent(ET_MOUSE_MOVED
));
145 EXPECT_TRUE(grandchild_r
->DidReceiveEvent(ET_MOUSE_MOVED
));
146 grandchild_r
->ResetReceivedEvents();
148 // Now install a targeter on the parent that looks at the bounds and makes
149 // sure the event reaches the target only if the location of the event within
150 // the bounds of the target.
151 MouseEvent
mouse2(ET_MOUSE_MOVED
, gfx::Point(1, 1), gfx::Point(1, 1), EF_NONE
,
153 parent_r
->SetEventTargeter(scoped_ptr
<EventTargeter
>(
154 new BoundsEventTargeter
<BoundsTestTarget
>()));
155 DispatchEvent(&mouse2
);
156 EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED
));
157 EXPECT_TRUE(parent_r
->DidReceiveEvent(ET_MOUSE_MOVED
));
158 EXPECT_FALSE(child_r
->DidReceiveEvent(ET_MOUSE_MOVED
));
159 EXPECT_FALSE(grandchild_r
->DidReceiveEvent(ET_MOUSE_MOVED
));
160 parent_r
->ResetReceivedEvents();
162 MouseEvent
second(ET_MOUSE_MOVED
, gfx::Point(12, 12), gfx::Point(12, 12),
164 DispatchEvent(&second
);
165 EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED
));
166 EXPECT_FALSE(parent_r
->DidReceiveEvent(ET_MOUSE_MOVED
));
167 EXPECT_FALSE(child_r
->DidReceiveEvent(ET_MOUSE_MOVED
));
168 EXPECT_TRUE(grandchild_r
->DidReceiveEvent(ET_MOUSE_MOVED
));
171 class IgnoreEventTargeter
: public EventTargeter
{
173 IgnoreEventTargeter() {}
174 virtual ~IgnoreEventTargeter() {}
178 virtual bool SubtreeShouldBeExploredForEvent(
179 EventTarget
* target
, const LocatedEvent
& event
) OVERRIDE
{
184 // Verifies that the EventTargeter installed on an EventTarget can dictate
185 // whether the target itself can process an event.
186 TEST_F(EventProcessorTest
, TargeterChecksOwningEventTarget
) {
187 scoped_ptr
<TestEventTarget
> child(new TestEventTarget());
188 root()->AddChild(child
.Pass());
190 MouseEvent
mouse(ET_MOUSE_MOVED
, gfx::Point(10, 10), gfx::Point(10, 10),
192 DispatchEvent(&mouse
);
193 EXPECT_TRUE(root()->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED
));
194 EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED
));
195 root()->child_at(0)->ResetReceivedEvents();
197 // Install an event handler on |child| which always prevents the target from
199 root()->child_at(0)->SetEventTargeter(
200 scoped_ptr
<EventTargeter
>(new IgnoreEventTargeter()));
201 MouseEvent
mouse2(ET_MOUSE_MOVED
, gfx::Point(10, 10), gfx::Point(10, 10),
203 DispatchEvent(&mouse2
);
204 EXPECT_FALSE(root()->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED
));
205 EXPECT_TRUE(root()->DidReceiveEvent(ET_MOUSE_MOVED
));
208 // An EventTargeter which is used to allow a bubbling behaviour in event
209 // dispatch: if an event is not handled after being dispatched to its
210 // initial target, the event is dispatched to the next-best target as
211 // specified by FindNextBestTarget().
212 class BubblingEventTargeter
: public EventTargeter
{
214 explicit BubblingEventTargeter(TestEventTarget
* initial_target
)
215 : initial_target_(initial_target
) {}
216 virtual ~BubblingEventTargeter() {}
220 virtual EventTarget
* FindTargetForEvent(EventTarget
* root
,
221 Event
* event
) OVERRIDE
{
222 return initial_target_
;
225 virtual EventTarget
* FindNextBestTarget(EventTarget
* previous_target
,
226 Event
* event
) OVERRIDE
{
227 return previous_target
->GetParentTarget();
230 TestEventTarget
* initial_target_
;
232 DISALLOW_COPY_AND_ASSIGN(BubblingEventTargeter
);
235 // Tests that unhandled events are correctly dispatched to the next-best
236 // target as decided by the BubblingEventTargeter.
237 TEST_F(EventProcessorTest
, DispatchToNextBestTarget
) {
238 scoped_ptr
<TestEventTarget
> child(new TestEventTarget());
239 scoped_ptr
<TestEventTarget
> grandchild(new TestEventTarget());
241 root()->SetEventTargeter(
242 scoped_ptr
<EventTargeter
>(new BubblingEventTargeter(grandchild
.get())));
243 child
->AddChild(grandchild
.Pass());
244 root()->AddChild(child
.Pass());
246 ASSERT_EQ(1u, root()->child_count());
247 ASSERT_EQ(1u, root()->child_at(0)->child_count());
248 ASSERT_EQ(0u, root()->child_at(0)->child_at(0)->child_count());
250 TestEventTarget
* child_r
= root()->child_at(0);
251 TestEventTarget
* grandchild_r
= child_r
->child_at(0);
253 // When the root has a BubblingEventTargeter installed, events targeted
254 // at the grandchild target should be dispatched to all three targets.
255 KeyEvent
key_event(ET_KEY_PRESSED
, VKEY_ESCAPE
, EF_NONE
);
256 DispatchEvent(&key_event
);
257 EXPECT_TRUE(root()->DidReceiveEvent(ET_KEY_PRESSED
));
258 EXPECT_TRUE(child_r
->DidReceiveEvent(ET_KEY_PRESSED
));
259 EXPECT_TRUE(grandchild_r
->DidReceiveEvent(ET_KEY_PRESSED
));
260 root()->ResetReceivedEvents();
261 child_r
->ResetReceivedEvents();
262 grandchild_r
->ResetReceivedEvents();
264 // Add a pre-target handler on the child of the root that will mark the event
265 // as handled. No targets in the hierarchy should receive the event.
266 TestEventHandler handler
;
267 child_r
->AddPreTargetHandler(&handler
);
268 key_event
= KeyEvent(ET_KEY_PRESSED
, VKEY_ESCAPE
, EF_NONE
);
269 DispatchEvent(&key_event
);
270 EXPECT_FALSE(root()->DidReceiveEvent(ET_KEY_PRESSED
));
271 EXPECT_FALSE(child_r
->DidReceiveEvent(ET_KEY_PRESSED
));
272 EXPECT_FALSE(grandchild_r
->DidReceiveEvent(ET_KEY_PRESSED
));
273 EXPECT_EQ(1, handler
.num_key_events());
276 // Add a post-target handler on the child of the root that will mark the event
277 // as handled. Only the grandchild (the initial target) should receive the
279 child_r
->RemovePreTargetHandler(&handler
);
280 child_r
->AddPostTargetHandler(&handler
);
281 key_event
= KeyEvent(ET_KEY_PRESSED
, VKEY_ESCAPE
, EF_NONE
);
282 DispatchEvent(&key_event
);
283 EXPECT_FALSE(root()->DidReceiveEvent(ET_KEY_PRESSED
));
284 EXPECT_FALSE(child_r
->DidReceiveEvent(ET_KEY_PRESSED
));
285 EXPECT_TRUE(grandchild_r
->DidReceiveEvent(ET_KEY_PRESSED
));
286 EXPECT_EQ(1, handler
.num_key_events());
288 grandchild_r
->ResetReceivedEvents();
289 child_r
->RemovePostTargetHandler(&handler
);
291 // Mark the event as handled when it reaches the EP_TARGET phase of
292 // dispatch at the child of the root. The child and grandchild
293 // targets should both receive the event, but the root should not.
294 child_r
->set_mark_events_as_handled(true);
295 key_event
= KeyEvent(ET_KEY_PRESSED
, VKEY_ESCAPE
, EF_NONE
);
296 DispatchEvent(&key_event
);
297 EXPECT_FALSE(root()->DidReceiveEvent(ET_KEY_PRESSED
));
298 EXPECT_TRUE(child_r
->DidReceiveEvent(ET_KEY_PRESSED
));
299 EXPECT_TRUE(grandchild_r
->DidReceiveEvent(ET_KEY_PRESSED
));
300 root()->ResetReceivedEvents();
301 child_r
->ResetReceivedEvents();
302 grandchild_r
->ResetReceivedEvents();
303 child_r
->set_mark_events_as_handled(false);
306 // Tests that unhandled events are seen by the correct sequence of
307 // targets, pre-target handlers, and post-target handlers when
308 // a BubblingEventTargeter is installed on the root target.
309 TEST_F(EventProcessorTest
, HandlerSequence
) {
310 scoped_ptr
<TestEventTarget
> child(new TestEventTarget());
311 scoped_ptr
<TestEventTarget
> grandchild(new TestEventTarget());
313 root()->SetEventTargeter(
314 scoped_ptr
<EventTargeter
>(new BubblingEventTargeter(grandchild
.get())));
315 child
->AddChild(grandchild
.Pass());
316 root()->AddChild(child
.Pass());
318 ASSERT_EQ(1u, root()->child_count());
319 ASSERT_EQ(1u, root()->child_at(0)->child_count());
320 ASSERT_EQ(0u, root()->child_at(0)->child_at(0)->child_count());
322 TestEventTarget
* child_r
= root()->child_at(0);
323 TestEventTarget
* grandchild_r
= child_r
->child_at(0);
325 HandlerSequenceRecorder recorder
;
326 root()->set_target_name("R");
327 root()->set_recorder(&recorder
);
328 child_r
->set_target_name("C");
329 child_r
->set_recorder(&recorder
);
330 grandchild_r
->set_target_name("G");
331 grandchild_r
->set_recorder(&recorder
);
333 TestEventHandler pre_root
;
334 pre_root
.set_handler_name("PreR");
335 pre_root
.set_recorder(&recorder
);
336 root()->AddPreTargetHandler(&pre_root
);
338 TestEventHandler pre_child
;
339 pre_child
.set_handler_name("PreC");
340 pre_child
.set_recorder(&recorder
);
341 child_r
->AddPreTargetHandler(&pre_child
);
343 TestEventHandler pre_grandchild
;
344 pre_grandchild
.set_handler_name("PreG");
345 pre_grandchild
.set_recorder(&recorder
);
346 grandchild_r
->AddPreTargetHandler(&pre_grandchild
);
348 TestEventHandler post_root
;
349 post_root
.set_handler_name("PostR");
350 post_root
.set_recorder(&recorder
);
351 root()->AddPostTargetHandler(&post_root
);
353 TestEventHandler post_child
;
354 post_child
.set_handler_name("PostC");
355 post_child
.set_recorder(&recorder
);
356 child_r
->AddPostTargetHandler(&post_child
);
358 TestEventHandler post_grandchild
;
359 post_grandchild
.set_handler_name("PostG");
360 post_grandchild
.set_recorder(&recorder
);
361 grandchild_r
->AddPostTargetHandler(&post_grandchild
);
363 MouseEvent
mouse(ET_MOUSE_MOVED
, gfx::Point(10, 10), gfx::Point(10, 10),
365 DispatchEvent(&mouse
);
367 std::string expected
[] = { "PreR", "PreC", "PreG", "G", "PostG", "PostC",
368 "PostR", "PreR", "PreC", "C", "PostC", "PostR", "PreR", "R", "PostR" };
369 EXPECT_EQ(std::vector
<std::string
>(
370 expected
, expected
+ arraysize(expected
)), recorder
);