OLD | NEW |
| (Empty) |
1 // Copyright 2014 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 "chrome/browser/ui/views/apps/shaped_app_window_targeter.h" | |
6 | |
7 #include "chrome/browser/ui/views/apps/native_app_window_views.h" | |
8 #include "ui/aura/root_window.h" | |
9 #include "ui/aura/test/aura_test_base.h" | |
10 #include "ui/aura/window.h" | |
11 #include "ui/views/controls/webview/webview.h" | |
12 #include "ui/wm/public/easy_resize_window_targeter.h" | |
13 | |
14 class ShapedAppWindowTargeterTest : public aura::test::AuraTestBase { | |
15 public: | |
16 ShapedAppWindowTargeterTest() | |
17 : web_view_(NULL) { | |
18 } | |
19 | |
20 virtual ~ShapedAppWindowTargeterTest() {} | |
21 | |
22 views::Widget* widget() { return widget_.get(); } | |
23 | |
24 apps::NativeAppWindow* app_window() { return &app_window_; } | |
25 NativeAppWindowViews* app_window_views() { return &app_window_; } | |
26 | |
27 protected: | |
28 virtual void SetUp() OVERRIDE { | |
29 aura::test::AuraTestBase::SetUp(); | |
30 widget_.reset(new views::Widget); | |
31 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
32 params.remove_standard_frame = true; | |
33 params.bounds = gfx::Rect(30, 30, 100, 100); | |
34 params.context = root_window(); | |
35 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
36 widget_->Init(params); | |
37 | |
38 app_window_.web_view_ = &web_view_; | |
39 app_window_.window_ = widget_.get(); | |
40 | |
41 widget_->Show(); | |
42 } | |
43 | |
44 virtual void TearDown() OVERRIDE { | |
45 widget_.reset(); | |
46 aura::test::AuraTestBase::TearDown(); | |
47 } | |
48 | |
49 private: | |
50 views::WebView web_view_; | |
51 scoped_ptr<views::Widget> widget_; | |
52 NativeAppWindowViews app_window_; | |
53 | |
54 DISALLOW_COPY_AND_ASSIGN(ShapedAppWindowTargeterTest); | |
55 }; | |
56 | |
57 TEST_F(ShapedAppWindowTargeterTest, HitTestBasic) { | |
58 aura::Window* window = widget()->GetNativeWindow(); | |
59 { | |
60 // Without any custom shapes, the event should be targeted correctly to the | |
61 // window. | |
62 ui::MouseEvent move(ui::ET_MOUSE_MOVED, | |
63 gfx::Point(40, 40), gfx::Point(40, 40), | |
64 ui::EF_NONE, ui::EF_NONE); | |
65 ui::EventDispatchDetails details = dispatcher()->OnEventFromSource(&move); | |
66 ASSERT_FALSE(details.dispatcher_destroyed); | |
67 EXPECT_EQ(window, move.target()); | |
68 } | |
69 | |
70 scoped_ptr<SkRegion> region(new SkRegion); | |
71 region->op(SkIRect::MakeXYWH(40, 0, 20, 100), SkRegion::kUnion_Op); | |
72 region->op(SkIRect::MakeXYWH(0, 40, 100, 20), SkRegion::kUnion_Op); | |
73 app_window()->UpdateShape(region.Pass()); | |
74 { | |
75 // With the custom shape, the events that don't fall within the custom shape | |
76 // will go through to the root window. | |
77 ui::MouseEvent move(ui::ET_MOUSE_MOVED, | |
78 gfx::Point(40, 40), gfx::Point(40, 40), | |
79 ui::EF_NONE, ui::EF_NONE); | |
80 ui::EventDispatchDetails details = dispatcher()->OnEventFromSource(&move); | |
81 ASSERT_FALSE(details.dispatcher_destroyed); | |
82 EXPECT_EQ(root_window(), move.target()); | |
83 | |
84 // But events within the shape will still reach the window. | |
85 ui::MouseEvent move2(ui::ET_MOUSE_MOVED, | |
86 gfx::Point(80, 80), gfx::Point(80, 80), | |
87 ui::EF_NONE, ui::EF_NONE); | |
88 details = dispatcher()->OnEventFromSource(&move2); | |
89 ASSERT_FALSE(details.dispatcher_destroyed); | |
90 EXPECT_EQ(window, move2.target()); | |
91 } | |
92 } | |
93 | |
94 TEST_F(ShapedAppWindowTargeterTest, HitTestOnlyForShapedWindow) { | |
95 // Install a window-targeter on the root window that allows a window to | |
96 // receive events outside of its bounds. Verify that this window-targeter is | |
97 // active unless the window has a custom shape. | |
98 gfx::Insets inset(-30, -30, -30, -30); | |
99 root_window()->SetEventTargeter(scoped_ptr<ui::EventTargeter>( | |
100 new wm::EasyResizeWindowTargeter(root_window(), inset, inset))); | |
101 | |
102 aura::Window* window = widget()->GetNativeWindow(); | |
103 { | |
104 // Without any custom shapes, an event within the window bounds should be | |
105 // targeted correctly to the window. | |
106 ui::MouseEvent move(ui::ET_MOUSE_MOVED, | |
107 gfx::Point(40, 40), gfx::Point(40, 40), | |
108 ui::EF_NONE, ui::EF_NONE); | |
109 ui::EventDispatchDetails details = dispatcher()->OnEventFromSource(&move); | |
110 ASSERT_FALSE(details.dispatcher_destroyed); | |
111 EXPECT_EQ(window, move.target()); | |
112 } | |
113 { | |
114 // Without any custom shapes, an event that falls just outside the window | |
115 // bounds should also be targeted correctly to the window, because of the | |
116 // targeter installed on the root-window. | |
117 ui::MouseEvent move(ui::ET_MOUSE_MOVED, | |
118 gfx::Point(10, 10), gfx::Point(10, 10), | |
119 ui::EF_NONE, ui::EF_NONE); | |
120 ui::EventDispatchDetails details = dispatcher()->OnEventFromSource(&move); | |
121 ASSERT_FALSE(details.dispatcher_destroyed); | |
122 EXPECT_EQ(window, move.target()); | |
123 } | |
124 | |
125 scoped_ptr<SkRegion> region(new SkRegion); | |
126 region->op(SkIRect::MakeXYWH(40, 0, 20, 100), SkRegion::kUnion_Op); | |
127 region->op(SkIRect::MakeXYWH(0, 40, 100, 20), SkRegion::kUnion_Op); | |
128 app_window()->UpdateShape(region.Pass()); | |
129 { | |
130 // With the custom shape, the events that don't fall within the custom shape | |
131 // will go through to the root window. | |
132 ui::MouseEvent move(ui::ET_MOUSE_MOVED, | |
133 gfx::Point(10, 10), gfx::Point(10, 10), | |
134 ui::EF_NONE, ui::EF_NONE); | |
135 ui::EventDispatchDetails details = dispatcher()->OnEventFromSource(&move); | |
136 ASSERT_FALSE(details.dispatcher_destroyed); | |
137 EXPECT_EQ(root_window(), move.target()); | |
138 } | |
139 | |
140 // Remove the custom shape. This should restore the behaviour of targeting the | |
141 // app window for events just outside its bounds. | |
142 app_window()->UpdateShape(scoped_ptr<SkRegion>()); | |
143 { | |
144 ui::MouseEvent move(ui::ET_MOUSE_MOVED, | |
145 gfx::Point(10, 10), gfx::Point(10, 10), | |
146 ui::EF_NONE, ui::EF_NONE); | |
147 ui::EventDispatchDetails details = dispatcher()->OnEventFromSource(&move); | |
148 ASSERT_FALSE(details.dispatcher_destroyed); | |
149 EXPECT_EQ(window, move.target()); | |
150 } | |
151 } | |
OLD | NEW |