• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
StaticWindowTargeter(aura::Window * window)18   explicit StaticWindowTargeter(aura::Window* window)
19       : window_(window) {}
~StaticWindowTargeter()20   virtual ~StaticWindowTargeter() {}
21 
22  private:
23   // ui::EventTargeter:
FindTargetForLocatedEvent(ui::EventTarget * root,ui::LocatedEvent * event)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:
WindowTargeterTest()37   WindowTargeterTest() {}
~WindowTargeterTest()38   virtual ~WindowTargeterTest() {}
39 
root_window()40   Window* root_window() { return AuraTestBase::root_window(); }
41 };
42 
GetEffectiveVisibleBoundsInRootWindow(Window * 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());
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 
TEST_F(WindowTargeterTest,Basic)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 
TEST_F(WindowTargeterTest,ScopedWindowTargeter)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 
TEST_F(WindowTargeterTest,TargetTransformedWindow)121 TEST_F(WindowTargeterTest, TargetTransformedWindow) {
122   root_window()->Show();
123 
124   test::TestWindowDelegate delegate;
125   scoped_ptr<Window> window(CreateNormalWindow(2, root_window(), &delegate));
126 
127   const gfx::Rect window_bounds(100, 20, 400, 80);
128   window->SetBounds(window_bounds);
129 
130   ui::EventTarget* root_target = root_window();
131   ui::EventTargeter* targeter = root_target->GetEventTargeter();
132   gfx::Point event_location(490, 50);
133   {
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));
137   }
138 
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());
146   {
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));
150   }
151 
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());
158   {
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));
162   }
163 }
164 
165 }  // namespace aura
166