OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/views/controls/native/native_view_host_aura.h" | 5 #include "ui/views/controls/native/native_view_host_aura.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "ui/aura/client/aura_constants.h" | |
9 #include "ui/aura/window.h" | 10 #include "ui/aura/window.h" |
10 #include "ui/base/cursor/cursor.h" | 11 #include "ui/base/cursor/cursor.h" |
11 #include "ui/views/controls/native/native_view_host.h" | 12 #include "ui/views/controls/native/native_view_host.h" |
12 #include "ui/views/test/views_test_base.h" | 13 #include "ui/views/test/views_test_base.h" |
13 #include "ui/views/view.h" | 14 #include "ui/views/view.h" |
14 #include "ui/views/view_constants_aura.h" | 15 #include "ui/views/view_constants_aura.h" |
15 #include "ui/views/widget/widget.h" | 16 #include "ui/views/widget/widget.h" |
16 | 17 |
17 namespace views { | 18 namespace views { |
18 | 19 |
20 // Testing wrapper of the NativeViewHost | |
21 class NativeViewHostTesting : public NativeViewHost { | |
22 public: | |
23 NativeViewHostTesting() {} | |
24 virtual ~NativeViewHostTesting() { destroyed_count_++; } | |
25 | |
26 static void ResetDestroyedCount() { destroyed_count_ = 0; } | |
27 | |
28 static int destroyed_count() { return destroyed_count_; } | |
29 | |
30 private: | |
31 static int destroyed_count_; | |
32 | |
33 DISALLOW_COPY_AND_ASSIGN(NativeViewHostTesting); | |
34 }; | |
35 int NativeViewHostTesting::destroyed_count_ = 0; | |
36 | |
19 class NativeViewHostAuraTest : public ViewsTestBase { | 37 class NativeViewHostAuraTest : public ViewsTestBase { |
20 public: | 38 public: |
21 NativeViewHostAuraTest() { | 39 NativeViewHostAuraTest() { |
22 } | 40 } |
23 | 41 |
24 NativeViewHostAura* native_host() { | 42 NativeViewHostAura* native_host() { |
25 return static_cast<NativeViewHostAura*>(host_->native_wrapper_.get()); | 43 return static_cast<NativeViewHostAura*>(host_->native_wrapper_.get()); |
26 } | 44 } |
27 | 45 |
28 Widget* toplevel() { | 46 Widget* toplevel() { |
29 return toplevel_.get(); | 47 return toplevel_.get(); |
30 } | 48 } |
31 | 49 |
32 NativeViewHost* host() { | 50 NativeViewHost* host() { |
33 return host_.get(); | 51 return host_.get(); |
34 } | 52 } |
35 | 53 |
36 Widget* child() { | 54 Widget* child() { |
37 return child_.get(); | 55 return child_.get(); |
38 } | 56 } |
39 | 57 |
58 aura::Window* clipping_window() { return &(native_host()->clipping_window_); } | |
59 | |
40 void CreateHost() { | 60 void CreateHost() { |
41 // Create the top level widget. | 61 // Create the top level widget. |
42 toplevel_.reset(new Widget); | 62 toplevel_.reset(new Widget); |
43 Widget::InitParams toplevel_params = | 63 Widget::InitParams toplevel_params = |
44 CreateParams(Widget::InitParams::TYPE_WINDOW); | 64 CreateParams(Widget::InitParams::TYPE_WINDOW); |
45 toplevel_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 65 toplevel_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
46 toplevel_->Init(toplevel_params); | 66 toplevel_->Init(toplevel_params); |
47 | 67 |
48 // And the child widget. | 68 // And the child widget. |
49 View* test_view = new View; | 69 View* test_view = new View; |
50 child_.reset(new Widget); | 70 child_.reset(new Widget); |
51 Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL); | 71 Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL); |
52 child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 72 child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
53 child_params.parent = toplevel_->GetNativeView(); | 73 child_params.parent = toplevel_->GetNativeView(); |
54 child_->Init(child_params); | 74 child_->Init(child_params); |
55 child_->SetContentsView(test_view); | 75 child_->SetContentsView(test_view); |
56 | 76 |
57 // Owned by |toplevel|. | 77 // Owned by |toplevel|. |
58 host_.reset(new NativeViewHost); | 78 host_.reset(new NativeViewHostTesting); |
59 toplevel_->GetRootView()->AddChildView(host_.get()); | 79 toplevel_->GetRootView()->AddChildView(host_.get()); |
60 host_->Attach(child_->GetNativeView()); | 80 host_->Attach(child_->GetNativeView()); |
61 } | 81 } |
62 | 82 |
63 void DestroyHost() { | 83 void DestroyHost() { |
64 host_.reset(); | 84 host_.reset(); |
65 } | 85 } |
66 | 86 |
87 NativeViewHostTesting* ReleaseHost() { return host_.release(); } | |
88 | |
89 void DestroyTopLevel() { toplevel_.reset(); } | |
90 | |
67 private: | 91 private: |
68 scoped_ptr<Widget> toplevel_; | 92 scoped_ptr<Widget> toplevel_; |
69 scoped_ptr<NativeViewHost> host_; | 93 scoped_ptr<NativeViewHostTesting> host_; |
70 scoped_ptr<Widget> child_; | 94 scoped_ptr<Widget> child_; |
71 | 95 |
72 DISALLOW_COPY_AND_ASSIGN(NativeViewHostAuraTest); | 96 DISALLOW_COPY_AND_ASSIGN(NativeViewHostAuraTest); |
73 }; | 97 }; |
74 | 98 |
75 // Verifies NativeViewHostAura stops observing native view on destruction. | 99 // Verifies NativeViewHostAura stops observing native view on destruction. |
76 TEST_F(NativeViewHostAuraTest, StopObservingNativeViewOnDestruct) { | 100 TEST_F(NativeViewHostAuraTest, StopObservingNativeViewOnDestruct) { |
77 CreateHost(); | 101 CreateHost(); |
78 aura::Window* child_win = child()->GetNativeView(); | 102 aura::Window* child_win = child()->GetNativeView(); |
79 NativeViewHostAura* aura_host = native_host(); | 103 NativeViewHostAura* aura_host = native_host(); |
80 | 104 |
81 EXPECT_TRUE(child_win->HasObserver(aura_host)); | 105 EXPECT_TRUE(child_win->HasObserver(aura_host)); |
82 DestroyHost(); | 106 DestroyHost(); |
83 EXPECT_FALSE(child_win->HasObserver(aura_host)); | 107 EXPECT_FALSE(child_win->HasObserver(aura_host)); |
84 } | 108 } |
85 | 109 |
86 // Tests that the kHostViewKey is correctly set and cleared. | 110 // Tests that the kHostViewKey is correctly set and cleared. |
87 TEST_F(NativeViewHostAuraTest, HostViewPropertyKey) { | 111 TEST_F(NativeViewHostAuraTest, HostViewPropertyKey) { |
88 // Create the NativeViewHost and attach a NativeView. | 112 // Create the NativeViewHost and attach a NativeView. |
89 CreateHost(); | 113 CreateHost(); |
90 aura::Window* child_win = child()->GetNativeView(); | 114 aura::Window* child_win = child()->GetNativeView(); |
91 EXPECT_EQ(host(), child_win->GetProperty(views::kHostViewKey)); | 115 EXPECT_EQ(host(), child_win->GetProperty(views::kHostViewKey)); |
116 EXPECT_EQ(host()->GetWidget()->GetNativeView(), | |
117 child_win->GetProperty(aura::client::kHostWindowKey)); | |
118 EXPECT_EQ(host(), clipping_window()->GetProperty(views::kHostViewKey)); | |
92 | 119 |
93 host()->Detach(); | 120 host()->Detach(); |
94 EXPECT_FALSE(child_win->GetProperty(views::kHostViewKey)); | 121 EXPECT_FALSE(child_win->GetProperty(views::kHostViewKey)); |
122 EXPECT_FALSE(child_win->GetProperty(aura::client::kHostWindowKey)); | |
123 EXPECT_TRUE(clipping_window()->GetProperty(views::kHostViewKey)); | |
calamity
2014/06/19 00:14:44
This change is necessary due to the clipping windo
| |
95 | 124 |
96 host()->Attach(child_win); | 125 host()->Attach(child_win); |
97 EXPECT_EQ(host(), child_win->GetProperty(views::kHostViewKey)); | 126 EXPECT_EQ(host(), child_win->GetProperty(views::kHostViewKey)); |
127 EXPECT_EQ(host()->GetWidget()->GetNativeView(), | |
128 child_win->GetProperty(aura::client::kHostWindowKey)); | |
129 EXPECT_EQ(host(), clipping_window()->GetProperty(views::kHostViewKey)); | |
98 | 130 |
99 DestroyHost(); | 131 DestroyHost(); |
100 EXPECT_FALSE(child_win->GetProperty(views::kHostViewKey)); | 132 EXPECT_FALSE(child_win->GetProperty(views::kHostViewKey)); |
133 EXPECT_FALSE(child_win->GetProperty(aura::client::kHostWindowKey)); | |
101 } | 134 } |
102 | 135 |
103 // Tests that the NativeViewHost reports the cursor set on its native view. | 136 // Tests that the NativeViewHost reports the cursor set on its native view. |
104 TEST_F(NativeViewHostAuraTest, CursorForNativeView) { | 137 TEST_F(NativeViewHostAuraTest, CursorForNativeView) { |
105 CreateHost(); | 138 CreateHost(); |
106 | 139 |
107 toplevel()->SetCursor(ui::kCursorHand); | 140 toplevel()->SetCursor(ui::kCursorHand); |
108 child()->SetCursor(ui::kCursorWait); | 141 child()->SetCursor(ui::kCursorWait); |
109 ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, gfx::Point(0, 0), | 142 ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, gfx::Point(0, 0), |
110 gfx::Point(0, 0), 0, 0); | 143 gfx::Point(0, 0), 0, 0); |
111 | 144 |
112 EXPECT_EQ(ui::kCursorWait, host()->GetCursor(move_event).native_type()); | 145 EXPECT_EQ(ui::kCursorWait, host()->GetCursor(move_event).native_type()); |
113 | 146 |
114 DestroyHost(); | 147 DestroyHost(); |
115 } | 148 } |
116 | 149 |
150 // Test that destroying the top level widget before destroying the attached | |
151 // NativeViewHost works correctly. Specifically the associated NVH should be | |
152 // destroyed and there shouldn't be any errors. | |
153 TEST_F(NativeViewHostAuraTest, DestroyWidget) { | |
154 NativeViewHostTesting::ResetDestroyedCount(); | |
155 CreateHost(); | |
156 ReleaseHost(); | |
157 EXPECT_EQ(0, NativeViewHostTesting::destroyed_count()); | |
158 DestroyTopLevel(); | |
159 EXPECT_EQ(1, NativeViewHostTesting::destroyed_count()); | |
160 } | |
161 | |
162 // Test that the fast resize path places the clipping and content windows were | |
163 // they are supposed to be. | |
164 TEST_F(NativeViewHostAuraTest, FastResizePath) { | |
165 CreateHost(); | |
166 toplevel()->SetBounds(gfx::Rect(20, 20, 100, 100)); | |
167 | |
168 // Without fast resize, the clipping window should size to the native view | |
169 // with the native view positioned at the origin of the clipping window and | |
170 // the clipping window positioned where the native view was requested. | |
171 host()->set_fast_resize(false); | |
172 native_host()->ShowWidget(5, 10, 100, 100); | |
173 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), | |
174 host()->native_view()->bounds().ToString()); | |
175 EXPECT_EQ(gfx::Rect(5, 10, 100, 100).ToString(), | |
176 clipping_window()->bounds().ToString()); | |
177 | |
178 // With fast resize, the native view should remain the same size but be | |
179 // clipped the requested size. | |
180 host()->set_fast_resize(true); | |
181 native_host()->ShowWidget(10, 25, 50, 50); | |
182 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), | |
183 host()->native_view()->bounds().ToString()); | |
184 EXPECT_EQ(gfx::Rect(10, 25, 50, 50).ToString(), | |
185 clipping_window()->bounds().ToString()); | |
186 | |
187 // Turning off fast resize should make the native view start resizing again. | |
188 host()->set_fast_resize(false); | |
189 native_host()->ShowWidget(10, 25, 50, 50); | |
190 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), | |
191 host()->native_view()->bounds().ToString()); | |
192 EXPECT_EQ(gfx::Rect(10, 25, 50, 50).ToString(), | |
193 clipping_window()->bounds().ToString()); | |
194 | |
195 DestroyHost(); | |
196 } | |
197 | |
198 // Test installing and uninstalling a clip. | |
199 TEST_F(NativeViewHostAuraTest, InstallClip) { | |
200 CreateHost(); | |
201 toplevel()->SetBounds(gfx::Rect(20, 20, 100, 100)); | |
202 | |
203 // Without a clip, the clipping window should always be positioned at the | |
204 // requested coordinates with the native view positioned at the origin of the | |
205 // clipping window. | |
206 native_host()->ShowWidget(10, 20, 100, 100); | |
207 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), | |
208 host()->native_view()->bounds().ToString()); | |
209 EXPECT_EQ(gfx::Rect(10, 20, 100, 100).ToString(), | |
210 clipping_window()->bounds().ToString()); | |
211 | |
212 // Clip to the bottom right quarter of the native view. | |
213 native_host()->InstallClip(60, 70, 50, 50); | |
214 native_host()->ShowWidget(10, 20, 100, 100); | |
215 EXPECT_EQ(gfx::Rect(-50, -50, 100, 100).ToString(), | |
216 host()->native_view()->bounds().ToString()); | |
217 EXPECT_EQ(gfx::Rect(60, 70, 50, 50).ToString(), | |
218 clipping_window()->bounds().ToString()); | |
219 | |
220 // Clip to the center of the native view. | |
221 native_host()->InstallClip(35, 45, 50, 50); | |
222 native_host()->ShowWidget(10, 20, 100, 100); | |
223 EXPECT_EQ(gfx::Rect(-25, -25, 100, 100).ToString(), | |
224 host()->native_view()->bounds().ToString()); | |
225 EXPECT_EQ(gfx::Rect(35, 45, 50, 50).ToString(), | |
226 clipping_window()->bounds().ToString()); | |
227 | |
228 // Uninstalling the clip should make the clipping window match the native view | |
229 // again. | |
230 native_host()->UninstallClip(); | |
231 native_host()->ShowWidget(10, 20, 100, 100); | |
232 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), | |
233 host()->native_view()->bounds().ToString()); | |
234 EXPECT_EQ(gfx::Rect(10, 20, 100, 100).ToString(), | |
235 clipping_window()->bounds().ToString()); | |
236 | |
237 DestroyHost(); | |
238 } | |
239 | |
117 } // namespace views | 240 } // namespace views |
OLD | NEW |