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 "ash/shelf/shelf_layout_manager.h"
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/launcher/launcher_view.h"
14 #include "ash/root_window_controller.h"
15 #include "ash/screen_ash.h"
16 #include "ash/shelf/shelf_widget.h"
17 #include "ash/shell.h"
18 #include "ash/shell_delegate.h"
19 #include "ash/shell_window_ids.h"
20 #include "ash/system/status_area_widget.h"
21 #include "ash/system/tray/system_tray.h"
22 #include "ash/system/tray/system_tray_item.h"
23 #include "ash/test/ash_test_base.h"
24 #include "ash/wm/window_util.h"
25 #include "base/command_line.h"
26 #include "base/utf_string_conversions.h"
27 #include "ui/aura/client/aura_constants.h"
28 #include "ui/aura/root_window.h"
29 #include "ui/aura/test/event_generator.h"
30 #include "ui/aura/window.h"
31 #include "ui/base/animation/animation_container_element.h"
32 #include "ui/compositor/layer.h"
33 #include "ui/compositor/layer_animator.h"
34 #include "ui/gfx/display.h"
35 #include "ui/gfx/screen.h"
36 #include "ui/views/controls/label.h"
37 #include "ui/views/layout/fill_layout.h"
38 #include "ui/views/view.h"
39 #include "ui/views/widget/widget.h"
42 #include "base/win/windows_version.h"
50 void StepWidgetLayerAnimatorToEnd(views::Widget
* widget
) {
51 ui::AnimationContainerElement
* element
=
52 static_cast<ui::AnimationContainerElement
*>(
53 widget
->GetNativeView()->layer()->GetAnimator());
54 element
->Step(base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1));
57 ShelfWidget
* GetShelfWidget() {
58 return Shell::GetPrimaryRootWindowController()->shelf();
61 ShelfLayoutManager
* GetShelfLayoutManager() {
62 return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
65 SystemTray
* GetSystemTray() {
66 return Shell::GetPrimaryRootWindowController()->GetSystemTray();
69 class ShelfDragCallback
{
71 ShelfDragCallback(const gfx::Rect
& not_visible
, const gfx::Rect
& visible
)
72 : not_visible_bounds_(not_visible
),
73 visible_bounds_(visible
),
74 was_visible_on_drag_start_(false) {
75 EXPECT_EQ(not_visible_bounds_
.bottom(), visible_bounds_
.bottom());
78 virtual ~ShelfDragCallback() {
81 void ProcessScroll(ui::EventType type
, const gfx::Vector2dF
& delta
) {
82 if (GetShelfLayoutManager()->visibility_state() == ash::SHELF_HIDDEN
)
85 if (type
== ui::ET_GESTURE_SCROLL_BEGIN
) {
86 scroll_
= gfx::Vector2dF();
87 was_visible_on_drag_start_
= GetShelfLayoutManager()->IsVisible();
91 // The state of the shelf at the end of the gesture is tested separately.
92 if (type
== ui::ET_GESTURE_SCROLL_END
)
95 if (type
== ui::ET_GESTURE_SCROLL_UPDATE
)
98 gfx::Rect shelf_bounds
= GetShelfWidget()->GetWindowBoundsInScreen();
99 EXPECT_EQ(not_visible_bounds_
.bottom(), shelf_bounds
.bottom());
100 EXPECT_EQ(visible_bounds_
.bottom(), shelf_bounds
.bottom());
102 // The shelf should never be smaller than the hidden state.
103 EXPECT_GE(shelf_bounds
.height(), not_visible_bounds_
.height());
105 if (was_visible_on_drag_start_
) {
106 if (scroll_
.y() < 0) {
107 // If dragging up from the visible state, then the shelf should increase
108 // in height, but not as much as the scroll delta.
109 EXPECT_LE(shelf_bounds
.y(), visible_bounds_
.y());
110 EXPECT_LE(abs(shelf_bounds
.y() - visible_bounds_
.y()),
113 if (shelf_bounds
.height() > not_visible_bounds_
.height()) {
114 // If dragging down from the visible state, then the shelf should
115 // decrease in height, until it reaches the minimum height.
116 EXPECT_EQ(shelf_bounds
.y(), visible_bounds_
.y() + (scroll_
.y()));
120 if (fabs(scroll_
.y()) < not_visible_bounds_
.y() - visible_bounds_
.y()) {
121 // Tests that the shelf sticks with the touch point during the drag
122 // until the shelf is completely visible.
123 EXPECT_EQ(shelf_bounds
.y(), not_visible_bounds_
.y() + scroll_
.y());
125 // Tests that after the shelf is completely visible, the shelf starts
126 // resisting the drag.
127 EXPECT_GT(shelf_bounds
.y(), not_visible_bounds_
.y() + scroll_
.y());
133 const gfx::Rect not_visible_bounds_
;
134 const gfx::Rect visible_bounds_
;
135 gfx::Vector2dF scroll_
;
136 bool was_visible_on_drag_start_
;
138 DISALLOW_COPY_AND_ASSIGN(ShelfDragCallback
);
141 class ShelfLayoutObserverTest
: public ShelfLayoutManager::Observer
{
143 ShelfLayoutObserverTest()
144 : changed_auto_hide_state_(false) {
147 virtual ~ShelfLayoutObserverTest() {}
149 bool changed_auto_hide_state() const { return changed_auto_hide_state_
; }
152 virtual void OnAutoHideStateChanged(
153 ShelfAutoHideState new_state
) OVERRIDE
{
154 changed_auto_hide_state_
= true;
157 bool changed_auto_hide_state_
;
159 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutObserverTest
);
162 // Trivial item implementation that tracks its views for testing.
163 class TestItem
: public SystemTrayItem
{
166 : SystemTrayItem(GetSystemTray()),
169 detailed_view_(NULL
),
170 notification_view_(NULL
) {}
172 virtual views::View
* CreateTrayView(user::LoginStatus status
) OVERRIDE
{
173 tray_view_
= new views::View
;
174 // Add a label so it has non-zero width.
175 tray_view_
->SetLayoutManager(new views::FillLayout
);
176 tray_view_
->AddChildView(new views::Label(UTF8ToUTF16("Tray")));
180 virtual views::View
* CreateDefaultView(user::LoginStatus status
) OVERRIDE
{
181 default_view_
= new views::View
;
182 default_view_
->SetLayoutManager(new views::FillLayout
);
183 default_view_
->AddChildView(new views::Label(UTF8ToUTF16("Default")));
184 return default_view_
;
187 virtual views::View
* CreateDetailedView(user::LoginStatus status
) OVERRIDE
{
188 detailed_view_
= new views::View
;
189 detailed_view_
->SetLayoutManager(new views::FillLayout
);
190 detailed_view_
->AddChildView(new views::Label(UTF8ToUTF16("Detailed")));
191 return detailed_view_
;
194 virtual views::View
* CreateNotificationView(
195 user::LoginStatus status
) OVERRIDE
{
196 notification_view_
= new views::View
;
197 return notification_view_
;
200 virtual void DestroyTrayView() OVERRIDE
{
204 virtual void DestroyDefaultView() OVERRIDE
{
205 default_view_
= NULL
;
208 virtual void DestroyDetailedView() OVERRIDE
{
209 detailed_view_
= NULL
;
212 virtual void DestroyNotificationView() OVERRIDE
{
213 notification_view_
= NULL
;
216 virtual void UpdateAfterLoginStatusChange(
217 user::LoginStatus status
) OVERRIDE
{}
219 views::View
* tray_view() const { return tray_view_
; }
220 views::View
* default_view() const { return default_view_
; }
221 views::View
* detailed_view() const { return detailed_view_
; }
222 views::View
* notification_view() const { return notification_view_
; }
225 views::View
* tray_view_
;
226 views::View
* default_view_
;
227 views::View
* detailed_view_
;
228 views::View
* notification_view_
;
230 DISALLOW_COPY_AND_ASSIGN(TestItem
);
235 class ShelfLayoutManagerTest
: public ash::test::AshTestBase
{
237 ShelfLayoutManagerTest() {}
239 void SetState(ShelfLayoutManager
* shelf
,
240 ShelfVisibilityState state
) {
241 shelf
->SetState(state
);
244 void UpdateAutoHideStateNow() {
245 GetShelfLayoutManager()->UpdateAutoHideStateNow();
248 aura::Window
* CreateTestWindow() {
249 aura::Window
* window
= new aura::Window(NULL
);
250 window
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_NORMAL
);
251 window
->SetType(aura::client::WINDOW_TYPE_NORMAL
);
252 window
->Init(ui::LAYER_TEXTURED
);
253 SetDefaultParentByPrimaryRootWindow(window
);
257 views::Widget
* CreateTestWidgetWithParams(
258 const views::Widget::InitParams
& params
) {
259 views::Widget
* out
= new views::Widget
;
265 // Create a simple widget attached to the current context (will
266 // delete on TearDown).
267 views::Widget
* CreateTestWidget() {
268 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
269 params
.bounds
= gfx::Rect(0, 0, 200, 200);
270 params
.context
= CurrentContext();
271 return CreateTestWidgetWithParams(params
);
274 // Overridden from AshTestBase:
275 virtual void SetUp() OVERRIDE
{
276 CommandLine::ForCurrentProcess()->AppendSwitch(
277 ash::switches::kAshEnableTrayDragging
);
278 test::AshTestBase::SetUp();
281 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerTest
);
284 // Fails on Mac only. Need to be implemented. http://crbug.com/111279.
285 #if defined(OS_MACOSX) || defined(OS_WIN)
286 #define MAYBE_SetVisible DISABLED_SetVisible
288 #define MAYBE_SetVisible SetVisible
290 // Makes sure SetVisible updates work area and widget appropriately.
291 TEST_F(ShelfLayoutManagerTest
, MAYBE_SetVisible
) {
292 ShelfWidget
* shelf
= GetShelfWidget();
293 ShelfLayoutManager
* manager
= shelf
->shelf_layout_manager();
294 // Force an initial layout.
295 manager
->LayoutShelf();
296 EXPECT_EQ(SHELF_VISIBLE
, manager
->visibility_state());
298 gfx::Rect
status_bounds(
299 shelf
->status_area_widget()->GetWindowBoundsInScreen());
300 gfx::Rect
launcher_bounds(
301 shelf
->GetWindowBoundsInScreen());
302 int shelf_height
= manager
->GetIdealBounds().height();
304 const gfx::Display
& display
= Shell::GetInstance()->display_manager()->
305 GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
306 ASSERT_NE(-1, display
.id());
307 // Bottom inset should be the max of widget heights.
308 EXPECT_EQ(shelf_height
,
309 display
.bounds().bottom() - display
.work_area().bottom());
312 SetState(manager
, SHELF_HIDDEN
);
313 // Run the animation to completion.
314 StepWidgetLayerAnimatorToEnd(shelf
);
315 StepWidgetLayerAnimatorToEnd(shelf
->status_area_widget());
316 EXPECT_EQ(SHELF_HIDDEN
, manager
->visibility_state());
318 display
.bounds().bottom() - display
.work_area().bottom());
320 // Make sure the bounds of the two widgets changed.
321 EXPECT_GE(shelf
->GetNativeView()->bounds().y(),
322 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
323 EXPECT_GE(shelf
->status_area_widget()->GetNativeView()->bounds().y(),
324 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
326 // And show it again.
327 SetState(manager
, SHELF_VISIBLE
);
328 // Run the animation to completion.
329 StepWidgetLayerAnimatorToEnd(shelf
);
330 StepWidgetLayerAnimatorToEnd(shelf
->status_area_widget());
331 EXPECT_EQ(SHELF_VISIBLE
, manager
->visibility_state());
332 EXPECT_EQ(shelf_height
,
333 display
.bounds().bottom() - display
.work_area().bottom());
335 // Make sure the bounds of the two widgets changed.
336 launcher_bounds
= shelf
->GetNativeView()->bounds();
338 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom() - shelf_height
;
339 EXPECT_EQ(launcher_bounds
.y(),
340 bottom
+ (manager
->GetIdealBounds().height() -
341 launcher_bounds
.height()) / 2);
342 status_bounds
= shelf
->status_area_widget()->GetNativeView()->bounds();
343 EXPECT_EQ(status_bounds
.y(),
344 bottom
+ shelf_height
- status_bounds
.height());
347 // Makes sure LayoutShelf invoked while animating cleans things up.
348 TEST_F(ShelfLayoutManagerTest
, LayoutShelfWhileAnimating
) {
349 ShelfWidget
* shelf
= GetShelfWidget();
350 // Force an initial layout.
351 shelf
->shelf_layout_manager()->LayoutShelf();
352 EXPECT_EQ(SHELF_VISIBLE
, shelf
->shelf_layout_manager()->visibility_state());
354 const gfx::Display
& display
= Shell::GetInstance()->display_manager()->
355 GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
358 SetState(shelf
->shelf_layout_manager(), SHELF_HIDDEN
);
359 shelf
->shelf_layout_manager()->LayoutShelf();
360 EXPECT_EQ(SHELF_HIDDEN
, shelf
->shelf_layout_manager()->visibility_state());
361 EXPECT_EQ(0, display
.bounds().bottom() - display
.work_area().bottom());
363 // Make sure the bounds of the two widgets changed.
364 EXPECT_GE(shelf
->GetNativeView()->bounds().y(),
365 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
366 EXPECT_GE(shelf
->status_area_widget()->GetNativeView()->bounds().y(),
367 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
370 // Makes sure the launcher is sized when the status area changes size.
371 TEST_F(ShelfLayoutManagerTest
, LauncherUpdatedWhenStatusAreaChangesSize
) {
372 Launcher
* launcher
= Launcher::ForPrimaryDisplay();
373 ASSERT_TRUE(launcher
);
374 ShelfWidget
* shelf_widget
= GetShelfWidget();
375 ASSERT_TRUE(shelf_widget
);
376 ASSERT_TRUE(shelf_widget
->status_area_widget());
377 shelf_widget
->status_area_widget()->SetBounds(
378 gfx::Rect(0, 0, 200, 200));
379 EXPECT_EQ(200, shelf_widget
->GetContentsView()->width() -
380 launcher
->GetLauncherViewForTest()->width());
385 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
386 #define MAYBE_AutoHide DISABLED_AutoHide
388 #define MAYBE_AutoHide AutoHide
391 // Various assertions around auto-hide.
392 TEST_F(ShelfLayoutManagerTest
, MAYBE_AutoHide
) {
393 aura::RootWindow
* root
= Shell::GetPrimaryRootWindow();
394 aura::test::EventGenerator
generator(root
, root
);
395 generator
.MoveMouseTo(0, 0);
397 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
398 shelf
->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
399 views::Widget
* widget
= new views::Widget
;
400 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
401 params
.bounds
= gfx::Rect(0, 0, 200, 200);
402 params
.context
= CurrentContext();
403 // Widget is now owned by the parent window.
404 widget
->Init(params
);
407 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
408 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
410 // LayoutShelf() forces the animation to completion, at which point the
411 // launcher should go off the screen.
412 shelf
->LayoutShelf();
413 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
414 GetShelfWidget()->GetWindowBoundsInScreen().y());
415 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
416 Shell::GetScreen()->GetDisplayNearestWindow(
417 root
).work_area().bottom());
419 // Move the mouse to the bottom of the screen.
420 generator
.MoveMouseTo(0, root
->bounds().bottom() - 1);
422 // Shelf should be shown again (but it shouldn't have changed the work area).
423 SetState(shelf
, SHELF_AUTO_HIDE
);
424 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
425 shelf
->LayoutShelf();
426 EXPECT_EQ(root
->bounds().bottom() - shelf
->GetIdealBounds().height(),
427 GetShelfWidget()->GetWindowBoundsInScreen().y());
428 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
429 Shell::GetScreen()->GetDisplayNearestWindow(
430 root
).work_area().bottom());
432 // Move mouse back up.
433 generator
.MoveMouseTo(0, 0);
434 SetState(shelf
, SHELF_AUTO_HIDE
);
435 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
436 shelf
->LayoutShelf();
437 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
438 GetShelfWidget()->GetWindowBoundsInScreen().y());
440 // Drag mouse to bottom of screen.
441 generator
.PressLeftButton();
442 generator
.MoveMouseTo(0, root
->bounds().bottom() - 1);
443 UpdateAutoHideStateNow();
444 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
446 generator
.ReleaseLeftButton();
447 generator
.MoveMouseTo(1, root
->bounds().bottom() - 1);
448 UpdateAutoHideStateNow();
449 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
450 generator
.PressLeftButton();
451 generator
.MoveMouseTo(1, root
->bounds().bottom() - 1);
452 UpdateAutoHideStateNow();
453 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
456 // Assertions around the lock screen showing.
457 TEST_F(ShelfLayoutManagerTest
, VisibleWhenLockScreenShowing
) {
458 // Since ShelfLayoutManager queries for mouse location, move the mouse so
459 // it isn't over the shelf.
460 aura::test::EventGenerator
generator(
461 Shell::GetPrimaryRootWindow(), gfx::Point());
462 generator
.MoveMouseTo(0, 0);
464 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
465 shelf
->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
466 views::Widget
* widget
= new views::Widget
;
467 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
468 params
.bounds
= gfx::Rect(0, 0, 200, 200);
469 params
.context
= CurrentContext();
470 // Widget is now owned by the parent window.
471 widget
->Init(params
);
474 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
475 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
477 aura::RootWindow
* root
= Shell::GetPrimaryRootWindow();
478 // LayoutShelf() forces the animation to completion, at which point the
479 // launcher should go off the screen.
480 shelf
->LayoutShelf();
481 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
482 GetShelfWidget()->GetWindowBoundsInScreen().y());
484 aura::Window
* lock_container
= Shell::GetContainer(
485 Shell::GetPrimaryRootWindow(),
486 internal::kShellWindowId_LockScreenContainer
);
488 views::Widget
* lock_widget
= new views::Widget
;
489 views::Widget::InitParams
lock_params(
490 views::Widget::InitParams::TYPE_WINDOW
);
491 lock_params
.bounds
= gfx::Rect(0, 0, 200, 200);
492 params
.context
= CurrentContext();
493 lock_params
.parent
= lock_container
;
494 // Widget is now owned by the parent window.
495 lock_widget
->Init(lock_params
);
496 lock_widget
->Maximize();
500 Shell::GetInstance()->delegate()->LockScreen();
501 shelf
->UpdateVisibilityState();
502 // Showing a widget in the lock screen should force the shelf to be visibile.
503 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
505 Shell::GetInstance()->delegate()->UnlockScreen();
506 shelf
->UpdateVisibilityState();
507 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
510 // Assertions around SetAutoHideBehavior.
511 TEST_F(ShelfLayoutManagerTest
, SetAutoHideBehavior
) {
512 // Since ShelfLayoutManager queries for mouse location, move the mouse so
513 // it isn't over the shelf.
514 aura::test::EventGenerator
generator(
515 Shell::GetPrimaryRootWindow(), gfx::Point());
516 generator
.MoveMouseTo(0, 0);
518 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
519 views::Widget
* widget
= new views::Widget
;
520 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
521 params
.bounds
= gfx::Rect(0, 0, 200, 200);
522 params
.context
= CurrentContext();
523 // Widget is now owned by the parent window.
524 widget
->Init(params
);
526 aura::Window
* window
= widget
->GetNativeWindow();
527 gfx::Rect
display_bounds(
528 Shell::GetScreen()->GetDisplayNearestWindow(window
).bounds());
530 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
531 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
533 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
534 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
537 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
538 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
539 window
).work_area().bottom(),
540 widget
->GetWorkAreaBoundsInScreen().bottom());
542 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
543 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
544 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
545 window
).work_area().bottom(),
546 widget
->GetWorkAreaBoundsInScreen().bottom());
548 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
549 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
550 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
551 window
).work_area().bottom(),
552 widget
->GetWorkAreaBoundsInScreen().bottom());
555 // Basic assertions around the dimming of the shelf.
556 TEST_F(ShelfLayoutManagerTest
, TestDimmingBehavior
) {
557 // Since ShelfLayoutManager queries for mouse location, move the mouse so
558 // it isn't over the shelf.
559 aura::test::EventGenerator
generator(
560 Shell::GetPrimaryRootWindow(), gfx::Point());
561 generator
.MoveMouseTo(0, 0);
563 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
564 shelf
->shelf_widget()->DisableDimmingAnimationsForTest();
566 views::Widget
* widget
= new views::Widget
;
567 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
568 params
.bounds
= gfx::Rect(0, 0, 200, 200);
569 params
.context
= CurrentContext();
570 // Widget is now owned by the parent window.
571 widget
->Init(params
);
573 aura::Window
* window
= widget
->GetNativeWindow();
574 gfx::Rect
display_bounds(
575 Shell::GetScreen()->GetDisplayNearestWindow(window
).bounds());
577 gfx::Point off_shelf
= display_bounds
.CenterPoint();
578 gfx::Point on_shelf
=
579 shelf
->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
581 // Test there is no dimming object active at this point.
582 generator
.MoveMouseTo(on_shelf
.x(), on_shelf
.y());
583 EXPECT_EQ(-1, shelf
->shelf_widget()->GetDimmingAlphaForTest());
584 generator
.MoveMouseTo(off_shelf
.x(), off_shelf
.y());
585 EXPECT_EQ(-1, shelf
->shelf_widget()->GetDimmingAlphaForTest());
587 // After maximization, the shelf should be visible and the dimmer created.
590 on_shelf
= shelf
->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
591 EXPECT_LT(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
593 // Moving the mouse off the shelf should dim the bar.
594 generator
.MoveMouseTo(off_shelf
.x(), off_shelf
.y());
595 EXPECT_LT(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
597 // Adding touch events outside the shelf should still keep the shelf in
599 generator
.PressTouch();
600 generator
.MoveTouch(off_shelf
);
601 EXPECT_LT(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
602 // Move the touch into the shelf area should undim.
603 generator
.MoveTouch(on_shelf
);
604 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
605 generator
.ReleaseTouch();
606 // And a release dims again.
607 EXPECT_LT(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
609 // Moving the mouse on the shelf should undim the bar.
610 generator
.MoveMouseTo(on_shelf
);
611 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
613 // No matter what the touch events do, the shelf should stay undimmed.
614 generator
.PressTouch();
615 generator
.MoveTouch(off_shelf
);
616 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
617 generator
.MoveTouch(on_shelf
);
618 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
619 generator
.MoveTouch(off_shelf
);
620 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
621 generator
.MoveTouch(on_shelf
);
622 generator
.ReleaseTouch();
624 // After restore, the dimming object should be deleted again.
626 EXPECT_EQ(-1, shelf
->shelf_widget()->GetDimmingAlphaForTest());
629 // Assertions around the dimming of the shelf in conjunction with menus.
630 TEST_F(ShelfLayoutManagerTest
, TestDimmingBehaviorWithMenus
) {
631 // Since ShelfLayoutManager queries for mouse location, move the mouse so
632 // it isn't over the shelf.
633 aura::test::EventGenerator
generator(
634 Shell::GetPrimaryRootWindow(), gfx::Point());
635 generator
.MoveMouseTo(0, 0);
637 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
638 shelf
->shelf_widget()->DisableDimmingAnimationsForTest();
640 views::Widget
* widget
= new views::Widget
;
641 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
642 params
.bounds
= gfx::Rect(0, 0, 200, 200);
643 params
.context
= CurrentContext();
644 // Widget is now owned by the parent window.
645 widget
->Init(params
);
647 aura::Window
* window
= widget
->GetNativeWindow();
648 gfx::Rect
display_bounds(
649 Shell::GetScreen()->GetDisplayNearestWindow(window
).bounds());
651 // After maximization, the shelf should be visible and the dimmer created.
654 gfx::Point off_shelf
= display_bounds
.CenterPoint();
655 gfx::Point on_shelf
=
656 shelf
->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
658 // Moving the mouse on the shelf should undim the bar.
659 generator
.MoveMouseTo(on_shelf
.x(), on_shelf
.y());
660 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
662 // Simulate a menu opening.
663 shelf
->shelf_widget()->ForceUndimming(true);
665 // Moving the mouse off the shelf should not dim the bar.
666 generator
.MoveMouseTo(off_shelf
.x(), off_shelf
.y());
667 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
669 // No matter what the touch events do, the shelf should stay undimmed.
670 generator
.PressTouch();
671 generator
.MoveTouch(off_shelf
);
672 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
673 generator
.MoveTouch(on_shelf
);
674 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
675 generator
.MoveTouch(off_shelf
);
676 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
677 generator
.ReleaseTouch();
678 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
680 // "Closing the menu" should now turn off the menu since no event is inside
681 // the shelf any longer.
682 shelf
->shelf_widget()->ForceUndimming(false);
683 EXPECT_LT(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
685 // Moving the mouse again on the shelf which should undim the bar again.
686 // This time we check that the bar stays undimmed when the mouse remains on
687 // the bar and the "menu gets closed".
688 generator
.MoveMouseTo(on_shelf
.x(), on_shelf
.y());
689 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
690 shelf
->shelf_widget()->ForceUndimming(true);
691 generator
.MoveMouseTo(off_shelf
.x(), off_shelf
.y());
692 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
693 generator
.MoveMouseTo(on_shelf
.x(), on_shelf
.y());
694 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
695 shelf
->shelf_widget()->ForceUndimming(true);
696 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
699 // Verifies the shelf is visible when status/launcher is focused.
700 TEST_F(ShelfLayoutManagerTest
, VisibleWhenStatusOrLauncherFocused
) {
701 // Since ShelfLayoutManager queries for mouse location, move the mouse so
702 // it isn't over the shelf.
703 aura::test::EventGenerator
generator(
704 Shell::GetPrimaryRootWindow(), gfx::Point());
705 generator
.MoveMouseTo(0, 0);
707 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
708 views::Widget
* widget
= new views::Widget
;
709 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
710 params
.bounds
= gfx::Rect(0, 0, 200, 200);
711 params
.context
= CurrentContext();
712 // Widget is now owned by the parent window.
713 widget
->Init(params
);
715 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
716 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
717 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
719 // Focus the launcher. Have to go through the focus cycler as normal focus
720 // requests to it do nothing.
721 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD
);
722 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
725 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
727 // Trying to activate the status should fail, since we only allow activating
728 // it when the user is using the keyboard (i.e. through FocusCycler).
729 GetShelfWidget()->status_area_widget()->Activate();
730 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
732 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD
);
733 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
736 // Makes sure shelf will be visible when app list opens as shelf is in
737 // SHELF_VISIBLE state,and toggling app list won't change shelf
739 TEST_F(ShelfLayoutManagerTest
, OpenAppListWithShelfVisibleState
) {
740 Shell
* shell
= Shell::GetInstance();
741 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
742 shelf
->LayoutShelf();
743 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
745 // Create a normal unmaximized windowm shelf should be visible.
746 aura::Window
* window
= CreateTestWindow();
747 window
->SetBounds(gfx::Rect(0, 0, 100, 100));
749 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
750 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
752 // Toggle app list to show, and the shelf stays visible.
753 shell
->ToggleAppList(NULL
);
754 EXPECT_TRUE(shell
->GetAppListTargetVisibility());
755 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
757 // Toggle app list to hide, and the shelf stays visible.
758 shell
->ToggleAppList(NULL
);
759 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
760 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
763 // Makes sure shelf will be shown with SHELF_AUTO_HIDE_SHOWN state
764 // when app list opens as shelf is in SHELF_AUTO_HIDE state, and
765 // toggling app list won't change shelf visibility state.
766 TEST_F(ShelfLayoutManagerTest
, OpenAppListWithShelfAutoHideState
) {
767 Shell
* shell
= Shell::GetInstance();
768 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
769 shelf
->LayoutShelf();
770 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
772 // Create a window and show it in maximized state.
773 aura::Window
* window
= CreateTestWindow();
774 window
->SetBounds(gfx::Rect(0, 0, 100, 100));
775 window
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
777 wm::ActivateWindow(window
);
779 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
780 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
782 // Toggle app list to show.
783 shell
->ToggleAppList(NULL
);
784 // The shelf's auto hide state won't be changed until the timer fires, so
785 // calling shell->UpdateShelfVisibility() is kind of manually helping it to
787 shell
->UpdateShelfVisibility();
788 EXPECT_TRUE(shell
->GetAppListTargetVisibility());
789 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
790 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
792 // Toggle app list to hide.
793 shell
->ToggleAppList(NULL
);
794 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
795 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
798 // Makes sure shelf will be hidden when app list opens as shelf is in HIDDEN
799 // state, and toggling app list won't change shelf visibility state.
800 TEST_F(ShelfLayoutManagerTest
, OpenAppListWithShelfHiddenState
) {
801 Shell
* shell
= Shell::GetInstance();
802 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
803 // For shelf to be visible, app list is not open in initial state.
804 shelf
->LayoutShelf();
806 // Create a window and make it full screen.
807 aura::Window
* window
= CreateTestWindow();
808 window
->SetBounds(gfx::Rect(0, 0, 100, 100));
809 window
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_FULLSCREEN
);
811 wm::ActivateWindow(window
);
813 // App list and shelf is not shown.
814 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
815 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
817 // Toggle app list to show.
818 shell
->ToggleAppList(NULL
);
819 EXPECT_TRUE(shell
->GetAppListTargetVisibility());
820 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
822 // Toggle app list to hide.
823 shell
->ToggleAppList(NULL
);
824 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
825 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
829 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
830 #define MAYBE_SetAlignment DISABLED_SetAlignment
832 #define MAYBE_SetAlignment SetAlignment
835 // Tests SHELF_ALIGNMENT_(LEFT, RIGHT, TOP).
836 TEST_F(ShelfLayoutManagerTest
, MAYBE_SetAlignment
) {
837 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
838 // Force an initial layout.
839 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
840 shelf
->LayoutShelf();
841 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
843 shelf
->SetAlignment(SHELF_ALIGNMENT_LEFT
);
844 gfx::Rect
launcher_bounds(
845 GetShelfWidget()->GetWindowBoundsInScreen());
846 const internal::DisplayManager
* manager
=
847 Shell::GetInstance()->display_manager();
848 gfx::Display display
=
849 manager
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
850 ASSERT_NE(-1, display
.id());
851 EXPECT_EQ(shelf
->GetIdealBounds().width(),
852 display
.GetWorkAreaInsets().left());
854 launcher_bounds
.width(),
855 GetShelfWidget()->GetContentsView()->GetPreferredSize().width());
856 EXPECT_EQ(SHELF_ALIGNMENT_LEFT
, GetSystemTray()->shelf_alignment());
857 StatusAreaWidget
* status_area_widget
= GetShelfWidget()->status_area_widget();
858 gfx::Rect
status_bounds(status_area_widget
->GetWindowBoundsInScreen());
859 EXPECT_GE(status_bounds
.width(),
860 status_area_widget
->GetContentsView()->GetPreferredSize().width());
861 EXPECT_EQ(shelf
->GetIdealBounds().width(),
862 display
.GetWorkAreaInsets().left());
863 EXPECT_EQ(0, display
.GetWorkAreaInsets().top());
864 EXPECT_EQ(0, display
.GetWorkAreaInsets().bottom());
865 EXPECT_EQ(0, display
.GetWorkAreaInsets().right());
866 EXPECT_EQ(display
.bounds().x(), launcher_bounds
.x());
867 EXPECT_EQ(display
.bounds().y(), launcher_bounds
.y());
868 EXPECT_EQ(display
.bounds().height(), launcher_bounds
.height());
869 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
870 display
= manager
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
871 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
,
872 display
.GetWorkAreaInsets().left());
873 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
, display
.work_area().x());
875 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
876 shelf
->SetAlignment(SHELF_ALIGNMENT_RIGHT
);
877 display
= manager
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
878 launcher_bounds
= GetShelfWidget()->GetWindowBoundsInScreen();
879 display
= manager
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
880 ASSERT_NE(-1, display
.id());
881 EXPECT_EQ(shelf
->GetIdealBounds().width(),
882 display
.GetWorkAreaInsets().right());
883 EXPECT_GE(launcher_bounds
.width(),
884 GetShelfWidget()->GetContentsView()->GetPreferredSize().width());
885 EXPECT_EQ(SHELF_ALIGNMENT_RIGHT
, GetSystemTray()->shelf_alignment());
886 status_bounds
= gfx::Rect(status_area_widget
->GetWindowBoundsInScreen());
887 EXPECT_GE(status_bounds
.width(),
888 status_area_widget
->GetContentsView()->GetPreferredSize().width());
889 EXPECT_EQ(shelf
->GetIdealBounds().width(),
890 display
.GetWorkAreaInsets().right());
891 EXPECT_EQ(0, display
.GetWorkAreaInsets().top());
892 EXPECT_EQ(0, display
.GetWorkAreaInsets().bottom());
893 EXPECT_EQ(0, display
.GetWorkAreaInsets().left());
894 EXPECT_EQ(display
.work_area().right(), launcher_bounds
.x());
895 EXPECT_EQ(display
.bounds().y(), launcher_bounds
.y());
896 EXPECT_EQ(display
.bounds().height(), launcher_bounds
.height());
897 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
898 display
= manager
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
899 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
,
900 display
.GetWorkAreaInsets().right());
901 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
,
902 display
.bounds().right() - display
.work_area().right());
904 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
905 shelf
->SetAlignment(SHELF_ALIGNMENT_TOP
);
906 display
= manager
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
907 launcher_bounds
= GetShelfWidget()->GetWindowBoundsInScreen();
908 display
= manager
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
909 ASSERT_NE(-1, display
.id());
910 EXPECT_EQ(shelf
->GetIdealBounds().height(),
911 display
.GetWorkAreaInsets().top());
912 EXPECT_GE(launcher_bounds
.height(),
913 GetShelfWidget()->GetContentsView()->GetPreferredSize().height());
914 EXPECT_EQ(SHELF_ALIGNMENT_TOP
, GetSystemTray()->shelf_alignment());
915 status_bounds
= gfx::Rect(status_area_widget
->GetWindowBoundsInScreen());
916 EXPECT_GE(status_bounds
.height(),
917 status_area_widget
->GetContentsView()->GetPreferredSize().height());
918 EXPECT_EQ(shelf
->GetIdealBounds().height(),
919 display
.GetWorkAreaInsets().top());
920 EXPECT_EQ(0, display
.GetWorkAreaInsets().right());
921 EXPECT_EQ(0, display
.GetWorkAreaInsets().bottom());
922 EXPECT_EQ(0, display
.GetWorkAreaInsets().left());
923 EXPECT_EQ(display
.work_area().y(), launcher_bounds
.bottom());
924 EXPECT_EQ(display
.bounds().x(), launcher_bounds
.x());
925 EXPECT_EQ(display
.bounds().width(), launcher_bounds
.width());
926 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
927 display
= manager
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
928 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
,
929 display
.GetWorkAreaInsets().top());
930 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
,
931 display
.work_area().y() - display
.bounds().y());
935 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
936 #define MAYBE_GestureDrag DISABLED_GestureDrag
938 #define MAYBE_GestureDrag GestureDrag
941 TEST_F(ShelfLayoutManagerTest
, MAYBE_GestureDrag
) {
942 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
943 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
944 shelf
->LayoutShelf();
946 views::Widget
* widget
= new views::Widget
;
947 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
948 params
.bounds
= gfx::Rect(0, 0, 200, 200);
949 params
.context
= CurrentContext();
950 widget
->Init(params
);
954 aura::Window
* window
= widget
->GetNativeWindow();
956 gfx::Rect shelf_shown
= GetShelfWidget()->GetWindowBoundsInScreen();
957 gfx::Rect bounds_shelf
= window
->bounds();
958 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
960 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
961 shelf
->LayoutShelf();
962 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
964 gfx::Rect bounds_noshelf
= window
->bounds();
965 gfx::Rect shelf_hidden
= GetShelfWidget()->GetWindowBoundsInScreen();
967 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
968 shelf
->LayoutShelf();
970 aura::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
971 const int kNumScrollSteps
= 10;
972 ShelfDragCallback
handler(shelf_hidden
, shelf_shown
);
974 // Swipe up on the shelf. This should not change any state.
975 gfx::Point start
= GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint();
976 gfx::Point
end(start
.x(), start
.y() + 100);
978 // Swipe down on the shelf to hide it.
979 end
.set_y(start
.y() + 100);
980 generator
.GestureScrollSequenceWithCallback(start
, end
,
981 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps
,
982 base::Bind(&ShelfDragCallback::ProcessScroll
,
983 base::Unretained(&handler
)));
984 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
985 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
986 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
987 EXPECT_NE(bounds_shelf
.ToString(), window
->bounds().ToString());
988 EXPECT_NE(shelf_shown
.ToString(),
989 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
991 // Swipe up to show the shelf.
992 generator
.GestureScrollSequenceWithCallback(end
, start
,
993 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps
,
994 base::Bind(&ShelfDragCallback::ProcessScroll
,
995 base::Unretained(&handler
)));
996 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
997 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
, shelf
->auto_hide_behavior());
998 EXPECT_EQ(bounds_shelf
.ToString(), window
->bounds().ToString());
999 EXPECT_EQ(shelf_shown
.ToString(),
1000 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
1002 // Swipe up again. The shelf should hide.
1003 end
.set_y(start
.y() - 100);
1004 generator
.GestureScrollSequenceWithCallback(start
, end
,
1005 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps
,
1006 base::Bind(&ShelfDragCallback::ProcessScroll
,
1007 base::Unretained(&handler
)));
1008 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1009 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1010 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
1011 EXPECT_EQ(shelf_hidden
.ToString(),
1012 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
1014 // Swipe up yet again to show it.
1015 end
.set_y(start
.y() + 100);
1016 generator
.GestureScrollSequenceWithCallback(end
, start
,
1017 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps
,
1018 base::Bind(&ShelfDragCallback::ProcessScroll
,
1019 base::Unretained(&handler
)));
1021 // Swipe down very little. It shouldn't change any state.
1022 end
.set_y(start
.y() + shelf_shown
.height() * 3 / 10);
1023 generator
.GestureScrollSequenceWithCallback(start
, end
,
1024 base::TimeDelta::FromMilliseconds(100), 1,
1025 base::Bind(&ShelfDragCallback::ProcessScroll
,
1026 base::Unretained(&handler
)));
1027 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1028 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
, shelf
->auto_hide_behavior());
1029 EXPECT_EQ(bounds_shelf
.ToString(), window
->bounds().ToString());
1030 EXPECT_EQ(shelf_shown
.ToString(),
1031 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
1033 // Swipe down again to hide.
1034 end
.set_y(start
.y() + 100);
1035 generator
.GestureScrollSequenceWithCallback(start
, end
,
1036 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps
,
1037 base::Bind(&ShelfDragCallback::ProcessScroll
,
1038 base::Unretained(&handler
)));
1039 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1040 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1041 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
1042 EXPECT_EQ(bounds_noshelf
.ToString(), window
->bounds().ToString());
1043 EXPECT_EQ(shelf_hidden
.ToString(),
1044 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
1046 // Make the window fullscreen.
1047 widget
->SetFullscreen(true);
1048 gfx::Rect bounds_fullscreen
= window
->bounds();
1049 EXPECT_TRUE(widget
->IsFullscreen());
1050 EXPECT_NE(bounds_noshelf
.ToString(), bounds_fullscreen
.ToString());
1051 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
1053 // Swipe-up. This should not change anything.
1054 generator
.GestureScrollSequenceWithCallback(end
, start
,
1055 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps
,
1056 base::Bind(&ShelfDragCallback::ProcessScroll
,
1057 base::Unretained(&handler
)));
1058 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
1059 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
1060 EXPECT_EQ(bounds_fullscreen
.ToString(), window
->bounds().ToString());
1063 TEST_F(ShelfLayoutManagerTest
, WindowVisibilityDisablesAutoHide
) {
1064 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1065 shelf
->LayoutShelf();
1066 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1068 // Create a visible window so auto-hide behavior is enforced
1069 views::Widget
* dummy
= CreateTestWidget();
1071 // Window visible => auto hide behaves normally.
1072 shelf
->UpdateVisibilityState();
1073 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1075 // Window minimized => auto hide disabled.
1077 shelf
->UpdateVisibilityState();
1078 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1080 // Window closed => auto hide disabled.
1082 shelf
->UpdateVisibilityState();
1083 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1085 // Multiple window test
1086 views::Widget
* window1
= CreateTestWidget();
1087 views::Widget
* window2
= CreateTestWidget();
1089 // both visible => normal autohide
1090 shelf
->UpdateVisibilityState();
1091 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1093 // either minimzed => normal autohide
1094 window2
->Minimize();
1095 shelf
->UpdateVisibilityState();
1096 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1098 window1
->Minimize();
1099 shelf
->UpdateVisibilityState();
1100 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1102 // both minimzed => disable auto hide
1103 window2
->Minimize();
1104 shelf
->UpdateVisibilityState();
1105 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1109 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1110 #define MAYBE_GestureRevealsTrayBubble DISABLED_GestureRevealsTrayBubble
1112 #define MAYBE_GestureRevealsTrayBubble GestureRevealsTrayBubble
1115 TEST_F(ShelfLayoutManagerTest
, MAYBE_GestureRevealsTrayBubble
) {
1116 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1117 shelf
->LayoutShelf();
1119 // Create a visible window so auto-hide behavior is enforced.
1122 aura::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
1123 SystemTray
* tray
= GetSystemTray();
1125 // First, make sure the shelf is visible.
1126 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
1127 EXPECT_FALSE(tray
->HasSystemBubble());
1129 // Now, drag up on the tray to show the bubble.
1130 gfx::Point start
= GetShelfWidget()->status_area_widget()->
1131 GetWindowBoundsInScreen().CenterPoint();
1132 gfx::Point
end(start
.x(), start
.y() - 100);
1133 generator
.GestureScrollSequence(start
, end
,
1134 base::TimeDelta::FromMilliseconds(10), 1);
1135 EXPECT_TRUE(tray
->HasSystemBubble());
1136 tray
->CloseSystemBubbleForTest();
1137 RunAllPendingInMessageLoop();
1138 EXPECT_FALSE(tray
->HasSystemBubble());
1140 // Drag again, but only a small amount, and slowly. The bubble should not be
1142 end
.set_y(start
.y() - 30);
1143 generator
.GestureScrollSequence(start
, end
,
1144 base::TimeDelta::FromMilliseconds(500), 100);
1145 EXPECT_FALSE(tray
->HasSystemBubble());
1147 // Now, hide the shelf.
1148 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1150 // Start a drag from the bezel, and drag up to show both the shelf and the
1152 start
.set_y(start
.y() + 100);
1153 end
.set_y(start
.y() - 400);
1154 generator
.GestureScrollSequence(start
, end
,
1155 base::TimeDelta::FromMilliseconds(10), 1);
1156 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1157 EXPECT_TRUE(tray
->HasSystemBubble());
1160 TEST_F(ShelfLayoutManagerTest
, ShelfFlickerOnTrayActivation
) {
1161 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1163 // Create a visible window so auto-hide behavior is enforced.
1166 // Turn on auto-hide for the shelf.
1167 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1168 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1169 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1171 // Show the status menu. That should make the shelf visible again.
1172 Shell::GetInstance()->accelerator_controller()->PerformAction(
1173 SHOW_SYSTEM_TRAY_BUBBLE
, ui::Accelerator());
1174 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1175 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1176 EXPECT_TRUE(GetSystemTray()->HasSystemBubble());
1178 // Now activate the tray (using the keyboard, instead of using the mouse to
1179 // make sure the mouse does not alter the auto-hide state in the shelf).
1180 // This should not trigger any auto-hide state change in the shelf.
1181 ShelfLayoutObserverTest observer
;
1182 shelf
->AddObserver(&observer
);
1184 aura::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
1185 generator
.PressKey(ui::VKEY_SPACE
, 0);
1186 generator
.ReleaseKey(ui::VKEY_SPACE
, 0);
1187 EXPECT_TRUE(GetSystemTray()->HasSystemBubble());
1188 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1189 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1190 EXPECT_FALSE(observer
.changed_auto_hide_state());
1192 shelf
->RemoveObserver(&observer
);
1195 TEST_F(ShelfLayoutManagerTest
, WorkAreaChangeWorkspace
) {
1196 // Make sure the shelf is always visible.
1197 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1198 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
1199 shelf
->LayoutShelf();
1201 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
1202 params
.bounds
= gfx::Rect(0, 0, 200, 200);
1203 params
.context
= CurrentContext();
1204 views::Widget
* widget_one
= CreateTestWidgetWithParams(params
);
1205 widget_one
->Maximize();
1207 views::Widget
* widget_two
= CreateTestWidgetWithParams(params
);
1208 widget_two
->Maximize();
1209 widget_two
->Activate();
1211 // Both windows are maximized. They should be of the same size.
1212 EXPECT_EQ(widget_one
->GetNativeWindow()->bounds().ToString(),
1213 widget_two
->GetNativeWindow()->bounds().ToString());
1215 // Now hide the shelf.
1216 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1218 // The active maximized window will get resized to the new work area. However,
1219 // the inactive window should not get resized.
1220 EXPECT_NE(widget_one
->GetNativeWindow()->bounds().ToString(),
1221 widget_two
->GetNativeWindow()->bounds().ToString());
1223 // Activate the first window. Now, both windows should be of the same size
1225 widget_one
->Activate();
1226 EXPECT_EQ(widget_one
->GetNativeWindow()->bounds().ToString(),
1227 widget_two
->GetNativeWindow()->bounds().ToString());
1229 // Now show the shelf.
1230 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
1232 // The active maximized window will get resized to the new work area. However,
1233 // the inactive window should not get resized.
1234 EXPECT_NE(widget_one
->GetNativeWindow()->bounds().ToString(),
1235 widget_two
->GetNativeWindow()->bounds().ToString());
1237 // Activate the first window. Now, both windows should be of the same size
1239 widget_two
->Activate();
1240 EXPECT_EQ(widget_one
->GetNativeWindow()->bounds().ToString(),
1241 widget_two
->GetNativeWindow()->bounds().ToString());
1244 // Confirm that the shelf is dimmed only when content is maximized and
1245 // shelf is not autohidden.
1246 TEST_F(ShelfLayoutManagerTest
, Dimming
) {
1247 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
1248 scoped_ptr
<aura::Window
> w1(CreateTestWindow());
1250 wm::ActivateWindow(w1
.get());
1252 // Normal window doesn't dim shelf.
1253 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_NORMAL
);
1254 ShelfWidget
* shelf
= GetShelfWidget();
1255 EXPECT_FALSE(shelf
->GetDimsShelf());
1257 // Maximized window does.
1258 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
1259 EXPECT_TRUE(shelf
->GetDimsShelf());
1261 // Change back to normal stops dimming.
1262 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_NORMAL
);
1263 EXPECT_FALSE(shelf
->GetDimsShelf());
1265 // Changing back to maximized dims again.
1266 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
1267 EXPECT_TRUE(shelf
->GetDimsShelf());
1269 // Changing shelf to autohide stops dimming.
1270 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1271 EXPECT_FALSE(shelf
->GetDimsShelf());
1274 // Make sure that the shelf will not hide if the mouse is between a bubble and
1276 TEST_F(ShelfLayoutManagerTest
, BubbleEnlargesShelfMouseHitArea
) {
1277 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1278 StatusAreaWidget
* status_area_widget
=
1279 Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
1280 SystemTray
* tray
= GetSystemTray();
1282 // Create a visible window so auto-hide behavior is enforced.
1285 shelf
->LayoutShelf();
1286 aura::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
1288 // Make two iterations - first without a message bubble which should make
1289 // the shelf disappear and then with a message bubble which should keep it
1291 for (int i
= 0; i
< 2; i
++) {
1292 // Make sure the shelf is visible and position the mouse over it. Then
1294 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
1295 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
1297 status_area_widget
->GetWindowBoundsInScreen().CenterPoint();
1298 generator
.MoveMouseTo(center
.x(), center
.y());
1299 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1300 EXPECT_TRUE(shelf
->IsVisible());
1302 // In our first iteration we make sure there is no bubble.
1303 tray
->CloseSystemBubbleForTest();
1304 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
1306 // In our second iteration we show a bubble.
1307 TestItem
*item
= new TestItem
;
1308 tray
->AddTrayItem(item
);
1309 tray
->ShowNotificationView(item
);
1310 EXPECT_TRUE(status_area_widget
->IsMessageBubbleShown());
1312 // Move the pointer over the edge of the shelf.
1313 generator
.MoveMouseTo(
1314 center
.x(), status_area_widget
->GetWindowBoundsInScreen().y() - 8);
1315 shelf
->UpdateVisibilityState();
1317 EXPECT_TRUE(shelf
->IsVisible());
1318 EXPECT_TRUE(status_area_widget
->IsMessageBubbleShown());
1320 EXPECT_FALSE(shelf
->IsVisible());
1321 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
1326 } // namespace internal