Exclude TrayIMETest.PerformActionOnDetailedView under valgrind, where it crashes.
[chromium-blink-merge.git] / ui / wm / core / shadow_controller_unittest.cc
blob3c8ab0cc4dea5c8b5aea51d417d916f0dfb85630
1 // Copyright (c) 2012 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/wm/core/shadow_controller.h"
7 #include <algorithm>
8 #include <vector>
10 #include "base/memory/scoped_ptr.h"
11 #include "ui/aura/client/aura_constants.h"
12 #include "ui/aura/client/window_tree_client.h"
13 #include "ui/aura/test/aura_test_base.h"
14 #include "ui/aura/window.h"
15 #include "ui/aura/window_event_dispatcher.h"
16 #include "ui/compositor/layer.h"
17 #include "ui/wm/core/default_activation_client.h"
18 #include "ui/wm/core/shadow.h"
19 #include "ui/wm/core/shadow_types.h"
20 #include "ui/wm/core/window_util.h"
21 #include "ui/wm/core/wm_state.h"
22 #include "ui/wm/public/activation_client.h"
24 namespace wm {
26 class ShadowControllerTest : public aura::test::AuraTestBase {
27 public:
28 ShadowControllerTest() {}
29 ~ShadowControllerTest() override {}
31 void SetUp() override {
32 wm_state_.reset(new wm::WMState);
33 AuraTestBase::SetUp();
34 new wm::DefaultActivationClient(root_window());
35 aura::client::ActivationClient* activation_client =
36 aura::client::GetActivationClient(root_window());
37 shadow_controller_.reset(new ShadowController(activation_client));
39 void TearDown() override {
40 shadow_controller_.reset();
41 AuraTestBase::TearDown();
42 wm_state_.reset();
45 protected:
46 ShadowController* shadow_controller() { return shadow_controller_.get(); }
48 void ActivateWindow(aura::Window* window) {
49 DCHECK(window);
50 DCHECK(window->GetRootWindow());
51 aura::client::GetActivationClient(window->GetRootWindow())->ActivateWindow(
52 window);
55 private:
56 scoped_ptr<ShadowController> shadow_controller_;
57 scoped_ptr<wm::WMState> wm_state_;
59 DISALLOW_COPY_AND_ASSIGN(ShadowControllerTest);
62 // Tests that various methods in Window update the Shadow object as expected.
63 TEST_F(ShadowControllerTest, Shadow) {
64 scoped_ptr<aura::Window> window(new aura::Window(NULL));
65 window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
66 window->Init(ui::LAYER_TEXTURED);
67 ParentWindow(window.get());
69 // We should create the shadow before the window is visible (the shadow's
70 // layer won't get drawn yet since it's a child of the window's layer).
71 ShadowController::TestApi api(shadow_controller());
72 const Shadow* shadow = api.GetShadowForWindow(window.get());
73 ASSERT_TRUE(shadow != NULL);
74 EXPECT_TRUE(shadow->layer()->visible());
76 // The shadow should remain visible after window visibility changes.
77 window->Show();
78 EXPECT_TRUE(shadow->layer()->visible());
79 window->Hide();
80 EXPECT_TRUE(shadow->layer()->visible());
82 // If the shadow is disabled, it should be hidden.
83 SetShadowType(window.get(), SHADOW_TYPE_NONE);
84 window->Show();
85 EXPECT_FALSE(shadow->layer()->visible());
86 SetShadowType(window.get(), SHADOW_TYPE_RECTANGULAR);
87 EXPECT_TRUE(shadow->layer()->visible());
89 // The shadow's layer should be a child of the window's layer.
90 EXPECT_EQ(window->layer(), shadow->layer()->parent());
92 window->parent()->RemoveChild(window.get());
93 aura::Window* window_ptr = window.get();
94 window.reset();
95 EXPECT_TRUE(api.GetShadowForWindow(window_ptr) == NULL);
98 // Tests that the window's shadow's bounds are updated correctly.
99 TEST_F(ShadowControllerTest, ShadowBounds) {
100 scoped_ptr<aura::Window> window(new aura::Window(NULL));
101 window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
102 window->Init(ui::LAYER_TEXTURED);
103 ParentWindow(window.get());
104 window->Show();
106 const gfx::Rect kOldBounds(20, 30, 400, 300);
107 window->SetBounds(kOldBounds);
109 // When the shadow is first created, it should use the window's size (but
110 // remain at the origin, since it's a child of the window's layer).
111 SetShadowType(window.get(), SHADOW_TYPE_RECTANGULAR);
112 ShadowController::TestApi api(shadow_controller());
113 const Shadow* shadow = api.GetShadowForWindow(window.get());
114 ASSERT_TRUE(shadow != NULL);
115 EXPECT_EQ(gfx::Rect(kOldBounds.size()).ToString(),
116 shadow->content_bounds().ToString());
118 // When we change the window's bounds, the shadow's should be updated too.
119 gfx::Rect kNewBounds(50, 60, 500, 400);
120 window->SetBounds(kNewBounds);
121 EXPECT_EQ(gfx::Rect(kNewBounds.size()).ToString(),
122 shadow->content_bounds().ToString());
125 // Tests that activating a window changes the shadow style.
126 TEST_F(ShadowControllerTest, ShadowStyle) {
127 ShadowController::TestApi api(shadow_controller());
129 scoped_ptr<aura::Window> window1(new aura::Window(NULL));
130 window1->SetType(ui::wm::WINDOW_TYPE_NORMAL);
131 window1->Init(ui::LAYER_TEXTURED);
132 ParentWindow(window1.get());
133 window1->SetBounds(gfx::Rect(10, 20, 300, 400));
134 window1->Show();
135 ActivateWindow(window1.get());
137 // window1 is active, so style should have active appearance.
138 Shadow* shadow1 = api.GetShadowForWindow(window1.get());
139 ASSERT_TRUE(shadow1 != NULL);
140 EXPECT_EQ(Shadow::STYLE_ACTIVE, shadow1->style());
142 // Create another window and activate it.
143 scoped_ptr<aura::Window> window2(new aura::Window(NULL));
144 window2->SetType(ui::wm::WINDOW_TYPE_NORMAL);
145 window2->Init(ui::LAYER_TEXTURED);
146 ParentWindow(window2.get());
147 window2->SetBounds(gfx::Rect(11, 21, 301, 401));
148 window2->Show();
149 ActivateWindow(window2.get());
151 // window1 is now inactive, so shadow should go inactive.
152 Shadow* shadow2 = api.GetShadowForWindow(window2.get());
153 ASSERT_TRUE(shadow2 != NULL);
154 EXPECT_EQ(Shadow::STYLE_INACTIVE, shadow1->style());
155 EXPECT_EQ(Shadow::STYLE_ACTIVE, shadow2->style());
158 // Tests that shadow gets updated when the window show state changes.
159 TEST_F(ShadowControllerTest, ShowState) {
160 ShadowController::TestApi api(shadow_controller());
162 scoped_ptr<aura::Window> window(new aura::Window(NULL));
163 window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
164 window->Init(ui::LAYER_TEXTURED);
165 ParentWindow(window.get());
166 window->Show();
168 Shadow* shadow = api.GetShadowForWindow(window.get());
169 ASSERT_TRUE(shadow != NULL);
170 EXPECT_EQ(Shadow::STYLE_INACTIVE, shadow->style());
172 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
173 EXPECT_FALSE(shadow->layer()->visible());
175 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
176 EXPECT_TRUE(shadow->layer()->visible());
178 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
179 EXPECT_FALSE(shadow->layer()->visible());
182 // Tests that we use smaller shadows for tooltips and menus.
183 TEST_F(ShadowControllerTest, SmallShadowsForTooltipsAndMenus) {
184 ShadowController::TestApi api(shadow_controller());
186 scoped_ptr<aura::Window> tooltip_window(new aura::Window(NULL));
187 tooltip_window->SetType(ui::wm::WINDOW_TYPE_TOOLTIP);
188 tooltip_window->Init(ui::LAYER_TEXTURED);
189 ParentWindow(tooltip_window.get());
190 tooltip_window->SetBounds(gfx::Rect(10, 20, 300, 400));
191 tooltip_window->Show();
193 Shadow* tooltip_shadow = api.GetShadowForWindow(tooltip_window.get());
194 ASSERT_TRUE(tooltip_shadow != NULL);
195 EXPECT_EQ(Shadow::STYLE_SMALL, tooltip_shadow->style());
197 scoped_ptr<aura::Window> menu_window(new aura::Window(NULL));
198 menu_window->SetType(ui::wm::WINDOW_TYPE_MENU);
199 menu_window->Init(ui::LAYER_TEXTURED);
200 ParentWindow(menu_window.get());
201 menu_window->SetBounds(gfx::Rect(10, 20, 300, 400));
202 menu_window->Show();
204 Shadow* menu_shadow = api.GetShadowForWindow(tooltip_window.get());
205 ASSERT_TRUE(menu_shadow != NULL);
206 EXPECT_EQ(Shadow::STYLE_SMALL, menu_shadow->style());
209 // http://crbug.com/120210 - transient parents of certain types of transients
210 // should not lose their shadow when they lose activation to the transient.
211 TEST_F(ShadowControllerTest, TransientParentKeepsActiveShadow) {
212 ShadowController::TestApi api(shadow_controller());
214 scoped_ptr<aura::Window> window1(new aura::Window(NULL));
215 window1->SetType(ui::wm::WINDOW_TYPE_NORMAL);
216 window1->Init(ui::LAYER_TEXTURED);
217 ParentWindow(window1.get());
218 window1->SetBounds(gfx::Rect(10, 20, 300, 400));
219 window1->Show();
220 ActivateWindow(window1.get());
222 // window1 is active, so style should have active appearance.
223 Shadow* shadow1 = api.GetShadowForWindow(window1.get());
224 ASSERT_TRUE(shadow1 != NULL);
225 EXPECT_EQ(Shadow::STYLE_ACTIVE, shadow1->style());
227 // Create a window that is transient to window1, and that has the 'hide on
228 // deactivate' property set. Upon activation, window1 should still have an
229 // active shadow.
230 scoped_ptr<aura::Window> window2(new aura::Window(NULL));
231 window2->SetType(ui::wm::WINDOW_TYPE_NORMAL);
232 window2->Init(ui::LAYER_TEXTURED);
233 ParentWindow(window2.get());
234 window2->SetBounds(gfx::Rect(11, 21, 301, 401));
235 AddTransientChild(window1.get(), window2.get());
236 aura::client::SetHideOnDeactivate(window2.get(), true);
237 window2->Show();
238 ActivateWindow(window2.get());
240 // window1 is now inactive, but its shadow should still appear active.
241 EXPECT_EQ(Shadow::STYLE_ACTIVE, shadow1->style());
244 } // namespace wm