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.
5 #include "athena/wm/public/window_manager.h"
7 #include "athena/screen/public/screen_manager.h"
8 #include "athena/test/athena_test_base.h"
9 #include "athena/wm/public/window_list_provider.h"
10 #include "athena/wm/split_view_controller.h"
11 #include "athena/wm/test/window_manager_impl_test_api.h"
12 #include "athena/wm/window_manager_impl.h"
13 #include "ui/aura/client/window_tree_client.h"
14 #include "ui/aura/test/test_window_delegate.h"
15 #include "ui/aura/window.h"
16 #include "ui/base/hit_test.h"
17 #include "ui/events/test/event_generator.h"
18 #include "ui/gfx/display.h"
19 #include "ui/gfx/screen.h"
20 #include "ui/wm/core/window_util.h"
24 scoped_ptr
<aura::Window
> CreateWindow(aura::WindowDelegate
* delegate
) {
25 scoped_ptr
<aura::Window
> window(new aura::Window(delegate
));
26 window
->SetType(ui::wm::WINDOW_TYPE_NORMAL
);
27 window
->Init(aura::WINDOW_LAYER_SOLID_COLOR
);
36 typedef test::AthenaTestBase WindowManagerTest
;
38 TEST_F(WindowManagerTest
, Empty
) {
41 TEST_F(WindowManagerTest
, OverviewModeBasics
) {
42 aura::test::TestWindowDelegate delegate
;
43 scoped_ptr
<aura::Window
> first(CreateWindow(&delegate
));
44 scoped_ptr
<aura::Window
> second(CreateWindow(&delegate
));
46 test::WindowManagerImplTestApi wm_api
;
47 aura::client::ParentWindowWithContext(
48 first
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
49 aura::client::ParentWindowWithContext(
50 second
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
52 ASSERT_FALSE(WindowManager::GetInstance()->IsOverviewModeActive());
53 EXPECT_EQ(first
->bounds().ToString(), second
->bounds().ToString());
54 EXPECT_EQ(gfx::Screen::GetNativeScreen()
59 first
->bounds().size().ToString());
60 EXPECT_FALSE(WindowManager::GetInstance()->IsOverviewModeActive());
62 // Tests that going into overview mode does not change the window bounds.
63 WindowManager::GetInstance()->ToggleOverview();
64 ASSERT_TRUE(WindowManager::GetInstance()->IsOverviewModeActive());
65 EXPECT_EQ(first
->bounds().ToString(), second
->bounds().ToString());
66 EXPECT_EQ(gfx::Screen::GetNativeScreen()
71 first
->bounds().size().ToString());
74 TEST_F(WindowManagerTest
, BezelGestureToSplitViewMode
) {
75 aura::test::TestWindowDelegate delegate
;
76 scoped_ptr
<aura::Window
> first(CreateWindow(&delegate
));
77 scoped_ptr
<aura::Window
> second(CreateWindow(&delegate
));
78 scoped_ptr
<aura::Window
> third(CreateWindow(&delegate
));
80 test::WindowManagerImplTestApi wm_api
;
81 aura::client::ParentWindowWithContext(
82 first
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
83 aura::client::ParentWindowWithContext(
84 second
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
85 aura::client::ParentWindowWithContext(
86 third
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
88 // Test that going into split-view mode with two-finger gesture selects the
89 // correct windows on left and right splits.
90 ui::test::EventGenerator
generator(root_window());
91 const gfx::Point start_points
[2] = {
92 gfx::Point(2, 10), gfx::Point(4, 20),
94 const int kEventTimeSepration
= 16;
95 int x_middle
= root_window()->bounds().width() / 2;
96 generator
.GestureMultiFingerScroll(
97 2, start_points
, kEventTimeSepration
, 1, x_middle
, 0);
98 ASSERT_TRUE(wm_api
.GetSplitViewController()->IsSplitViewModeActive());
99 EXPECT_EQ(second
.get(), wm_api
.GetSplitViewController()->left_window());
100 EXPECT_EQ(third
.get(), wm_api
.GetSplitViewController()->right_window());
101 EXPECT_EQ(second
->bounds().size().ToString(),
102 third
->bounds().size().ToString());
105 TEST_F(WindowManagerTest
, BezelGestureToSwitchBetweenWindows
) {
106 aura::test::TestWindowDelegate delegate
;
107 scoped_ptr
<aura::Window
> first(CreateWindow(&delegate
));
108 scoped_ptr
<aura::Window
> second(CreateWindow(&delegate
));
109 scoped_ptr
<aura::Window
> third(CreateWindow(&delegate
));
111 test::WindowManagerImplTestApi wm_api
;
112 aura::client::ParentWindowWithContext(
113 first
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
114 aura::client::ParentWindowWithContext(
115 second
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
116 aura::client::ParentWindowWithContext(
117 third
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
119 EXPECT_EQ(third
.get(),
120 wm_api
.GetWindowListProvider()->GetWindowList().back());
122 // Do a two-finger swipe from the left bezel.
123 ui::test::EventGenerator
generator(root_window());
124 const gfx::Point left_bezel_points
[2] = {
125 gfx::Point(2, 10), gfx::Point(4, 20),
127 const int kEventTimeSepration
= 16;
128 int width
= root_window()->bounds().width();
129 generator
.GestureMultiFingerScroll(
130 2, left_bezel_points
, kEventTimeSepration
, 1, width
, 0);
131 EXPECT_TRUE(wm::IsActiveWindow(second
.get()));
132 EXPECT_EQ(second
.get(),
133 wm_api
.GetWindowListProvider()->GetWindowList().back());
136 TEST_F(WindowManagerTest
, TitleDragSwitchBetweenWindows
) {
137 aura::test::TestWindowDelegate delegate
;
138 delegate
.set_window_component(HTCAPTION
);
139 scoped_ptr
<aura::Window
> first(CreateWindow(&delegate
));
140 scoped_ptr
<aura::Window
> second(CreateWindow(&delegate
));
141 scoped_ptr
<aura::Window
> third(CreateWindow(&delegate
));
143 test::WindowManagerImplTestApi wm_api
;
144 aura::client::ParentWindowWithContext(
145 first
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
146 aura::client::ParentWindowWithContext(
147 second
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
148 aura::client::ParentWindowWithContext(
149 third
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
151 EXPECT_EQ(third
.get(),
152 wm_api
.GetWindowListProvider()->GetWindowList().back());
154 // Do a title-swipe from the top to switch to the previous window.
155 ui::test::EventGenerator
generator(root_window());
156 generator
.GestureScrollSequence(gfx::Point(20, 10),
158 base::TimeDelta::FromMilliseconds(20),
160 EXPECT_TRUE(wm::IsActiveWindow(second
.get()));
161 EXPECT_EQ(second
.get(),
162 wm_api
.GetWindowListProvider()->GetWindowList().back());
163 EXPECT_TRUE(second
->IsVisible());
164 EXPECT_FALSE(third
->IsVisible());
166 // Performing the same gesture again will switch back to |third|.
167 generator
.GestureScrollSequence(gfx::Point(20, 10),
169 base::TimeDelta::FromMilliseconds(20),
171 EXPECT_TRUE(wm::IsActiveWindow(third
.get()));
172 EXPECT_EQ(third
.get(),
173 wm_api
.GetWindowListProvider()->GetWindowList().back());
174 EXPECT_FALSE(second
->IsVisible());
175 EXPECT_TRUE(third
->IsVisible());
177 // Perform a swipe that doesn't go enough to perform the window switch.
178 generator
.GestureScrollSequence(gfx::Point(20, 10),
180 base::TimeDelta::FromMilliseconds(20),
182 EXPECT_TRUE(wm::IsActiveWindow(third
.get()));
183 EXPECT_EQ(third
.get(),
184 wm_api
.GetWindowListProvider()->GetWindowList().back());
185 EXPECT_FALSE(second
->IsVisible());
186 EXPECT_TRUE(third
->IsVisible());
189 TEST_F(WindowManagerTest
, TitleDragSwitchBetweenWindowsInSplitViewMode
) {
190 aura::test::TestWindowDelegate delegate
;
191 delegate
.set_window_component(HTCAPTION
);
192 scoped_ptr
<aura::Window
> first(CreateWindow(&delegate
));
193 scoped_ptr
<aura::Window
> second(CreateWindow(&delegate
));
194 scoped_ptr
<aura::Window
> third(CreateWindow(&delegate
));
195 scoped_ptr
<aura::Window
> fourth(CreateWindow(&delegate
));
197 test::WindowManagerImplTestApi wm_api
;
198 aura::client::ParentWindowWithContext(
199 first
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
200 aura::client::ParentWindowWithContext(
201 second
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
202 aura::client::ParentWindowWithContext(
203 third
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
204 aura::client::ParentWindowWithContext(
205 fourth
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
207 // Test that going into split-view mode with two-finger gesture selects the
208 // correct windows on left and right splits.
209 ui::test::EventGenerator
generator(root_window());
210 const gfx::Point start_points
[2] = {
211 gfx::Point(2, 10), gfx::Point(4, 20),
213 const int kEventTimeSepration
= 16;
214 int x_middle
= root_window()->bounds().width() / 2;
215 generator
.GestureMultiFingerScroll(
216 2, start_points
, kEventTimeSepration
, 1, x_middle
, 0);
217 ASSERT_TRUE(wm_api
.GetSplitViewController()->IsSplitViewModeActive());
218 EXPECT_EQ(third
.get(), wm_api
.GetSplitViewController()->left_window());
219 EXPECT_EQ(fourth
.get(), wm_api
.GetSplitViewController()->right_window());
221 // Swipe the title of the left window. It should switch to |second|.
222 generator
.GestureScrollSequence(gfx::Point(20, 10),
224 base::TimeDelta::FromMilliseconds(20),
226 EXPECT_EQ(second
.get(), wm_api
.GetSplitViewController()->left_window());
227 EXPECT_EQ(fourth
.get(), wm_api
.GetSplitViewController()->right_window());
228 aura::Window::Windows windows
=
229 wm_api
.GetWindowListProvider()->GetWindowList();
230 ASSERT_EQ(4u, windows
.size());
231 EXPECT_EQ(second
.get(), windows
[3]);
232 EXPECT_EQ(third
.get(), windows
[2]);
233 EXPECT_EQ(fourth
.get(), windows
[1]);
235 // Swipe the title of the right window now. It should switch to |third|.
236 generator
.GestureScrollSequence(gfx::Point(x_middle
+ 20, 10),
237 gfx::Point(x_middle
+ 20, 400),
238 base::TimeDelta::FromMilliseconds(20),
240 EXPECT_EQ(second
.get(), wm_api
.GetSplitViewController()->left_window());
241 EXPECT_EQ(third
.get(), wm_api
.GetSplitViewController()->right_window());
244 TEST_F(WindowManagerTest
, NewWindowBounds
) {
245 aura::test::TestWindowDelegate delegate
;
246 scoped_ptr
<aura::Window
> first(CreateWindow(&delegate
));
248 test::WindowManagerImplTestApi wm_api
;
249 aura::client::ParentWindowWithContext(
250 first
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
251 // The window should have the same size as the container.
252 const gfx::Size work_area
=
253 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area().size();
254 EXPECT_EQ(work_area
.ToString(),
255 first
->bounds().size().ToString());
256 EXPECT_TRUE(first
->bounds().origin().IsOrigin());
258 // A second window should have the same bounds as the first one.
259 scoped_ptr
<aura::Window
> second(CreateWindow(&delegate
));
260 aura::client::ParentWindowWithContext(
261 second
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
262 EXPECT_EQ(first
->bounds().ToString(), second
->bounds().ToString());
264 // Get into split view.
265 wm_api
.GetSplitViewController()->ActivateSplitMode(NULL
, NULL
);
266 const gfx::Rect left_bounds
=
267 wm_api
.GetSplitViewController()->left_window()->bounds();
268 EXPECT_NE(work_area
.ToString(),
269 left_bounds
.size().ToString());
271 scoped_ptr
<aura::Window
> third(CreateWindow(&delegate
));
272 aura::client::ParentWindowWithContext(
273 third
.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
274 EXPECT_NE(wm_api
.GetSplitViewController()->left_window(), third
.get());
275 EXPECT_EQ(left_bounds
.ToString(), third
->bounds().ToString());
279 left_bounds
.ToString(),
280 wm_api
.GetSplitViewController()->left_window()->bounds().ToString());
283 TEST_F(WindowManagerTest
, SplitModeActivationByShortcut
) {
284 test::WindowManagerImplTestApi wm_api
;
286 aura::test::TestWindowDelegate delegate
;
287 scoped_ptr
<aura::Window
> w1(CreateTestWindow(&delegate
, gfx::Rect()));
290 ui::test::EventGenerator
generator(root_window());
292 // Splitview mode needs at least two windows.
293 generator
.PressKey(ui::VKEY_F6
, ui::EF_CONTROL_DOWN
);
294 generator
.ReleaseKey(ui::VKEY_F6
, ui::EF_CONTROL_DOWN
);
295 EXPECT_FALSE(wm_api
.GetSplitViewController()->IsSplitViewModeActive());
297 scoped_ptr
<aura::Window
> w2(CreateTestWindow(&delegate
, gfx::Rect()));
300 generator
.PressKey(ui::VKEY_F6
, ui::EF_CONTROL_DOWN
);
301 generator
.ReleaseKey(ui::VKEY_F6
, ui::EF_CONTROL_DOWN
);
302 EXPECT_TRUE(wm_api
.GetSplitViewController()->IsSplitViewModeActive());
304 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area().width();
306 EXPECT_EQ(width
/ 2, w1
->bounds().width());
307 EXPECT_EQ(width
/ 2, w2
->bounds().width());
309 // Toggle back to normal mode.
310 generator
.PressKey(ui::VKEY_F6
, ui::EF_CONTROL_DOWN
);
311 generator
.ReleaseKey(ui::VKEY_F6
, ui::EF_CONTROL_DOWN
);
312 EXPECT_FALSE(wm_api
.GetSplitViewController()->IsSplitViewModeActive());
314 EXPECT_EQ(width
, w1
->bounds().width());
315 EXPECT_EQ(width
, w2
->bounds().width());
318 } // namespace athena