OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "ash/wm/shelf_layout_manager.h" | |
6 | |
7 #include "ash/accelerators/accelerator_controller.h" | |
8 #include "ash/accelerators/accelerator_table.h" | |
9 #include "ash/ash_switches.h" | |
10 #include "ash/display/display_manager.h" | |
11 #include "ash/focus_cycler.h" | |
12 #include "ash/launcher/launcher.h" | |
13 #include "ash/root_window_controller.h" | |
14 #include "ash/screen_ash.h" | |
15 #include "ash/shell.h" | |
16 #include "ash/shell_delegate.h" | |
17 #include "ash/shell_window_ids.h" | |
18 #include "ash/system/status_area_widget.h" | |
19 #include "ash/system/tray/system_tray.h" | |
20 #include "ash/system/tray/system_tray_item.h" | |
21 #include "ash/test/ash_test_base.h" | |
22 #include "ash/wm/window_util.h" | |
23 #include "base/command_line.h" | |
24 #include "base/utf_string_conversions.h" | |
25 #include "ui/aura/client/aura_constants.h" | |
26 #include "ui/aura/root_window.h" | |
27 #include "ui/aura/test/event_generator.h" | |
28 #include "ui/aura/window.h" | |
29 #include "ui/base/animation/animation_container_element.h" | |
30 #include "ui/compositor/layer.h" | |
31 #include "ui/compositor/layer_animator.h" | |
32 #include "ui/gfx/display.h" | |
33 #include "ui/gfx/screen.h" | |
34 #include "ui/views/controls/label.h" | |
35 #include "ui/views/layout/fill_layout.h" | |
36 #include "ui/views/view.h" | |
37 #include "ui/views/widget/widget.h" | |
38 | |
39 #if defined(OS_WIN) | |
40 #include "base/win/windows_version.h" | |
41 #endif | |
42 | |
43 namespace ash { | |
44 namespace internal { | |
45 | |
46 namespace { | |
47 | |
48 void StepWidgetLayerAnimatorToEnd(views::Widget* widget) { | |
49 ui::AnimationContainerElement* element = | |
50 static_cast<ui::AnimationContainerElement*>( | |
51 widget->GetNativeView()->layer()->GetAnimator()); | |
52 element->Step(base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1)); | |
53 } | |
54 | |
55 ShelfLayoutManager* GetShelfLayoutManager() { | |
56 return Shell::GetPrimaryRootWindowController()->shelf(); | |
57 } | |
58 | |
59 SystemTray* GetSystemTray() { | |
60 return Shell::GetPrimaryRootWindowController()->GetSystemTray(); | |
61 } | |
62 | |
63 class ShelfLayoutObserverTest : public ShelfLayoutManager::Observer { | |
64 public: | |
65 ShelfLayoutObserverTest() | |
66 : changed_auto_hide_state_(false) { | |
67 } | |
68 | |
69 virtual ~ShelfLayoutObserverTest() {} | |
70 | |
71 bool changed_auto_hide_state() const { return changed_auto_hide_state_; } | |
72 | |
73 private: | |
74 virtual void OnAutoHideStateChanged( | |
75 ShelfAutoHideState new_state) OVERRIDE { | |
76 changed_auto_hide_state_ = true; | |
77 } | |
78 | |
79 bool changed_auto_hide_state_; | |
80 | |
81 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutObserverTest); | |
82 }; | |
83 | |
84 // Trivial item implementation that tracks its views for testing. | |
85 class TestItem : public SystemTrayItem { | |
86 public: | |
87 TestItem() | |
88 : SystemTrayItem(GetSystemTray()), | |
89 tray_view_(NULL), | |
90 default_view_(NULL), | |
91 detailed_view_(NULL), | |
92 notification_view_(NULL) {} | |
93 | |
94 virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE { | |
95 tray_view_ = new views::View; | |
96 // Add a label so it has non-zero width. | |
97 tray_view_->SetLayoutManager(new views::FillLayout); | |
98 tray_view_->AddChildView(new views::Label(UTF8ToUTF16("Tray"))); | |
99 return tray_view_; | |
100 } | |
101 | |
102 virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE { | |
103 default_view_ = new views::View; | |
104 default_view_->SetLayoutManager(new views::FillLayout); | |
105 default_view_->AddChildView(new views::Label(UTF8ToUTF16("Default"))); | |
106 return default_view_; | |
107 } | |
108 | |
109 virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE { | |
110 detailed_view_ = new views::View; | |
111 detailed_view_->SetLayoutManager(new views::FillLayout); | |
112 detailed_view_->AddChildView(new views::Label(UTF8ToUTF16("Detailed"))); | |
113 return detailed_view_; | |
114 } | |
115 | |
116 virtual views::View* CreateNotificationView( | |
117 user::LoginStatus status) OVERRIDE { | |
118 notification_view_ = new views::View; | |
119 return notification_view_; | |
120 } | |
121 | |
122 virtual void DestroyTrayView() OVERRIDE { | |
123 tray_view_ = NULL; | |
124 } | |
125 | |
126 virtual void DestroyDefaultView() OVERRIDE { | |
127 default_view_ = NULL; | |
128 } | |
129 | |
130 virtual void DestroyDetailedView() OVERRIDE { | |
131 detailed_view_ = NULL; | |
132 } | |
133 | |
134 virtual void DestroyNotificationView() OVERRIDE { | |
135 notification_view_ = NULL; | |
136 } | |
137 | |
138 virtual void UpdateAfterLoginStatusChange( | |
139 user::LoginStatus status) OVERRIDE {} | |
140 | |
141 views::View* tray_view() const { return tray_view_; } | |
142 views::View* default_view() const { return default_view_; } | |
143 views::View* detailed_view() const { return detailed_view_; } | |
144 views::View* notification_view() const { return notification_view_; } | |
145 | |
146 private: | |
147 views::View* tray_view_; | |
148 views::View* default_view_; | |
149 views::View* detailed_view_; | |
150 views::View* notification_view_; | |
151 | |
152 DISALLOW_COPY_AND_ASSIGN(TestItem); | |
153 }; | |
154 | |
155 } // namespace | |
156 | |
157 class ShelfLayoutManagerTest : public ash::test::AshTestBase { | |
158 public: | |
159 ShelfLayoutManagerTest() {} | |
160 | |
161 void SetState(ShelfLayoutManager* shelf, | |
162 ShelfVisibilityState state) { | |
163 shelf->SetState(state); | |
164 } | |
165 | |
166 void UpdateAutoHideStateNow() { | |
167 GetShelfLayoutManager()->UpdateAutoHideStateNow(); | |
168 } | |
169 | |
170 aura::Window* CreateTestWindow() { | |
171 aura::Window* window = new aura::Window(NULL); | |
172 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); | |
173 window->SetType(aura::client::WINDOW_TYPE_NORMAL); | |
174 window->Init(ui::LAYER_TEXTURED); | |
175 SetDefaultParentByPrimaryRootWindow(window); | |
176 return window; | |
177 } | |
178 | |
179 views::Widget* CreateTestWidgetWithParams( | |
180 const views::Widget::InitParams& params) { | |
181 views::Widget* out = new views::Widget; | |
182 out->Init(params); | |
183 out->Show(); | |
184 return out; | |
185 } | |
186 | |
187 // Create a simple widget attached to the current context (will | |
188 // delete on TearDown). | |
189 views::Widget* CreateTestWidget() { | |
190 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
191 params.bounds = gfx::Rect(0, 0, 200, 200); | |
192 params.context = CurrentContext(); | |
193 return CreateTestWidgetWithParams(params); | |
194 } | |
195 | |
196 // Overridden from AshTestBase: | |
197 virtual void SetUp() OVERRIDE { | |
198 CommandLine::ForCurrentProcess()->AppendSwitch( | |
199 ash::switches::kAshEnableTrayDragging); | |
200 test::AshTestBase::SetUp(); | |
201 } | |
202 private: | |
203 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerTest); | |
204 }; | |
205 | |
206 // Fails on Mac only. Need to be implemented. http://crbug.com/111279. | |
207 #if defined(OS_MACOSX) || defined(OS_WIN) | |
208 #define MAYBE_SetVisible DISABLED_SetVisible | |
209 #else | |
210 #define MAYBE_SetVisible SetVisible | |
211 #endif | |
212 // Makes sure SetVisible updates work area and widget appropriately. | |
213 TEST_F(ShelfLayoutManagerTest, MAYBE_SetVisible) { | |
214 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
215 // Force an initial layout. | |
216 shelf->LayoutShelf(); | |
217 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
218 | |
219 gfx::Rect status_bounds( | |
220 shelf->status_area_widget()->GetWindowBoundsInScreen()); | |
221 gfx::Rect launcher_bounds( | |
222 shelf->launcher_widget()->GetWindowBoundsInScreen()); | |
223 int shelf_height = shelf->GetIdealBounds().height(); | |
224 | |
225 const gfx::Display& display = Shell::GetInstance()->display_manager()-> | |
226 GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
227 ASSERT_NE(-1, display.id()); | |
228 // Bottom inset should be the max of widget heights. | |
229 EXPECT_EQ(shelf_height, | |
230 display.bounds().bottom() - display.work_area().bottom()); | |
231 | |
232 // Hide the shelf. | |
233 SetState(shelf, SHELF_HIDDEN); | |
234 // Run the animation to completion. | |
235 StepWidgetLayerAnimatorToEnd(shelf->launcher_widget()); | |
236 StepWidgetLayerAnimatorToEnd(shelf->status_area_widget()); | |
237 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); | |
238 EXPECT_EQ(0, | |
239 display.bounds().bottom() - display.work_area().bottom()); | |
240 | |
241 // Make sure the bounds of the two widgets changed. | |
242 EXPECT_GE(shelf->launcher_widget()->GetNativeView()->bounds().y(), | |
243 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom()); | |
244 EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(), | |
245 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom()); | |
246 | |
247 // And show it again. | |
248 SetState(shelf, SHELF_VISIBLE); | |
249 // Run the animation to completion. | |
250 StepWidgetLayerAnimatorToEnd(shelf->launcher_widget()); | |
251 StepWidgetLayerAnimatorToEnd(shelf->status_area_widget()); | |
252 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
253 EXPECT_EQ(shelf_height, | |
254 display.bounds().bottom() - display.work_area().bottom()); | |
255 | |
256 // Make sure the bounds of the two widgets changed. | |
257 launcher_bounds = shelf->launcher_widget()->GetNativeView()->bounds(); | |
258 int bottom = | |
259 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom() - shelf_height; | |
260 EXPECT_EQ(launcher_bounds.y(), | |
261 bottom + (shelf->GetIdealBounds().height() - | |
262 launcher_bounds.height()) / 2); | |
263 status_bounds = shelf->status_area_widget()->GetNativeView()->bounds(); | |
264 EXPECT_EQ(status_bounds.y(), | |
265 bottom + shelf_height - status_bounds.height()); | |
266 } | |
267 | |
268 // Makes sure LayoutShelf invoked while animating cleans things up. | |
269 TEST_F(ShelfLayoutManagerTest, LayoutShelfWhileAnimating) { | |
270 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
271 // Force an initial layout. | |
272 shelf->LayoutShelf(); | |
273 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
274 | |
275 const gfx::Display& display = Shell::GetInstance()->display_manager()-> | |
276 GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
277 | |
278 // Hide the shelf. | |
279 SetState(shelf, SHELF_HIDDEN); | |
280 shelf->LayoutShelf(); | |
281 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); | |
282 EXPECT_EQ(0, display.bounds().bottom() - display.work_area().bottom()); | |
283 | |
284 // Make sure the bounds of the two widgets changed. | |
285 EXPECT_GE(shelf->launcher_widget()->GetNativeView()->bounds().y(), | |
286 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom()); | |
287 EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(), | |
288 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom()); | |
289 } | |
290 | |
291 // Makes sure the launcher is initially sized correctly. | |
292 TEST_F(ShelfLayoutManagerTest, LauncherInitiallySized) { | |
293 Launcher* launcher = Launcher::ForPrimaryDisplay(); | |
294 ASSERT_TRUE(launcher); | |
295 ShelfLayoutManager* shelf_layout_manager = GetShelfLayoutManager(); | |
296 ASSERT_TRUE(shelf_layout_manager); | |
297 ASSERT_TRUE(shelf_layout_manager->status_area_widget()); | |
298 int status_width = shelf_layout_manager->status_area_widget()-> | |
299 GetWindowBoundsInScreen().width(); | |
300 // Test only makes sense if the status is > 0, which is better be. | |
301 EXPECT_GT(status_width, 0); | |
302 EXPECT_EQ(status_width, launcher->status_size().width()); | |
303 } | |
304 | |
305 // Makes sure the launcher is sized when the status area changes size. | |
306 TEST_F(ShelfLayoutManagerTest, LauncherUpdatedWhenStatusAreaChangesSize) { | |
307 Launcher* launcher = Launcher::ForPrimaryDisplay(); | |
308 ASSERT_TRUE(launcher); | |
309 ShelfLayoutManager* shelf_layout_manager = GetShelfLayoutManager(); | |
310 ASSERT_TRUE(shelf_layout_manager); | |
311 ASSERT_TRUE(shelf_layout_manager->status_area_widget()); | |
312 shelf_layout_manager->status_area_widget()->SetBounds( | |
313 gfx::Rect(0, 0, 200, 200)); | |
314 EXPECT_EQ(200, launcher->status_size().width()); | |
315 } | |
316 | |
317 // Verifies when the shell is deleted with a full screen window we don't | |
318 // crash. This test is here as originally the crash was in ShelfLayoutManager. | |
319 TEST_F(ShelfLayoutManagerTest, DontReferenceLauncherAfterDeletion) { | |
320 views::Widget* widget = new views::Widget; | |
321 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
322 params.bounds = gfx::Rect(0, 0, 200, 200); | |
323 params.context = CurrentContext(); | |
324 // Widget is now owned by the parent window. | |
325 widget->Init(params); | |
326 widget->SetFullscreen(true); | |
327 } | |
328 | |
329 #if defined(OS_WIN) | |
330 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962 | |
331 #define MAYBE_AutoHide DISABLED_AutoHide | |
332 #else | |
333 #define MAYBE_AutoHide AutoHide | |
334 #endif | |
335 | |
336 // Various assertions around auto-hide. | |
337 TEST_F(ShelfLayoutManagerTest, MAYBE_AutoHide) { | |
338 aura::RootWindow* root = Shell::GetPrimaryRootWindow(); | |
339 aura::test::EventGenerator generator(root, root); | |
340 generator.MoveMouseTo(0, 0); | |
341 | |
342 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
343 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
344 views::Widget* widget = new views::Widget; | |
345 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
346 params.bounds = gfx::Rect(0, 0, 200, 200); | |
347 params.context = CurrentContext(); | |
348 // Widget is now owned by the parent window. | |
349 widget->Init(params); | |
350 widget->Maximize(); | |
351 widget->Show(); | |
352 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
353 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
354 | |
355 // LayoutShelf() forces the animation to completion, at which point the | |
356 // launcher should go off the screen. | |
357 shelf->LayoutShelf(); | |
358 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, | |
359 shelf->launcher_widget()->GetWindowBoundsInScreen().y()); | |
360 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, | |
361 Shell::GetScreen()->GetDisplayNearestWindow( | |
362 root).work_area().bottom()); | |
363 | |
364 // Move the mouse to the bottom of the screen. | |
365 generator.MoveMouseTo(0, root->bounds().bottom() - 1); | |
366 | |
367 // Shelf should be shown again (but it shouldn't have changed the work area). | |
368 SetState(shelf, SHELF_AUTO_HIDE); | |
369 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
370 shelf->LayoutShelf(); | |
371 EXPECT_EQ(root->bounds().bottom() - shelf->GetIdealBounds().height(), | |
372 shelf->launcher_widget()->GetWindowBoundsInScreen().y()); | |
373 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, | |
374 Shell::GetScreen()->GetDisplayNearestWindow( | |
375 root).work_area().bottom()); | |
376 | |
377 // Move mouse back up. | |
378 generator.MoveMouseTo(0, 0); | |
379 SetState(shelf, SHELF_AUTO_HIDE); | |
380 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
381 shelf->LayoutShelf(); | |
382 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, | |
383 shelf->launcher_widget()->GetWindowBoundsInScreen().y()); | |
384 | |
385 // Drag mouse to bottom of screen. | |
386 generator.PressLeftButton(); | |
387 generator.MoveMouseTo(0, root->bounds().bottom() - 1); | |
388 UpdateAutoHideStateNow(); | |
389 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
390 | |
391 generator.ReleaseLeftButton(); | |
392 generator.MoveMouseTo(1, root->bounds().bottom() - 1); | |
393 UpdateAutoHideStateNow(); | |
394 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
395 generator.PressLeftButton(); | |
396 generator.MoveMouseTo(1, root->bounds().bottom() - 1); | |
397 UpdateAutoHideStateNow(); | |
398 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
399 } | |
400 | |
401 // Assertions around the lock screen showing. | |
402 TEST_F(ShelfLayoutManagerTest, VisibleWhenLockScreenShowing) { | |
403 // Since ShelfLayoutManager queries for mouse location, move the mouse so | |
404 // it isn't over the shelf. | |
405 aura::test::EventGenerator generator( | |
406 Shell::GetPrimaryRootWindow(), gfx::Point()); | |
407 generator.MoveMouseTo(0, 0); | |
408 | |
409 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
410 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
411 views::Widget* widget = new views::Widget; | |
412 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
413 params.bounds = gfx::Rect(0, 0, 200, 200); | |
414 params.context = CurrentContext(); | |
415 // Widget is now owned by the parent window. | |
416 widget->Init(params); | |
417 widget->Maximize(); | |
418 widget->Show(); | |
419 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
420 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
421 | |
422 aura::RootWindow* root = Shell::GetPrimaryRootWindow(); | |
423 // LayoutShelf() forces the animation to completion, at which point the | |
424 // launcher should go off the screen. | |
425 shelf->LayoutShelf(); | |
426 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, | |
427 shelf->launcher_widget()->GetWindowBoundsInScreen().y()); | |
428 | |
429 aura::Window* lock_container = Shell::GetContainer( | |
430 Shell::GetPrimaryRootWindow(), | |
431 internal::kShellWindowId_LockScreenContainer); | |
432 | |
433 views::Widget* lock_widget = new views::Widget; | |
434 views::Widget::InitParams lock_params( | |
435 views::Widget::InitParams::TYPE_WINDOW); | |
436 lock_params.bounds = gfx::Rect(0, 0, 200, 200); | |
437 params.context = CurrentContext(); | |
438 lock_params.parent = lock_container; | |
439 // Widget is now owned by the parent window. | |
440 lock_widget->Init(lock_params); | |
441 lock_widget->Maximize(); | |
442 lock_widget->Show(); | |
443 | |
444 // Lock the screen. | |
445 Shell::GetInstance()->delegate()->LockScreen(); | |
446 shelf->UpdateVisibilityState(); | |
447 // Showing a widget in the lock screen should force the shelf to be visibile. | |
448 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
449 | |
450 Shell::GetInstance()->delegate()->UnlockScreen(); | |
451 shelf->UpdateVisibilityState(); | |
452 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
453 } | |
454 | |
455 // Assertions around SetAutoHideBehavior. | |
456 TEST_F(ShelfLayoutManagerTest, SetAutoHideBehavior) { | |
457 // Since ShelfLayoutManager queries for mouse location, move the mouse so | |
458 // it isn't over the shelf. | |
459 aura::test::EventGenerator generator( | |
460 Shell::GetPrimaryRootWindow(), gfx::Point()); | |
461 generator.MoveMouseTo(0, 0); | |
462 | |
463 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
464 views::Widget* widget = new views::Widget; | |
465 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
466 params.bounds = gfx::Rect(0, 0, 200, 200); | |
467 params.context = CurrentContext(); | |
468 // Widget is now owned by the parent window. | |
469 widget->Init(params); | |
470 widget->Show(); | |
471 aura::Window* window = widget->GetNativeWindow(); | |
472 gfx::Rect display_bounds( | |
473 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds()); | |
474 | |
475 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
476 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
477 | |
478 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
479 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
480 | |
481 widget->Maximize(); | |
482 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
483 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow( | |
484 window).work_area().bottom(), | |
485 widget->GetWorkAreaBoundsInScreen().bottom()); | |
486 | |
487 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
488 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
489 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow( | |
490 window).work_area().bottom(), | |
491 widget->GetWorkAreaBoundsInScreen().bottom()); | |
492 | |
493 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
494 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
495 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow( | |
496 window).work_area().bottom(), | |
497 widget->GetWorkAreaBoundsInScreen().bottom()); | |
498 } | |
499 | |
500 // Verifies the shelf is visible when status/launcher is focused. | |
501 TEST_F(ShelfLayoutManagerTest, VisibleWhenStatusOrLauncherFocused) { | |
502 // Since ShelfLayoutManager queries for mouse location, move the mouse so | |
503 // it isn't over the shelf. | |
504 aura::test::EventGenerator generator( | |
505 Shell::GetPrimaryRootWindow(), gfx::Point()); | |
506 generator.MoveMouseTo(0, 0); | |
507 | |
508 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
509 views::Widget* widget = new views::Widget; | |
510 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
511 params.bounds = gfx::Rect(0, 0, 200, 200); | |
512 params.context = CurrentContext(); | |
513 // Widget is now owned by the parent window. | |
514 widget->Init(params); | |
515 widget->Show(); | |
516 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
517 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
518 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
519 | |
520 // Focus the launcher. Have to go through the focus cycler as normal focus | |
521 // requests to it do nothing. | |
522 shelf->launcher()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD); | |
523 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
524 | |
525 widget->Activate(); | |
526 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
527 | |
528 // Trying to activate the status should fail, since we only allow activating | |
529 // it when the user is using the keyboard (i.e. through FocusCycler). | |
530 shelf->status_area_widget()->Activate(); | |
531 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
532 | |
533 shelf->launcher()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD); | |
534 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
535 } | |
536 | |
537 // Makes sure shelf will be visible when app list opens as shelf is in | |
538 // SHELF_VISIBLE state,and toggling app list won't change shelf | |
539 // visibility state. | |
540 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfVisibleState) { | |
541 Shell* shell = Shell::GetInstance(); | |
542 internal::RootWindowController* controller = | |
543 Shell::GetPrimaryRootWindowController(); | |
544 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
545 shelf->LayoutShelf(); | |
546 controller->SetShelfAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
547 | |
548 // Create a normal unmaximized windowm shelf should be visible. | |
549 aura::Window* window = CreateTestWindow(); | |
550 window->SetBounds(gfx::Rect(0, 0, 100, 100)); | |
551 window->Show(); | |
552 EXPECT_FALSE(shell->GetAppListTargetVisibility()); | |
553 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
554 | |
555 // Toggle app list to show, and the shelf stays visible. | |
556 shell->ToggleAppList(NULL); | |
557 EXPECT_TRUE(shell->GetAppListTargetVisibility()); | |
558 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
559 | |
560 // Toggle app list to hide, and the shelf stays visible. | |
561 shell->ToggleAppList(NULL); | |
562 EXPECT_FALSE(shell->GetAppListTargetVisibility()); | |
563 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
564 } | |
565 | |
566 // Makes sure shelf will be shown with SHELF_AUTO_HIDE_SHOWN state | |
567 // when app list opens as shelf is in SHELF_AUTO_HIDE state, and | |
568 // toggling app list won't change shelf visibility state. | |
569 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfAutoHideState) { | |
570 Shell* shell = Shell::GetInstance(); | |
571 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
572 internal::RootWindowController* controller = | |
573 Shell::GetPrimaryRootWindowController(); | |
574 shelf->LayoutShelf(); | |
575 controller->SetShelfAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
576 | |
577 // Create a window and show it in maximized state. | |
578 aura::Window* window = CreateTestWindow(); | |
579 window->SetBounds(gfx::Rect(0, 0, 100, 100)); | |
580 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); | |
581 window->Show(); | |
582 wm::ActivateWindow(window); | |
583 | |
584 EXPECT_FALSE(shell->GetAppListTargetVisibility()); | |
585 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
586 | |
587 // Toggle app list to show. | |
588 shell->ToggleAppList(NULL); | |
589 // The shelf's auto hide state won't be changed until the timer fires, so | |
590 // calling shell->UpdateShelfVisibility() is kind of manually helping it to | |
591 // update the state. | |
592 shell->UpdateShelfVisibility(); | |
593 EXPECT_TRUE(shell->GetAppListTargetVisibility()); | |
594 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
595 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
596 | |
597 // Toggle app list to hide. | |
598 shell->ToggleAppList(NULL); | |
599 EXPECT_FALSE(shell->GetAppListTargetVisibility()); | |
600 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
601 } | |
602 | |
603 // Makes sure shelf will be hidden when app list opens as shelf is in HIDDEN | |
604 // state, and toggling app list won't change shelf visibility state. | |
605 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfHiddenState) { | |
606 Shell* shell = Shell::GetInstance(); | |
607 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
608 // For shelf to be visible, app list is not open in initial state. | |
609 shelf->LayoutShelf(); | |
610 | |
611 // Create a window and make it full screen. | |
612 aura::Window* window = CreateTestWindow(); | |
613 window->SetBounds(gfx::Rect(0, 0, 100, 100)); | |
614 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN); | |
615 window->Show(); | |
616 wm::ActivateWindow(window); | |
617 | |
618 // App list and shelf is not shown. | |
619 EXPECT_FALSE(shell->GetAppListTargetVisibility()); | |
620 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); | |
621 | |
622 // Toggle app list to show. | |
623 shell->ToggleAppList(NULL); | |
624 EXPECT_TRUE(shell->GetAppListTargetVisibility()); | |
625 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); | |
626 | |
627 // Toggle app list to hide. | |
628 shell->ToggleAppList(NULL); | |
629 EXPECT_FALSE(shell->GetAppListTargetVisibility()); | |
630 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); | |
631 } | |
632 | |
633 #if defined(OS_WIN) | |
634 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962 | |
635 #define MAYBE_SetAlignment DISABLED_SetAlignment | |
636 #else | |
637 #define MAYBE_SetAlignment SetAlignment | |
638 #endif | |
639 | |
640 // Tests SHELF_ALIGNMENT_(LEFT, RIGHT, TOP). | |
641 TEST_F(ShelfLayoutManagerTest, MAYBE_SetAlignment) { | |
642 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
643 // Force an initial layout. | |
644 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
645 shelf->LayoutShelf(); | |
646 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
647 | |
648 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT); | |
649 gfx::Rect launcher_bounds( | |
650 shelf->launcher_widget()->GetWindowBoundsInScreen()); | |
651 const internal::DisplayManager* manager = | |
652 Shell::GetInstance()->display_manager(); | |
653 gfx::Display display = | |
654 manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
655 ASSERT_NE(-1, display.id()); | |
656 EXPECT_EQ(shelf->GetIdealBounds().width(), | |
657 display.GetWorkAreaInsets().left()); | |
658 EXPECT_GE( | |
659 launcher_bounds.width(), | |
660 shelf->launcher_widget()->GetContentsView()->GetPreferredSize().width()); | |
661 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, GetSystemTray()->shelf_alignment()); | |
662 StatusAreaWidget* status_area_widget = shelf->status_area_widget(); | |
663 gfx::Rect status_bounds(status_area_widget->GetWindowBoundsInScreen()); | |
664 EXPECT_GE(status_bounds.width(), | |
665 status_area_widget->GetContentsView()->GetPreferredSize().width()); | |
666 EXPECT_EQ(shelf->GetIdealBounds().width(), | |
667 display.GetWorkAreaInsets().left()); | |
668 EXPECT_EQ(0, display.GetWorkAreaInsets().top()); | |
669 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom()); | |
670 EXPECT_EQ(0, display.GetWorkAreaInsets().right()); | |
671 EXPECT_EQ(display.bounds().x(), launcher_bounds.x()); | |
672 EXPECT_EQ(display.bounds().y(), launcher_bounds.y()); | |
673 EXPECT_EQ(display.bounds().height(), launcher_bounds.height()); | |
674 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
675 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
676 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, | |
677 display.GetWorkAreaInsets().left()); | |
678 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, display.work_area().x()); | |
679 | |
680 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
681 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT); | |
682 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
683 launcher_bounds = shelf->launcher_widget()->GetWindowBoundsInScreen(); | |
684 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
685 ASSERT_NE(-1, display.id()); | |
686 EXPECT_EQ(shelf->GetIdealBounds().width(), | |
687 display.GetWorkAreaInsets().right()); | |
688 EXPECT_GE(launcher_bounds.width(), | |
689 shelf->launcher_widget()->GetContentsView()->GetPreferredSize().width()); | |
690 EXPECT_EQ(SHELF_ALIGNMENT_RIGHT, GetSystemTray()->shelf_alignment()); | |
691 status_bounds = gfx::Rect(status_area_widget->GetWindowBoundsInScreen()); | |
692 EXPECT_GE(status_bounds.width(), | |
693 status_area_widget->GetContentsView()->GetPreferredSize().width()); | |
694 EXPECT_EQ(shelf->GetIdealBounds().width(), | |
695 display.GetWorkAreaInsets().right()); | |
696 EXPECT_EQ(0, display.GetWorkAreaInsets().top()); | |
697 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom()); | |
698 EXPECT_EQ(0, display.GetWorkAreaInsets().left()); | |
699 EXPECT_EQ(display.work_area().right(), launcher_bounds.x()); | |
700 EXPECT_EQ(display.bounds().y(), launcher_bounds.y()); | |
701 EXPECT_EQ(display.bounds().height(), launcher_bounds.height()); | |
702 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
703 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
704 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, | |
705 display.GetWorkAreaInsets().right()); | |
706 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, | |
707 display.bounds().right() - display.work_area().right()); | |
708 | |
709 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
710 shelf->SetAlignment(SHELF_ALIGNMENT_TOP); | |
711 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
712 launcher_bounds = shelf->launcher_widget()->GetWindowBoundsInScreen(); | |
713 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
714 ASSERT_NE(-1, display.id()); | |
715 EXPECT_EQ(shelf->GetIdealBounds().height(), | |
716 display.GetWorkAreaInsets().top()); | |
717 EXPECT_GE(launcher_bounds.height(), | |
718 shelf->launcher_widget()->GetContentsView()->GetPreferredSize().height()); | |
719 EXPECT_EQ(SHELF_ALIGNMENT_TOP, GetSystemTray()->shelf_alignment()); | |
720 status_bounds = gfx::Rect(status_area_widget->GetWindowBoundsInScreen()); | |
721 EXPECT_GE(status_bounds.height(), | |
722 status_area_widget->GetContentsView()->GetPreferredSize().height()); | |
723 EXPECT_EQ(shelf->GetIdealBounds().height(), | |
724 display.GetWorkAreaInsets().top()); | |
725 EXPECT_EQ(0, display.GetWorkAreaInsets().right()); | |
726 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom()); | |
727 EXPECT_EQ(0, display.GetWorkAreaInsets().left()); | |
728 EXPECT_EQ(display.work_area().y(), launcher_bounds.bottom()); | |
729 EXPECT_EQ(display.bounds().x(), launcher_bounds.x()); | |
730 EXPECT_EQ(display.bounds().width(), launcher_bounds.width()); | |
731 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
732 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
733 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, | |
734 display.GetWorkAreaInsets().top()); | |
735 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, | |
736 display.work_area().y() - display.bounds().y()); | |
737 } | |
738 | |
739 #if defined(OS_WIN) | |
740 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962 | |
741 #define MAYBE_GestureDrag DISABLED_GestureDrag | |
742 #else | |
743 #define MAYBE_GestureDrag GestureDrag | |
744 #endif | |
745 | |
746 TEST_F(ShelfLayoutManagerTest, MAYBE_GestureDrag) { | |
747 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
748 internal::RootWindowController* controller = | |
749 Shell::GetPrimaryRootWindowController(); | |
750 controller->SetShelfAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
751 shelf->LayoutShelf(); | |
752 | |
753 views::Widget* widget = new views::Widget; | |
754 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
755 params.bounds = gfx::Rect(0, 0, 200, 200); | |
756 params.context = CurrentContext(); | |
757 widget->Init(params); | |
758 widget->Show(); | |
759 widget->Maximize(); | |
760 | |
761 aura::Window* window = widget->GetNativeWindow(); | |
762 | |
763 gfx::Rect shelf_shown = shelf->launcher_widget()->GetWindowBoundsInScreen(); | |
764 gfx::Rect bounds_shelf = window->bounds(); | |
765 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
766 | |
767 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); | |
768 | |
769 // Swipe up on the shelf. This should not change any state. | |
770 gfx::Point start = | |
771 shelf->launcher_widget()->GetWindowBoundsInScreen().CenterPoint(); | |
772 gfx::Point end(start.x(), start.y() + 100); | |
773 | |
774 // Swipe down on the shelf to hide it. | |
775 end.set_y(start.y() + 100); | |
776 generator.GestureScrollSequence(start, end, | |
777 base::TimeDelta::FromMilliseconds(10), 1); | |
778 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
779 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
780 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); | |
781 EXPECT_NE(bounds_shelf.ToString(), window->bounds().ToString()); | |
782 EXPECT_NE(shelf_shown.ToString(), | |
783 shelf->launcher_widget()->GetWindowBoundsInScreen().ToString()); | |
784 | |
785 gfx::Rect bounds_noshelf = window->bounds(); | |
786 gfx::Rect shelf_hidden = shelf->launcher_widget()->GetWindowBoundsInScreen(); | |
787 | |
788 // Swipe up to show the shelf. | |
789 generator.GestureScrollSequence(end, start, | |
790 base::TimeDelta::FromMilliseconds(10), 1); | |
791 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
792 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); | |
793 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString()); | |
794 EXPECT_EQ(shelf_shown.ToString(), | |
795 shelf->launcher_widget()->GetWindowBoundsInScreen().ToString()); | |
796 | |
797 // Swipe up again. The shelf should hide. | |
798 end.set_y(start.y() - 100); | |
799 generator.GestureScrollSequence(start, end, | |
800 base::TimeDelta::FromMilliseconds(10), 1); | |
801 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
802 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
803 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); | |
804 EXPECT_EQ(shelf_hidden.ToString(), | |
805 shelf->launcher_widget()->GetWindowBoundsInScreen().ToString()); | |
806 | |
807 // Swipe up yet again to show it. | |
808 end.set_y(start.y() + 100); | |
809 generator.GestureScrollSequence(end, start, | |
810 base::TimeDelta::FromMilliseconds(10), 1); | |
811 | |
812 // Swipe down very little. It shouldn't change any state. | |
813 end.set_y(start.y() + shelf_shown.height() * 3 / 10); | |
814 generator.GestureScrollSequence(start, end, | |
815 base::TimeDelta::FromMilliseconds(100), 1); | |
816 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
817 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); | |
818 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString()); | |
819 EXPECT_EQ(shelf_shown.ToString(), | |
820 shelf->launcher_widget()->GetWindowBoundsInScreen().ToString()); | |
821 | |
822 // Swipe down again to hide. | |
823 end.set_y(start.y() + 100); | |
824 generator.GestureScrollSequence(start, end, | |
825 base::TimeDelta::FromMilliseconds(10), 1); | |
826 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
827 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
828 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); | |
829 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString()); | |
830 EXPECT_EQ(shelf_hidden.ToString(), | |
831 shelf->launcher_widget()->GetWindowBoundsInScreen().ToString()); | |
832 | |
833 // Swipe up yet again to show it. | |
834 end.set_y(start.y() + 100); | |
835 generator.GestureScrollSequence(end, start, | |
836 base::TimeDelta::FromMilliseconds(10), 1); | |
837 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
838 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); | |
839 | |
840 // Tap on the shelf itself. This should not change anything. | |
841 generator.GestureTapAt(start); | |
842 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
843 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); | |
844 | |
845 // Now, tap on the desktop region (above the shelf). This should hide the | |
846 // shelf. | |
847 gfx::Point tap = start + gfx::Vector2d(0, -90); | |
848 generator.GestureTapAt(tap); | |
849 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
850 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
851 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); | |
852 | |
853 // Make the window fullscreen. | |
854 widget->SetFullscreen(true); | |
855 gfx::Rect bounds_fullscreen = window->bounds(); | |
856 EXPECT_TRUE(widget->IsFullscreen()); | |
857 EXPECT_NE(bounds_noshelf.ToString(), bounds_fullscreen.ToString()); | |
858 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); | |
859 | |
860 // Swipe-up. This should not change anything. | |
861 generator.GestureScrollSequence(end, start, | |
862 base::TimeDelta::FromMilliseconds(10), 1); | |
863 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); | |
864 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); | |
865 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString()); | |
866 } | |
867 | |
868 TEST_F(ShelfLayoutManagerTest, WindowVisibilityDisablesAutoHide) { | |
869 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
870 shelf->LayoutShelf(); | |
871 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
872 | |
873 // Create a visible window so auto-hide behavior is enforced | |
874 views::Widget* dummy = CreateTestWidget(); | |
875 | |
876 // Window visible => auto hide behaves normally. | |
877 shelf->UpdateVisibilityState(); | |
878 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
879 | |
880 // Window minimized => auto hide disabled. | |
881 dummy->Minimize(); | |
882 shelf->UpdateVisibilityState(); | |
883 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
884 | |
885 // Window closed => auto hide disabled. | |
886 dummy->CloseNow(); | |
887 shelf->UpdateVisibilityState(); | |
888 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
889 | |
890 // Multiple window test | |
891 views::Widget* window1 = CreateTestWidget(); | |
892 views::Widget* window2 = CreateTestWidget(); | |
893 | |
894 // both visible => normal autohide | |
895 shelf->UpdateVisibilityState(); | |
896 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
897 | |
898 // either minimzed => normal autohide | |
899 window2->Minimize(); | |
900 shelf->UpdateVisibilityState(); | |
901 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
902 window2->Restore(); | |
903 window1->Minimize(); | |
904 shelf->UpdateVisibilityState(); | |
905 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
906 | |
907 // both minimzed => disable auto hide | |
908 window2->Minimize(); | |
909 shelf->UpdateVisibilityState(); | |
910 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
911 } | |
912 | |
913 #if defined(OS_WIN) | |
914 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962 | |
915 #define MAYBE_GestureRevealsTrayBubble DISABLED_GestureRevealsTrayBubble | |
916 #else | |
917 #define MAYBE_GestureRevealsTrayBubble GestureRevealsTrayBubble | |
918 #endif | |
919 | |
920 TEST_F(ShelfLayoutManagerTest, MAYBE_GestureRevealsTrayBubble) { | |
921 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
922 shelf->LayoutShelf(); | |
923 | |
924 // Create a visible window so auto-hide behavior is enforced. | |
925 CreateTestWidget(); | |
926 | |
927 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); | |
928 SystemTray* tray = GetSystemTray(); | |
929 | |
930 // First, make sure the shelf is visible. | |
931 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
932 EXPECT_FALSE(tray->HasSystemBubble()); | |
933 | |
934 // Now, drag up on the tray to show the bubble. | |
935 gfx::Point start = | |
936 shelf->status_area_widget()->GetWindowBoundsInScreen().CenterPoint(); | |
937 gfx::Point end(start.x(), start.y() - 100); | |
938 generator.GestureScrollSequence(start, end, | |
939 base::TimeDelta::FromMilliseconds(10), 1); | |
940 EXPECT_TRUE(tray->HasSystemBubble()); | |
941 tray->CloseBubbleForTest(); | |
942 RunAllPendingInMessageLoop(); | |
943 EXPECT_FALSE(tray->HasSystemBubble()); | |
944 | |
945 // Drag again, but only a small amount, and slowly. The bubble should not be | |
946 // visible. | |
947 end.set_y(start.y() - 30); | |
948 generator.GestureScrollSequence(start, end, | |
949 base::TimeDelta::FromMilliseconds(500), 100); | |
950 EXPECT_FALSE(tray->HasSystemBubble()); | |
951 | |
952 // Now, hide the shelf. | |
953 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
954 | |
955 // Start a drag from the bezel, and drag up to show both the shelf and the | |
956 // tray bubble. | |
957 start.set_y(start.y() + 100); | |
958 end.set_y(start.y() - 400); | |
959 generator.GestureScrollSequence(start, end, | |
960 base::TimeDelta::FromMilliseconds(10), 1); | |
961 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
962 EXPECT_TRUE(tray->HasSystemBubble()); | |
963 } | |
964 | |
965 TEST_F(ShelfLayoutManagerTest, ShelfFlickerOnTrayActivation) { | |
966 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
967 | |
968 // Create a visible window so auto-hide behavior is enforced. | |
969 CreateTestWidget(); | |
970 | |
971 // Turn on auto-hide for the shelf. | |
972 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
973 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
974 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
975 | |
976 // Show the status menu. That should make the shelf visible again. | |
977 Shell::GetInstance()->accelerator_controller()->PerformAction( | |
978 SHOW_SYSTEM_TRAY_BUBBLE, ui::Accelerator()); | |
979 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
980 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
981 EXPECT_TRUE(GetSystemTray()->HasSystemBubble()); | |
982 | |
983 // Now activate the tray (using the keyboard, instead of using the mouse to | |
984 // make sure the mouse does not alter the auto-hide state in the shelf). | |
985 // This should not trigger any auto-hide state change in the shelf. | |
986 ShelfLayoutObserverTest observer; | |
987 shelf->AddObserver(&observer); | |
988 | |
989 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); | |
990 generator.PressKey(ui::VKEY_SPACE, 0); | |
991 generator.ReleaseKey(ui::VKEY_SPACE, 0); | |
992 EXPECT_TRUE(GetSystemTray()->HasSystemBubble()); | |
993 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
994 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
995 EXPECT_FALSE(observer.changed_auto_hide_state()); | |
996 | |
997 shelf->RemoveObserver(&observer); | |
998 } | |
999 | |
1000 TEST_F(ShelfLayoutManagerTest, WorkAreaChangeWorkspace) { | |
1001 // Make sure the shelf is always visible. | |
1002 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
1003 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
1004 shelf->LayoutShelf(); | |
1005 | |
1006 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
1007 params.bounds = gfx::Rect(0, 0, 200, 200); | |
1008 params.context = CurrentContext(); | |
1009 views::Widget* widget_one = CreateTestWidgetWithParams(params); | |
1010 widget_one->Maximize(); | |
1011 | |
1012 views::Widget* widget_two = CreateTestWidgetWithParams(params); | |
1013 widget_two->Maximize(); | |
1014 widget_two->Activate(); | |
1015 | |
1016 // Both windows are maximized. They should be of the same size. | |
1017 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(), | |
1018 widget_two->GetNativeWindow()->bounds().ToString()); | |
1019 | |
1020 // Now hide the shelf. | |
1021 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
1022 | |
1023 // The active maximized window will get resized to the new work area. However, | |
1024 // the inactive window should not get resized. | |
1025 EXPECT_NE(widget_one->GetNativeWindow()->bounds().ToString(), | |
1026 widget_two->GetNativeWindow()->bounds().ToString()); | |
1027 | |
1028 // Activate the first window. Now, both windows should be of the same size | |
1029 // again. | |
1030 widget_one->Activate(); | |
1031 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(), | |
1032 widget_two->GetNativeWindow()->bounds().ToString()); | |
1033 | |
1034 // Now show the shelf. | |
1035 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
1036 | |
1037 // The active maximized window will get resized to the new work area. However, | |
1038 // the inactive window should not get resized. | |
1039 EXPECT_NE(widget_one->GetNativeWindow()->bounds().ToString(), | |
1040 widget_two->GetNativeWindow()->bounds().ToString()); | |
1041 | |
1042 // Activate the first window. Now, both windows should be of the same size | |
1043 // again. | |
1044 widget_two->Activate(); | |
1045 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(), | |
1046 widget_two->GetNativeWindow()->bounds().ToString()); | |
1047 } | |
1048 | |
1049 // Confirm that the shelf is dimmed only when content is maximized and | |
1050 // shelf is not autohidden. | |
1051 TEST_F(ShelfLayoutManagerTest, Dimming) { | |
1052 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
1053 scoped_ptr<aura::Window> w1(CreateTestWindow()); | |
1054 w1->Show(); | |
1055 wm::ActivateWindow(w1.get()); | |
1056 | |
1057 // Normal window doesn't dim shelf. | |
1058 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); | |
1059 Launcher* launcher = Launcher::ForPrimaryDisplay(); | |
1060 EXPECT_FALSE(launcher->GetDimsShelf()); | |
1061 | |
1062 // Maximized window does. | |
1063 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); | |
1064 EXPECT_TRUE(launcher->GetDimsShelf()); | |
1065 | |
1066 // Change back to normal stops dimming. | |
1067 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); | |
1068 EXPECT_FALSE(launcher->GetDimsShelf()); | |
1069 | |
1070 // Changing back to maximized dims again. | |
1071 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); | |
1072 EXPECT_TRUE(launcher->GetDimsShelf()); | |
1073 | |
1074 // Changing shelf to autohide stops dimming. | |
1075 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
1076 EXPECT_FALSE(launcher->GetDimsShelf()); | |
1077 } | |
1078 | |
1079 // Make sure that the shelf will not hide if the mouse is between a bubble and | |
1080 // the shelf. | |
1081 TEST_F(ShelfLayoutManagerTest, BubbleEnlargesShelfMouseHitArea) { | |
1082 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
1083 StatusAreaWidget* status_area_widget = | |
1084 Shell::GetPrimaryRootWindowController()->status_area_widget(); | |
1085 SystemTray* tray = GetSystemTray(); | |
1086 | |
1087 // Create a visible window so auto-hide behavior is enforced. | |
1088 CreateTestWidget(); | |
1089 | |
1090 shelf->LayoutShelf(); | |
1091 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); | |
1092 | |
1093 // Make two iterations - first without a message bubble which should make | |
1094 // the shelf disappear and then with a message bubble which should keep it | |
1095 // visible. | |
1096 for (int i = 0; i < 2; i++) { | |
1097 // Make sure the shelf is visible and position the mouse over it. Then | |
1098 // allow auto hide. | |
1099 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
1100 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); | |
1101 gfx::Point center = | |
1102 status_area_widget->GetWindowBoundsInScreen().CenterPoint(); | |
1103 generator.MoveMouseTo(center.x(), center.y()); | |
1104 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
1105 EXPECT_TRUE(shelf->IsVisible()); | |
1106 if (!i) { | |
1107 // In our first iteration we make sure there is no bubble. | |
1108 tray->CloseBubbleForTest(); | |
1109 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); | |
1110 } else { | |
1111 // In our second iteration we show a bubble. | |
1112 TestItem *item = new TestItem; | |
1113 tray->AddTrayItem(item); | |
1114 tray->ShowNotificationView(item); | |
1115 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown()); | |
1116 } | |
1117 // Move the pointer over the edge of the shelf. | |
1118 generator.MoveMouseTo( | |
1119 center.x(), status_area_widget->GetWindowBoundsInScreen().y() - 8); | |
1120 shelf->UpdateVisibilityState(); | |
1121 if (i) { | |
1122 EXPECT_TRUE(shelf->IsVisible()); | |
1123 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown()); | |
1124 } else { | |
1125 EXPECT_FALSE(shelf->IsVisible()); | |
1126 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); | |
1127 } | |
1128 } | |
1129 } | |
1130 | |
1131 } // namespace internal | |
1132 } // namespace ash | |
OLD | NEW |