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_controller.h"
11 #include "ash/display/display_manager.h"
12 #include "ash/focus_cycler.h"
13 #include "ash/root_window_controller.h"
14 #include "ash/session/session_state_delegate.h"
15 #include "ash/shelf/shelf.h"
16 #include "ash/shelf/shelf_layout_manager_observer.h"
17 #include "ash/shelf/shelf_view.h"
18 #include "ash/shelf/shelf_widget.h"
19 #include "ash/shell.h"
20 #include "ash/shell_window_ids.h"
21 #include "ash/system/status_area_widget.h"
22 #include "ash/system/tray/system_tray.h"
23 #include "ash/system/tray/system_tray_item.h"
24 #include "ash/test/ash_test_base.h"
25 #include "ash/test/shelf_test_api.h"
26 #include "ash/wm/window_state.h"
27 #include "ash/wm/window_util.h"
28 #include "base/command_line.h"
29 #include "base/strings/utf_string_conversions.h"
30 #include "ui/aura/client/aura_constants.h"
31 #include "ui/aura/client/window_tree_client.h"
32 #include "ui/aura/window.h"
33 #include "ui/aura/window_event_dispatcher.h"
34 #include "ui/compositor/layer.h"
35 #include "ui/compositor/layer_animator.h"
36 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
37 #include "ui/events/gesture_detection/gesture_configuration.h"
38 #include "ui/events/test/event_generator.h"
39 #include "ui/gfx/display.h"
40 #include "ui/gfx/screen.h"
41 #include "ui/views/controls/label.h"
42 #include "ui/views/layout/fill_layout.h"
43 #include "ui/views/view.h"
44 #include "ui/views/widget/widget.h"
47 #include "base/win/windows_version.h"
53 void StepWidgetLayerAnimatorToEnd(views::Widget
* widget
) {
54 widget
->GetNativeView()->layer()->GetAnimator()->Step(
55 base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1));
58 ShelfWidget
* GetShelfWidget() {
59 return Shell::GetPrimaryRootWindowController()->shelf();
62 ShelfLayoutManager
* GetShelfLayoutManager() {
63 return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
66 SystemTray
* GetSystemTray() {
67 return Shell::GetPrimaryRootWindowController()->GetSystemTray();
70 // Class which waits till the shelf finishes animating to the target size and
71 // counts the number of animation steps.
72 class ShelfAnimationWaiter
: views::WidgetObserver
{
74 explicit ShelfAnimationWaiter(const gfx::Rect
& target_bounds
)
75 : target_bounds_(target_bounds
),
77 done_waiting_(false) {
78 GetShelfWidget()->AddObserver(this);
81 ~ShelfAnimationWaiter() override
{ GetShelfWidget()->RemoveObserver(this); }
83 // Wait till the shelf finishes animating to its expected bounds.
84 void WaitTillDoneAnimating() {
85 if (IsDoneAnimating())
88 base::MessageLoop::current()->Run();
91 // Returns true if the animation has completed and it was valid.
92 bool WasValidAnimation() const {
93 return done_waiting_
&& animation_steps_
> 0;
97 // Returns true if shelf has finished animating to the target size.
98 bool IsDoneAnimating() const {
99 ShelfLayoutManager
* layout_manager
= GetShelfLayoutManager();
100 gfx::Rect current_bounds
= GetShelfWidget()->GetWindowBoundsInScreen();
101 int size
= layout_manager
->PrimaryAxisValue(current_bounds
.height(),
102 current_bounds
.width());
103 int desired_size
= layout_manager
->PrimaryAxisValue(target_bounds_
.height(),
104 target_bounds_
.width());
105 return (size
== desired_size
);
108 // views::WidgetObserver override.
109 void OnWidgetBoundsChanged(views::Widget
* widget
,
110 const gfx::Rect
& new_bounds
) override
{
115 if (IsDoneAnimating()) {
116 done_waiting_
= true;
117 base::MessageLoop::current()->Quit();
121 gfx::Rect target_bounds_
;
122 int animation_steps_
;
125 DISALLOW_COPY_AND_ASSIGN(ShelfAnimationWaiter
);
128 class ShelfDragCallback
{
130 ShelfDragCallback(const gfx::Rect
& not_visible
, const gfx::Rect
& visible
)
131 : not_visible_bounds_(not_visible
),
132 visible_bounds_(visible
),
133 was_visible_on_drag_start_(false) {
134 EXPECT_EQ(not_visible_bounds_
.bottom(), visible_bounds_
.bottom());
137 virtual ~ShelfDragCallback() {
140 void ProcessScroll(ui::EventType type
, const gfx::Vector2dF
& delta
) {
141 if (GetShelfLayoutManager()->visibility_state() == ash::SHELF_HIDDEN
)
144 if (type
== ui::ET_GESTURE_SCROLL_BEGIN
) {
145 scroll_
= gfx::Vector2dF();
146 was_visible_on_drag_start_
= GetShelfLayoutManager()->IsVisible();
150 // The state of the shelf at the end of the gesture is tested separately.
151 if (type
== ui::ET_GESTURE_SCROLL_END
)
154 if (type
== ui::ET_GESTURE_SCROLL_UPDATE
)
157 gfx::Rect shelf_bounds
= GetShelfWidget()->GetWindowBoundsInScreen();
158 if (GetShelfLayoutManager()->IsHorizontalAlignment()) {
159 EXPECT_EQ(not_visible_bounds_
.bottom(), shelf_bounds
.bottom());
160 EXPECT_EQ(visible_bounds_
.bottom(), shelf_bounds
.bottom());
161 } else if (SHELF_ALIGNMENT_RIGHT
==
162 GetShelfLayoutManager()->GetAlignment()){
163 EXPECT_EQ(not_visible_bounds_
.right(), shelf_bounds
.right());
164 EXPECT_EQ(visible_bounds_
.right(), shelf_bounds
.right());
165 } else if (SHELF_ALIGNMENT_LEFT
==
166 GetShelfLayoutManager()->GetAlignment()) {
167 EXPECT_EQ(not_visible_bounds_
.x(), shelf_bounds
.x());
168 EXPECT_EQ(visible_bounds_
.x(), shelf_bounds
.x());
171 // if the shelf is being dimmed test dimmer bounds as well.
172 if (GetShelfWidget()->GetDimsShelf())
173 EXPECT_EQ(GetShelfWidget()->GetWindowBoundsInScreen(),
174 GetShelfWidget()->GetDimmerBoundsForTest());
176 // The shelf should never be smaller than the hidden state.
177 EXPECT_GE(shelf_bounds
.height(), not_visible_bounds_
.height());
178 float scroll_delta
= GetShelfLayoutManager()->PrimaryAxisValue(
181 bool increasing_drag
=
182 GetShelfLayoutManager()->SelectValueForShelfAlignment(
187 int shelf_size
= GetShelfLayoutManager()->PrimaryAxisValue(
188 shelf_bounds
.height(),
189 shelf_bounds
.width());
190 int visible_bounds_size
= GetShelfLayoutManager()->PrimaryAxisValue(
191 visible_bounds_
.height(),
192 visible_bounds_
.width());
193 int not_visible_bounds_size
= GetShelfLayoutManager()->PrimaryAxisValue(
194 not_visible_bounds_
.height(),
195 not_visible_bounds_
.width());
196 if (was_visible_on_drag_start_
) {
197 if (increasing_drag
) {
198 // If dragging inwards from the visible state, then the shelf should
199 // increase in size, but not more than the scroll delta.
200 EXPECT_LE(visible_bounds_size
, shelf_size
);
201 EXPECT_LE(std::abs(shelf_size
- visible_bounds_size
),
202 std::abs(scroll_delta
));
204 if (shelf_size
> not_visible_bounds_size
) {
205 // If dragging outwards from the visible state, then the shelf
206 // should decrease in size, until it reaches the minimum size.
207 EXPECT_EQ(shelf_size
, visible_bounds_size
- std::abs(scroll_delta
));
211 if (std::abs(scroll_delta
) <
212 visible_bounds_size
- not_visible_bounds_size
) {
213 // Tests that the shelf sticks with the touch point during the drag
214 // until the shelf is completely visible.
215 EXPECT_EQ(shelf_size
, not_visible_bounds_size
+ std::abs(scroll_delta
));
217 // Tests that after the shelf is completely visible, the shelf starts
218 // resisting the drag.
219 EXPECT_LT(shelf_size
, not_visible_bounds_size
+ std::abs(scroll_delta
));
225 const gfx::Rect not_visible_bounds_
;
226 const gfx::Rect visible_bounds_
;
227 gfx::Vector2dF scroll_
;
228 bool was_visible_on_drag_start_
;
230 DISALLOW_COPY_AND_ASSIGN(ShelfDragCallback
);
233 class ShelfLayoutObserverTest
: public ShelfLayoutManagerObserver
{
235 ShelfLayoutObserverTest()
236 : changed_auto_hide_state_(false) {
239 ~ShelfLayoutObserverTest() override
{}
241 bool changed_auto_hide_state() const { return changed_auto_hide_state_
; }
244 void OnAutoHideStateChanged(ShelfAutoHideState new_state
) override
{
245 changed_auto_hide_state_
= true;
248 bool changed_auto_hide_state_
;
250 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutObserverTest
);
253 // Trivial item implementation that tracks its views for testing.
254 class TestItem
: public SystemTrayItem
{
257 : SystemTrayItem(GetSystemTray()),
260 detailed_view_(NULL
),
261 notification_view_(NULL
) {}
263 views::View
* CreateTrayView(user::LoginStatus status
) override
{
264 tray_view_
= new views::View
;
265 // Add a label so it has non-zero width.
266 tray_view_
->SetLayoutManager(new views::FillLayout
);
267 tray_view_
->AddChildView(new views::Label(base::UTF8ToUTF16("Tray")));
271 views::View
* CreateDefaultView(user::LoginStatus status
) override
{
272 default_view_
= new views::View
;
273 default_view_
->SetLayoutManager(new views::FillLayout
);
274 default_view_
->AddChildView(new views::Label(base::UTF8ToUTF16("Default")));
275 return default_view_
;
278 views::View
* CreateDetailedView(user::LoginStatus status
) override
{
279 detailed_view_
= new views::View
;
280 detailed_view_
->SetLayoutManager(new views::FillLayout
);
281 detailed_view_
->AddChildView(
282 new views::Label(base::UTF8ToUTF16("Detailed")));
283 return detailed_view_
;
286 views::View
* CreateNotificationView(user::LoginStatus status
) override
{
287 notification_view_
= new views::View
;
288 return notification_view_
;
291 void DestroyTrayView() override
{ tray_view_
= NULL
; }
293 void DestroyDefaultView() override
{ default_view_
= NULL
; }
295 void DestroyDetailedView() override
{ detailed_view_
= NULL
; }
297 void DestroyNotificationView() override
{ notification_view_
= NULL
; }
299 void UpdateAfterLoginStatusChange(user::LoginStatus status
) override
{}
301 views::View
* tray_view() const { return tray_view_
; }
302 views::View
* default_view() const { return default_view_
; }
303 views::View
* detailed_view() const { return detailed_view_
; }
304 views::View
* notification_view() const { return notification_view_
; }
307 views::View
* tray_view_
;
308 views::View
* default_view_
;
309 views::View
* detailed_view_
;
310 views::View
* notification_view_
;
312 DISALLOW_COPY_AND_ASSIGN(TestItem
);
317 class ShelfLayoutManagerTest
: public ash::test::AshTestBase
{
319 ShelfLayoutManagerTest() {}
321 void SetState(ShelfLayoutManager
* shelf
,
322 ShelfVisibilityState state
) {
323 shelf
->SetState(state
);
326 void UpdateAutoHideStateNow() {
327 GetShelfLayoutManager()->UpdateAutoHideStateNow();
330 aura::Window
* CreateTestWindow() {
331 aura::Window
* window
= new aura::Window(NULL
);
332 window
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_NORMAL
);
333 window
->SetType(ui::wm::WINDOW_TYPE_NORMAL
);
334 window
->Init(aura::WINDOW_LAYER_TEXTURED
);
335 ParentWindowInPrimaryRootWindow(window
);
339 aura::Window
* CreateTestWindowInParent(aura::Window
* root_window
) {
340 aura::Window
* window
= new aura::Window(NULL
);
341 window
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_NORMAL
);
342 window
->SetType(ui::wm::WINDOW_TYPE_NORMAL
);
343 window
->Init(aura::WINDOW_LAYER_TEXTURED
);
344 aura::client::ParentWindowWithContext(window
, root_window
, gfx::Rect());
348 views::Widget
* CreateTestWidgetWithParams(
349 const views::Widget::InitParams
& params
) {
350 views::Widget
* out
= new views::Widget
;
356 // Create a simple widget attached to the current context (will
357 // delete on TearDown).
358 views::Widget
* CreateTestWidget() {
359 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
360 params
.bounds
= gfx::Rect(0, 0, 200, 200);
361 params
.context
= CurrentContext();
362 return CreateTestWidgetWithParams(params
);
365 // Overridden from AshTestBase:
366 void SetUp() override
{
367 base::CommandLine::ForCurrentProcess()->AppendSwitch(
368 ash::switches::kAshEnableTrayDragging
);
369 test::AshTestBase::SetUp();
372 void RunGestureDragTests(gfx::Vector2d
);
374 // Turn on the lock screen.
376 Shell::GetInstance()->session_state_delegate()->LockScreen();
377 // The test session state delegate does not fire the lock state change.
378 Shell::GetInstance()->OnLockStateChanged(true);
381 // Turn off the lock screen.
382 void UnlockScreen() {
383 Shell::GetInstance()->session_state_delegate()->UnlockScreen();
384 // The test session state delegate does not fire the lock state change.
385 Shell::GetInstance()->OnLockStateChanged(false);
388 // Open the add user screen if |show| is true, otherwise end it.
389 void ShowAddUserScreen(bool show
) {
390 ShelfLayoutManager
* manager
= GetShelfWidget()->shelf_layout_manager();
391 manager
->SessionStateChanged(
392 show
? SessionStateDelegate::SESSION_STATE_LOGIN_SECONDARY
:
393 SessionStateDelegate::SESSION_STATE_ACTIVE
);
397 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerTest
);
400 void ShelfLayoutManagerTest::RunGestureDragTests(gfx::Vector2d delta
) {
401 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
402 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
403 views::Widget
* widget
= new views::Widget
;
404 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
405 params
.bounds
= gfx::Rect(0, 0, 200, 200);
406 params
.context
= CurrentContext();
407 widget
->Init(params
);
411 // The time delta should be large enough to prevent accidental fling creation.
412 const base::TimeDelta kTimeDelta
= base::TimeDelta::FromMilliseconds(100);
414 aura::Window
* window
= widget
->GetNativeWindow();
415 shelf
->LayoutShelf();
417 gfx::Rect shelf_shown
= GetShelfWidget()->GetWindowBoundsInScreen();
418 gfx::Rect bounds_shelf
= window
->bounds();
419 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
421 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
422 shelf
->LayoutShelf();
423 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
425 gfx::Rect bounds_noshelf
= window
->bounds();
426 gfx::Rect shelf_hidden
= GetShelfWidget()->GetWindowBoundsInScreen();
428 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
429 shelf
->LayoutShelf();
431 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
432 const int kNumScrollSteps
= 4;
433 ShelfDragCallback
handler(shelf_hidden
, shelf_shown
);
435 // Swipe up on the shelf. This should not change any state.
436 gfx::Point start
= GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint();
437 gfx::Point end
= start
+ delta
;
439 // Swipe down on the shelf to hide it.
440 generator
.GestureScrollSequenceWithCallback(
445 base::Bind(&ShelfDragCallback::ProcessScroll
,
446 base::Unretained(&handler
)));
447 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
448 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
449 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
450 EXPECT_NE(bounds_shelf
.ToString(), window
->bounds().ToString());
451 EXPECT_NE(shelf_shown
.ToString(),
452 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
454 // Swipe up to show the shelf.
455 generator
.GestureScrollSequenceWithCallback(
460 base::Bind(&ShelfDragCallback::ProcessScroll
,
461 base::Unretained(&handler
)));
462 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
463 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
, shelf
->auto_hide_behavior());
464 EXPECT_EQ(bounds_shelf
.ToString(), window
->bounds().ToString());
465 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
466 GetShelfWidget()->GetWindowBoundsInScreen());
467 EXPECT_EQ(shelf_shown
.ToString(),
468 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
470 // Swipe up again. The shelf should hide.
472 generator
.GestureScrollSequenceWithCallback(
477 base::Bind(&ShelfDragCallback::ProcessScroll
,
478 base::Unretained(&handler
)));
479 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
480 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
481 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
482 EXPECT_EQ(shelf_hidden
.ToString(),
483 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
485 // Swipe up yet again to show it.
487 generator
.GestureScrollSequenceWithCallback(
492 base::Bind(&ShelfDragCallback::ProcessScroll
,
493 base::Unretained(&handler
)));
495 // Swipe down very little. It shouldn't change any state.
496 if (GetShelfLayoutManager()->IsHorizontalAlignment())
497 end
.set_y(start
.y() + shelf_shown
.height() * 3 / 10);
498 else if (SHELF_ALIGNMENT_LEFT
== GetShelfLayoutManager()->GetAlignment())
499 end
.set_x(start
.x() - shelf_shown
.width() * 3 / 10);
500 else if (SHELF_ALIGNMENT_RIGHT
== GetShelfLayoutManager()->GetAlignment())
501 end
.set_x(start
.x() + shelf_shown
.width() * 3 / 10);
502 generator
.GestureScrollSequence(start
, end
, kTimeDelta
, 5);
503 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
504 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
, shelf
->auto_hide_behavior());
505 EXPECT_EQ(bounds_shelf
.ToString(), window
->bounds().ToString());
506 EXPECT_EQ(shelf_shown
.ToString(),
507 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
509 // Swipe down again to hide.
511 generator
.GestureScrollSequenceWithCallback(
516 base::Bind(&ShelfDragCallback::ProcessScroll
,
517 base::Unretained(&handler
)));
518 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
519 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
520 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
521 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
522 EXPECT_EQ(bounds_noshelf
.ToString(), window
->bounds().ToString());
523 EXPECT_EQ(shelf_hidden
.ToString(),
524 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
526 // Swipe up in extended hit region to show it.
527 gfx::Point extended_start
= start
;
528 if (GetShelfLayoutManager()->IsHorizontalAlignment())
529 extended_start
.set_y(GetShelfWidget()->GetWindowBoundsInScreen().y() -1);
530 else if (SHELF_ALIGNMENT_LEFT
== GetShelfLayoutManager()->GetAlignment())
531 extended_start
.set_x(
532 GetShelfWidget()->GetWindowBoundsInScreen().right() + 1);
533 else if (SHELF_ALIGNMENT_RIGHT
== GetShelfLayoutManager()->GetAlignment())
534 extended_start
.set_x(GetShelfWidget()->GetWindowBoundsInScreen().x() - 1);
535 end
= extended_start
- delta
;
536 generator
.GestureScrollSequenceWithCallback(
541 base::Bind(&ShelfDragCallback::ProcessScroll
,
542 base::Unretained(&handler
)));
543 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
544 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
, shelf
->auto_hide_behavior());
545 EXPECT_EQ(bounds_shelf
.ToString(), window
->bounds().ToString());
546 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
547 GetShelfWidget()->GetWindowBoundsInScreen());
548 EXPECT_EQ(shelf_shown
.ToString(),
549 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
551 // Swipe down again to hide.
553 generator
.GestureScrollSequenceWithCallback(
558 base::Bind(&ShelfDragCallback::ProcessScroll
,
559 base::Unretained(&handler
)));
560 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
561 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
562 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
563 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
564 EXPECT_EQ(bounds_noshelf
.ToString(), window
->bounds().ToString());
565 EXPECT_EQ(shelf_hidden
.ToString(),
566 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
568 // Swipe up outside the hit area. This should not change anything.
569 gfx::Point outside_start
= gfx::Point(
570 (GetShelfWidget()->GetWindowBoundsInScreen().x() +
571 GetShelfWidget()->GetWindowBoundsInScreen().right())/2,
572 GetShelfWidget()->GetWindowBoundsInScreen().y() - 50);
573 end
= outside_start
+ delta
;
574 generator
.GestureScrollSequence(
575 outside_start
, end
, kTimeDelta
, kNumScrollSteps
);
576 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
577 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
578 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
579 EXPECT_EQ(shelf_hidden
.ToString(),
580 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
582 // Swipe up from below the shelf where a bezel would be, this should show the
584 gfx::Point below_start
= start
;
585 if (GetShelfLayoutManager()->IsHorizontalAlignment())
586 below_start
.set_y(GetShelfWidget()->GetWindowBoundsInScreen().bottom() + 1);
587 else if (SHELF_ALIGNMENT_LEFT
== GetShelfLayoutManager()->GetAlignment())
589 GetShelfWidget()->GetWindowBoundsInScreen().x() - 1);
590 else if (SHELF_ALIGNMENT_RIGHT
== GetShelfLayoutManager()->GetAlignment())
591 below_start
.set_x(GetShelfWidget()->GetWindowBoundsInScreen().right() + 1);
592 end
= below_start
- delta
;
593 generator
.GestureScrollSequence(
594 below_start
, end
, kTimeDelta
, kNumScrollSteps
);
595 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
596 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
, shelf
->auto_hide_behavior());
597 EXPECT_EQ(bounds_shelf
.ToString(), window
->bounds().ToString());
598 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
599 GetShelfWidget()->GetWindowBoundsInScreen());
600 EXPECT_EQ(shelf_shown
.ToString(),
601 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
603 // Swipe down again to hide.
605 generator
.GestureScrollSequenceWithCallback(
610 base::Bind(&ShelfDragCallback::ProcessScroll
,
611 base::Unretained(&handler
)));
612 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
613 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
614 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
615 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
616 EXPECT_EQ(bounds_noshelf
.ToString(), window
->bounds().ToString());
617 EXPECT_EQ(shelf_hidden
.ToString(),
618 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
620 // Put |widget| into fullscreen. Set the shelf to be auto hidden when |widget|
621 // is fullscreen. (eg browser immersive fullscreen).
622 widget
->SetFullscreen(true);
623 wm::GetWindowState(window
)->set_hide_shelf_when_fullscreen(false);
624 shelf
->UpdateVisibilityState();
626 gfx::Rect bounds_fullscreen
= window
->bounds();
627 EXPECT_TRUE(widget
->IsFullscreen());
628 EXPECT_NE(bounds_noshelf
.ToString(), bounds_fullscreen
.ToString());
630 // Swipe up. This should show the shelf.
631 end
= below_start
- delta
;
632 generator
.GestureScrollSequenceWithCallback(
637 base::Bind(&ShelfDragCallback::ProcessScroll
,
638 base::Unretained(&handler
)));
639 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
640 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
641 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
, shelf
->auto_hide_behavior());
642 EXPECT_EQ(shelf_shown
.ToString(),
643 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
644 EXPECT_EQ(bounds_fullscreen
.ToString(), window
->bounds().ToString());
646 // Swipe up again. This should hide the shelf.
647 generator
.GestureScrollSequenceWithCallback(
652 base::Bind(&ShelfDragCallback::ProcessScroll
,
653 base::Unretained(&handler
)));
654 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
655 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
656 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
657 EXPECT_EQ(shelf_hidden
.ToString(),
658 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
659 EXPECT_EQ(bounds_fullscreen
.ToString(), window
->bounds().ToString());
661 // Set the shelf to be hidden when |widget| is fullscreen. (eg tab fullscreen
662 // with or without immersive browser fullscreen).
663 wm::GetWindowState(window
)->set_hide_shelf_when_fullscreen(true);
664 shelf
->UpdateVisibilityState();
665 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
666 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
668 // Swipe-up. This should not change anything.
670 generator
.GestureScrollSequenceWithCallback(
675 base::Bind(&ShelfDragCallback::ProcessScroll
,
676 base::Unretained(&handler
)));
677 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
678 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
679 EXPECT_EQ(bounds_fullscreen
.ToString(), window
->bounds().ToString());
681 // Close actually, otherwise further event may be affected since widget
682 // is fullscreen status.
684 RunAllPendingInMessageLoop();
686 // The shelf should be shown because there are no more visible windows.
687 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
688 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
689 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
691 // Swipe-up to hide. This should have no effect because there are no visible
693 end
= below_start
- delta
;
694 generator
.GestureScrollSequenceWithCallback(
699 base::Bind(&ShelfDragCallback::ProcessScroll
,
700 base::Unretained(&handler
)));
701 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
702 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
703 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
706 // Need to be implemented. http://crbug.com/111279.
708 #define MAYBE_SetVisible DISABLED_SetVisible
710 #define MAYBE_SetVisible SetVisible
712 // Makes sure SetVisible updates work area and widget appropriately.
713 TEST_F(ShelfLayoutManagerTest
, MAYBE_SetVisible
) {
714 ShelfWidget
* shelf
= GetShelfWidget();
715 ShelfLayoutManager
* manager
= shelf
->shelf_layout_manager();
716 // Force an initial layout.
717 manager
->LayoutShelf();
718 EXPECT_EQ(SHELF_VISIBLE
, manager
->visibility_state());
720 gfx::Rect
status_bounds(
721 shelf
->status_area_widget()->GetWindowBoundsInScreen());
722 gfx::Rect
shelf_bounds(
723 shelf
->GetWindowBoundsInScreen());
724 int shelf_height
= manager
->GetIdealBounds().height();
725 gfx::Screen
* screen
= Shell::GetScreen();
726 gfx::Display display
= screen
->GetDisplayNearestWindow(
727 Shell::GetPrimaryRootWindow());
728 ASSERT_NE(-1, display
.id());
729 // Bottom inset should be the max of widget heights.
730 EXPECT_EQ(shelf_height
, display
.GetWorkAreaInsets().bottom());
733 SetState(manager
, SHELF_HIDDEN
);
734 // Run the animation to completion.
735 StepWidgetLayerAnimatorToEnd(shelf
);
736 StepWidgetLayerAnimatorToEnd(shelf
->status_area_widget());
737 EXPECT_EQ(SHELF_HIDDEN
, manager
->visibility_state());
738 display
= screen
->GetDisplayNearestWindow(
739 Shell::GetPrimaryRootWindow());
741 EXPECT_EQ(0, display
.GetWorkAreaInsets().bottom());
743 // Make sure the bounds of the two widgets changed.
744 EXPECT_GE(shelf
->GetNativeView()->bounds().y(),
745 screen
->GetPrimaryDisplay().bounds().bottom());
746 EXPECT_GE(shelf
->status_area_widget()->GetNativeView()->bounds().y(),
747 screen
->GetPrimaryDisplay().bounds().bottom());
749 // And show it again.
750 SetState(manager
, SHELF_VISIBLE
);
751 // Run the animation to completion.
752 StepWidgetLayerAnimatorToEnd(shelf
);
753 StepWidgetLayerAnimatorToEnd(shelf
->status_area_widget());
754 EXPECT_EQ(SHELF_VISIBLE
, manager
->visibility_state());
755 display
= screen
->GetDisplayNearestWindow(
756 Shell::GetPrimaryRootWindow());
757 EXPECT_EQ(shelf_height
, display
.GetWorkAreaInsets().bottom());
759 // Make sure the bounds of the two widgets changed.
760 shelf_bounds
= shelf
->GetNativeView()->bounds();
761 EXPECT_LT(shelf_bounds
.y(), screen
->GetPrimaryDisplay().bounds().bottom());
762 status_bounds
= shelf
->status_area_widget()->GetNativeView()->bounds();
763 EXPECT_LT(status_bounds
.y(),
764 screen
->GetPrimaryDisplay().bounds().bottom());
767 // Makes sure shelf alignment is correct for lock screen.
768 TEST_F(ShelfLayoutManagerTest
, SideAlignmentInteractionWithLockScreen
) {
769 ShelfLayoutManager
* manager
= GetShelfWidget()->shelf_layout_manager();
770 manager
->SetAlignment(SHELF_ALIGNMENT_LEFT
);
771 EXPECT_EQ(SHELF_ALIGNMENT_LEFT
, manager
->GetAlignment());
773 EXPECT_EQ(SHELF_ALIGNMENT_BOTTOM
, manager
->GetAlignment());
775 EXPECT_EQ(SHELF_ALIGNMENT_LEFT
, manager
->GetAlignment());
778 // Makes sure shelf alignment is correct for add user screen.
779 TEST_F(ShelfLayoutManagerTest
, SideAlignmentInteractionWithAddUserScreen
) {
780 ShelfLayoutManager
* manager
= GetShelfWidget()->shelf_layout_manager();
781 manager
->SetAlignment(SHELF_ALIGNMENT_LEFT
);
782 EXPECT_EQ(SHELF_ALIGNMENT_LEFT
, manager
->GetAlignment());
783 ShowAddUserScreen(true);
784 EXPECT_EQ(SHELF_ALIGNMENT_BOTTOM
, manager
->GetAlignment());
785 ShowAddUserScreen(false);
786 EXPECT_EQ(SHELF_ALIGNMENT_LEFT
, manager
->GetAlignment());
789 // Makes sure LayoutShelf invoked while animating cleans things up.
790 TEST_F(ShelfLayoutManagerTest
, LayoutShelfWhileAnimating
) {
791 ShelfWidget
* shelf
= GetShelfWidget();
792 // Force an initial layout.
793 shelf
->shelf_layout_manager()->LayoutShelf();
794 EXPECT_EQ(SHELF_VISIBLE
, shelf
->shelf_layout_manager()->visibility_state());
797 SetState(shelf
->shelf_layout_manager(), SHELF_HIDDEN
);
798 shelf
->shelf_layout_manager()->LayoutShelf();
799 EXPECT_EQ(SHELF_HIDDEN
, shelf
->shelf_layout_manager()->visibility_state());
800 gfx::Display display
= Shell::GetScreen()->GetDisplayNearestWindow(
801 Shell::GetPrimaryRootWindow());
802 EXPECT_EQ(0, display
.GetWorkAreaInsets().bottom());
804 // Make sure the bounds of the two widgets changed.
805 EXPECT_GE(shelf
->GetNativeView()->bounds().y(),
806 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
807 EXPECT_GE(shelf
->status_area_widget()->GetNativeView()->bounds().y(),
808 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
811 // Test that switching to a different visibility state does not restart the
812 // shelf show / hide animation if it is already running. (crbug.com/250918)
813 TEST_F(ShelfLayoutManagerTest
, SetStateWhileAnimating
) {
814 ShelfWidget
* shelf
= GetShelfWidget();
815 SetState(shelf
->shelf_layout_manager(), SHELF_VISIBLE
);
816 gfx::Rect initial_shelf_bounds
= shelf
->GetWindowBoundsInScreen();
817 gfx::Rect initial_status_bounds
=
818 shelf
->status_area_widget()->GetWindowBoundsInScreen();
820 ui::ScopedAnimationDurationScaleMode
normal_animation_duration(
821 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION
);
822 SetState(shelf
->shelf_layout_manager(), SHELF_HIDDEN
);
823 SetState(shelf
->shelf_layout_manager(), SHELF_VISIBLE
);
825 gfx::Rect current_shelf_bounds
= shelf
->GetWindowBoundsInScreen();
826 gfx::Rect current_status_bounds
=
827 shelf
->status_area_widget()->GetWindowBoundsInScreen();
829 const int small_change
= initial_shelf_bounds
.height() / 2;
831 std::abs(initial_shelf_bounds
.height() - current_shelf_bounds
.height()),
834 std::abs(initial_status_bounds
.height() - current_status_bounds
.height()),
838 // Makes sure the shelf is sized when the status area changes size.
839 TEST_F(ShelfLayoutManagerTest
, ShelfUpdatedWhenStatusAreaChangesSize
) {
840 Shelf
* shelf
= Shelf::ForPrimaryDisplay();
842 ShelfWidget
* shelf_widget
= GetShelfWidget();
843 ASSERT_TRUE(shelf_widget
);
844 ASSERT_TRUE(shelf_widget
->status_area_widget());
845 shelf_widget
->status_area_widget()->SetBounds(
846 gfx::Rect(0, 0, 200, 200));
847 EXPECT_EQ(200, shelf_widget
->GetContentsView()->width() -
848 test::ShelfTestAPI(shelf
).shelf_view()->width());
853 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
854 #define MAYBE_AutoHide DISABLED_AutoHide
856 #define MAYBE_AutoHide AutoHide
859 // Various assertions around auto-hide.
860 TEST_F(ShelfLayoutManagerTest
, MAYBE_AutoHide
) {
861 aura::Window
* root
= Shell::GetPrimaryRootWindow();
862 ui::test::EventGenerator
generator(root
, root
);
863 generator
.MoveMouseTo(0, 0);
865 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
866 shelf
->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
867 views::Widget
* widget
= new views::Widget
;
868 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
869 params
.bounds
= gfx::Rect(0, 0, 200, 200);
870 params
.context
= CurrentContext();
871 // Widget is now owned by the parent window.
872 widget
->Init(params
);
875 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
876 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
878 // LayoutShelf() forces the animation to completion, at which point the
879 // shelf should go off the screen.
880 shelf
->LayoutShelf();
881 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
882 GetShelfWidget()->GetWindowBoundsInScreen().y());
883 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
884 Shell::GetScreen()->GetDisplayNearestWindow(
885 root
).work_area().bottom());
887 // Move the mouse to the bottom of the screen.
888 generator
.MoveMouseTo(0, root
->bounds().bottom() - 1);
890 // Shelf should be shown again (but it shouldn't have changed the work area).
891 SetState(shelf
, SHELF_AUTO_HIDE
);
892 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
893 shelf
->LayoutShelf();
894 EXPECT_EQ(root
->bounds().bottom() - shelf
->GetIdealBounds().height(),
895 GetShelfWidget()->GetWindowBoundsInScreen().y());
896 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
897 Shell::GetScreen()->GetDisplayNearestWindow(
898 root
).work_area().bottom());
900 // Move mouse back up.
901 generator
.MoveMouseTo(0, 0);
902 SetState(shelf
, SHELF_AUTO_HIDE
);
903 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
904 shelf
->LayoutShelf();
905 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
906 GetShelfWidget()->GetWindowBoundsInScreen().y());
908 // Drag mouse to bottom of screen.
909 generator
.PressLeftButton();
910 generator
.MoveMouseTo(0, root
->bounds().bottom() - 1);
911 UpdateAutoHideStateNow();
912 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
914 generator
.ReleaseLeftButton();
915 generator
.MoveMouseTo(1, root
->bounds().bottom() - 1);
916 UpdateAutoHideStateNow();
917 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
918 generator
.PressLeftButton();
919 generator
.MoveMouseTo(1, root
->bounds().bottom() - 1);
920 UpdateAutoHideStateNow();
921 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
924 // Test the behavior of the shelf when it is auto hidden and it is on the
925 // boundary between the primary and the secondary display.
926 TEST_F(ShelfLayoutManagerTest
, AutoHideShelfOnScreenBoundary
) {
927 if (!SupportsMultipleDisplays())
930 UpdateDisplay("800x600,800x600");
931 DisplayLayout
display_layout(DisplayLayout::RIGHT
, 0);
932 Shell::GetInstance()->display_manager()->SetLayoutForCurrentDisplays(
934 // Put the primary monitor's shelf on the display boundary.
935 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
936 shelf
->SetAlignment(SHELF_ALIGNMENT_RIGHT
);
938 // Create a window because the shelf is always shown when no windows are
942 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
943 ASSERT_EQ(root_windows
[0],
944 GetShelfWidget()->GetNativeWindow()->GetRootWindow());
946 shelf
->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
947 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
949 int right_edge
= root_windows
[0]->GetBoundsInScreen().right() - 1;
950 int y
= root_windows
[0]->GetBoundsInScreen().y();
952 // Start off the mouse nowhere near the shelf; the shelf should be hidden.
953 ui::test::EventGenerator
& generator(GetEventGenerator());
954 generator
.MoveMouseTo(right_edge
- 50, y
);
955 UpdateAutoHideStateNow();
956 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
958 // Moving the mouse over the light bar (but not to the edge of the screen)
959 // should show the shelf.
960 generator
.MoveMouseTo(right_edge
- 1, y
);
961 UpdateAutoHideStateNow();
962 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
963 EXPECT_EQ(right_edge
- 1, Shell::GetScreen()->GetCursorScreenPoint().x());
965 // Moving the mouse off the light bar should hide the shelf.
966 generator
.MoveMouseTo(right_edge
- 50, y
);
967 UpdateAutoHideStateNow();
968 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
970 // Moving the mouse to the right edge of the screen crossing the light bar
971 // should show the shelf despite the mouse cursor getting warped to the
972 // secondary display.
973 generator
.MoveMouseTo(right_edge
- 1, y
);
974 generator
.MoveMouseTo(right_edge
, y
);
975 UpdateAutoHideStateNow();
976 EXPECT_NE(right_edge
- 1, Shell::GetScreen()->GetCursorScreenPoint().x());
977 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
980 generator
.MoveMouseTo(right_edge
- 50, y
);
981 UpdateAutoHideStateNow();
982 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
984 // Moving the mouse to the right edge of the screen crossing the light bar and
985 // overshooting by a lot should keep the shelf hidden.
986 generator
.MoveMouseTo(right_edge
- 1, y
);
987 generator
.MoveMouseTo(right_edge
+ 50, y
);
988 UpdateAutoHideStateNow();
989 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
991 // Moving the mouse to the right edge of the screen crossing the light bar and
992 // overshooting a bit should show the shelf.
993 generator
.MoveMouseTo(right_edge
- 1, y
);
994 generator
.MoveMouseTo(right_edge
+ 2, y
);
995 UpdateAutoHideStateNow();
996 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
998 // Keeping the mouse close to the left edge of the secondary display after the
999 // shelf is shown should keep the shelf shown.
1000 generator
.MoveMouseTo(right_edge
+ 2, y
+ 1);
1001 UpdateAutoHideStateNow();
1002 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1004 // Moving the mouse far from the left edge of the secondary display should
1006 generator
.MoveMouseTo(right_edge
+ 50, y
);
1007 UpdateAutoHideStateNow();
1008 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1010 // Moving to the left edge of the secondary display without first crossing
1011 // the primary display's right aligned shelf first should not show the shelf.
1012 generator
.MoveMouseTo(right_edge
+ 2, y
);
1013 UpdateAutoHideStateNow();
1014 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1017 // Assertions around the lock screen showing.
1018 TEST_F(ShelfLayoutManagerTest
, VisibleWhenLockScreenShowing
) {
1019 // Since ShelfLayoutManager queries for mouse location, move the mouse so
1020 // it isn't over the shelf.
1021 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow(),
1023 generator
.MoveMouseTo(0, 0);
1025 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1026 shelf
->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1027 views::Widget
* widget
= new views::Widget
;
1028 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
1029 params
.bounds
= gfx::Rect(0, 0, 200, 200);
1030 params
.context
= CurrentContext();
1031 // Widget is now owned by the parent window.
1032 widget
->Init(params
);
1035 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1036 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1038 aura::Window
* root
= Shell::GetPrimaryRootWindow();
1039 // LayoutShelf() forces the animation to completion, at which point the
1040 // shelf should go off the screen.
1041 shelf
->LayoutShelf();
1042 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
1043 GetShelfWidget()->GetWindowBoundsInScreen().y());
1045 aura::Window
* lock_container
= Shell::GetContainer(
1046 Shell::GetPrimaryRootWindow(), kShellWindowId_LockScreenContainer
);
1048 views::Widget
* lock_widget
= new views::Widget
;
1049 views::Widget::InitParams
lock_params(
1050 views::Widget::InitParams::TYPE_WINDOW
);
1051 lock_params
.bounds
= gfx::Rect(0, 0, 200, 200);
1052 params
.context
= CurrentContext();
1053 lock_params
.parent
= lock_container
;
1054 // Widget is now owned by the parent window.
1055 lock_widget
->Init(lock_params
);
1056 lock_widget
->Maximize();
1057 lock_widget
->Show();
1061 // Showing a widget in the lock screen should force the shelf to be visibile.
1062 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1065 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1068 // Assertions around SetAutoHideBehavior.
1069 TEST_F(ShelfLayoutManagerTest
, SetAutoHideBehavior
) {
1070 // Since ShelfLayoutManager queries for mouse location, move the mouse so
1071 // it isn't over the shelf.
1072 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow(),
1074 generator
.MoveMouseTo(0, 0);
1076 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1077 views::Widget
* widget
= new views::Widget
;
1078 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
1079 params
.bounds
= gfx::Rect(0, 0, 200, 200);
1080 params
.context
= CurrentContext();
1081 // Widget is now owned by the parent window.
1082 widget
->Init(params
);
1084 aura::Window
* window
= widget
->GetNativeWindow();
1085 gfx::Rect
display_bounds(
1086 Shell::GetScreen()->GetDisplayNearestWindow(window
).bounds());
1088 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1089 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1091 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
1092 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1095 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1096 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
1097 window
).work_area().bottom(),
1098 widget
->GetWorkAreaBoundsInScreen().bottom());
1100 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1101 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1102 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
1103 window
).work_area().bottom(),
1104 widget
->GetWorkAreaBoundsInScreen().bottom());
1106 ui::ScopedAnimationDurationScaleMode
animation_duration(
1107 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION
);
1109 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
1110 ShelfWidget
* shelf_widget
= GetShelfWidget();
1111 EXPECT_TRUE(shelf_widget
->status_area_widget()->IsVisible());
1112 StepWidgetLayerAnimatorToEnd(shelf_widget
);
1113 StepWidgetLayerAnimatorToEnd(shelf_widget
->status_area_widget());
1114 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1115 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
1116 window
).work_area().bottom(),
1117 widget
->GetWorkAreaBoundsInScreen().bottom());
1120 // Basic assertions around the dimming of the shelf.
1121 TEST_F(ShelfLayoutManagerTest
, DimmingBehavior
) {
1122 // Since ShelfLayoutManager queries for mouse location, move the mouse so
1123 // it isn't over the shelf.
1124 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow(),
1126 generator
.MoveMouseTo(0, 0);
1128 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1129 shelf
->shelf_widget()->DisableDimmingAnimationsForTest();
1131 views::Widget
* widget
= new views::Widget
;
1132 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
1133 params
.bounds
= gfx::Rect(0, 0, 200, 200);
1134 params
.context
= CurrentContext();
1135 // Widget is now owned by the parent window.
1136 widget
->Init(params
);
1138 aura::Window
* window
= widget
->GetNativeWindow();
1139 gfx::Rect
display_bounds(
1140 Shell::GetScreen()->GetDisplayNearestWindow(window
).bounds());
1142 gfx::Point off_shelf
= display_bounds
.CenterPoint();
1143 gfx::Point on_shelf
=
1144 shelf
->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
1146 // Test there is no dimming object active at this point.
1147 generator
.MoveMouseTo(on_shelf
.x(), on_shelf
.y());
1148 EXPECT_EQ(-1, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1149 generator
.MoveMouseTo(off_shelf
.x(), off_shelf
.y());
1150 EXPECT_EQ(-1, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1152 // After maximization, the shelf should be visible and the dimmer created.
1155 on_shelf
= shelf
->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
1156 EXPECT_LT(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1158 // Moving the mouse off the shelf should dim the bar.
1159 generator
.MoveMouseTo(off_shelf
.x(), off_shelf
.y());
1160 EXPECT_LT(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1162 // Adding touch events outside the shelf should still keep the shelf in
1164 generator
.PressTouch();
1165 generator
.MoveTouch(off_shelf
);
1166 EXPECT_LT(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1167 // Move the touch into the shelf area should undim.
1168 generator
.MoveTouch(on_shelf
);
1169 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1170 generator
.ReleaseTouch();
1171 // And a release dims again.
1172 EXPECT_LT(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1174 // Moving the mouse on the shelf should undim the bar.
1175 generator
.MoveMouseTo(on_shelf
);
1176 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1178 // No matter what the touch events do, the shelf should stay undimmed.
1179 generator
.PressTouch();
1180 generator
.MoveTouch(off_shelf
);
1181 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1182 generator
.MoveTouch(on_shelf
);
1183 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1184 generator
.MoveTouch(off_shelf
);
1185 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1186 generator
.MoveTouch(on_shelf
);
1187 generator
.ReleaseTouch();
1189 // After restore, the dimming object should be deleted again.
1191 EXPECT_EQ(-1, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1194 // Test that dimming works correctly with multiple displays.
1195 TEST_F(ShelfLayoutManagerTest
, DimmingBehaviorDualDisplay
) {
1196 if (!SupportsMultipleDisplays())
1199 // Create two displays.
1200 Shell
* shell
= Shell::GetInstance();
1201 UpdateDisplay("0+0-200x200,+200+0-100x100");
1202 EXPECT_EQ(2U, shell
->display_manager()->GetNumDisplays());
1204 DisplayController
* display_controller
= shell
->display_controller();
1205 aura::Window::Windows root_windows
= display_controller
->GetAllRootWindows();
1206 EXPECT_EQ(root_windows
.size(), 2U);
1208 std::vector
<ShelfWidget
*> shelf_widgets
;
1209 for (auto& root_window
: root_windows
) {
1210 ShelfLayoutManager
* shelf
=
1211 GetRootWindowController(root_window
)->GetShelfLayoutManager();
1212 shelf_widgets
.push_back(shelf
->shelf_widget());
1214 // For disabling the dimming animation to work, the animation must be
1215 // disabled prior to creating the dimmer.
1216 shelf_widgets
.back()->DisableDimmingAnimationsForTest();
1218 // Create a maximized window to create the dimmer.
1219 views::Widget
* widget
= new views::Widget
;
1220 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
1221 params
.context
= root_window
;
1222 params
.bounds
= root_window
->GetBoundsInScreen();
1223 params
.show_state
= ui::SHOW_STATE_MAXIMIZED
;
1224 widget
->Init(params
);
1228 ui::test::EventGenerator
& generator(GetEventGenerator());
1230 generator
.MoveMouseTo(root_windows
[0]->GetBoundsInScreen().CenterPoint());
1231 EXPECT_LT(0, shelf_widgets
[0]->GetDimmingAlphaForTest());
1232 EXPECT_LT(0, shelf_widgets
[1]->GetDimmingAlphaForTest());
1234 generator
.MoveMouseTo(
1235 shelf_widgets
[0]->GetWindowBoundsInScreen().CenterPoint());
1236 EXPECT_EQ(0, shelf_widgets
[0]->GetDimmingAlphaForTest());
1237 EXPECT_LT(0, shelf_widgets
[1]->GetDimmingAlphaForTest());
1239 generator
.MoveMouseTo(
1240 shelf_widgets
[1]->GetWindowBoundsInScreen().CenterPoint());
1241 EXPECT_LT(0, shelf_widgets
[0]->GetDimmingAlphaForTest());
1242 EXPECT_EQ(0, shelf_widgets
[1]->GetDimmingAlphaForTest());
1244 generator
.MoveMouseTo(root_windows
[1]->GetBoundsInScreen().CenterPoint());
1245 EXPECT_LT(0, shelf_widgets
[0]->GetDimmingAlphaForTest());
1246 EXPECT_LT(0, shelf_widgets
[1]->GetDimmingAlphaForTest());
1249 // Assertions around the dimming of the shelf in conjunction with menus.
1250 TEST_F(ShelfLayoutManagerTest
, DimmingBehaviorWithMenus
) {
1251 // Since ShelfLayoutManager queries for mouse location, move the mouse so
1252 // it isn't over the shelf.
1253 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow(),
1255 generator
.MoveMouseTo(0, 0);
1257 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1258 shelf
->shelf_widget()->DisableDimmingAnimationsForTest();
1260 views::Widget
* widget
= new views::Widget
;
1261 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
1262 params
.bounds
= gfx::Rect(0, 0, 200, 200);
1263 params
.context
= CurrentContext();
1264 // Widget is now owned by the parent window.
1265 widget
->Init(params
);
1267 aura::Window
* window
= widget
->GetNativeWindow();
1268 gfx::Rect
display_bounds(
1269 Shell::GetScreen()->GetDisplayNearestWindow(window
).bounds());
1271 // After maximization, the shelf should be visible and the dimmer created.
1274 gfx::Point off_shelf
= display_bounds
.CenterPoint();
1275 gfx::Point on_shelf
=
1276 shelf
->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
1278 // Moving the mouse on the shelf should undim the bar.
1279 generator
.MoveMouseTo(on_shelf
.x(), on_shelf
.y());
1280 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1282 // Simulate a menu opening.
1283 shelf
->shelf_widget()->ForceUndimming(true);
1285 // Moving the mouse off the shelf should not dim the bar.
1286 generator
.MoveMouseTo(off_shelf
.x(), off_shelf
.y());
1287 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1289 // No matter what the touch events do, the shelf should stay undimmed.
1290 generator
.PressTouch();
1291 generator
.MoveTouch(off_shelf
);
1292 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1293 generator
.MoveTouch(on_shelf
);
1294 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1295 generator
.MoveTouch(off_shelf
);
1296 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1297 generator
.ReleaseTouch();
1298 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1300 // "Closing the menu" should now turn off the menu since no event is inside
1301 // the shelf any longer.
1302 shelf
->shelf_widget()->ForceUndimming(false);
1303 EXPECT_LT(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1305 // Moving the mouse again on the shelf which should undim the bar again.
1306 // This time we check that the bar stays undimmed when the mouse remains on
1307 // the bar and the "menu gets closed".
1308 generator
.MoveMouseTo(on_shelf
.x(), on_shelf
.y());
1309 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1310 shelf
->shelf_widget()->ForceUndimming(true);
1311 generator
.MoveMouseTo(off_shelf
.x(), off_shelf
.y());
1312 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1313 generator
.MoveMouseTo(on_shelf
.x(), on_shelf
.y());
1314 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1315 shelf
->shelf_widget()->ForceUndimming(true);
1316 EXPECT_EQ(0, shelf
->shelf_widget()->GetDimmingAlphaForTest());
1319 // Verifies the shelf is visible when status/shelf is focused.
1320 TEST_F(ShelfLayoutManagerTest
, VisibleWhenStatusOrShelfFocused
) {
1321 // Since ShelfLayoutManager queries for mouse location, move the mouse so
1322 // it isn't over the shelf.
1323 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow(),
1325 generator
.MoveMouseTo(0, 0);
1327 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1328 views::Widget
* widget
= new views::Widget
;
1329 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
1330 params
.bounds
= gfx::Rect(0, 0, 200, 200);
1331 params
.context
= CurrentContext();
1332 // Widget is now owned by the parent window.
1333 widget
->Init(params
);
1335 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1336 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1337 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1339 // Focus the shelf. Have to go through the focus cycler as normal focus
1340 // requests to it do nothing.
1341 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD
);
1342 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1345 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1347 // Trying to activate the status should fail, since we only allow activating
1348 // it when the user is using the keyboard (i.e. through FocusCycler).
1349 GetShelfWidget()->status_area_widget()->Activate();
1350 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1352 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD
);
1353 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1356 // Makes sure shelf will be visible when app list opens as shelf is in
1357 // SHELF_VISIBLE state,and toggling app list won't change shelf
1358 // visibility state.
1359 TEST_F(ShelfLayoutManagerTest
, OpenAppListWithShelfVisibleState
) {
1360 Shell
* shell
= Shell::GetInstance();
1361 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1362 shelf
->LayoutShelf();
1363 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
1365 // Create a normal unmaximized windowm shelf should be visible.
1366 aura::Window
* window
= CreateTestWindow();
1367 window
->SetBounds(gfx::Rect(0, 0, 100, 100));
1369 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
1370 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1372 // Show app list and the shelf stays visible.
1373 shell
->ShowAppList(NULL
);
1374 EXPECT_TRUE(shell
->GetAppListTargetVisibility());
1375 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1377 // Hide app list and the shelf stays visible.
1378 shell
->DismissAppList();
1379 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
1380 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1383 // Makes sure shelf will be shown with SHELF_AUTO_HIDE_SHOWN state
1384 // when app list opens as shelf is in SHELF_AUTO_HIDE state, and
1385 // toggling app list won't change shelf visibility state.
1386 TEST_F(ShelfLayoutManagerTest
, OpenAppListWithShelfAutoHideState
) {
1387 Shell
* shell
= Shell::GetInstance();
1388 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1389 shelf
->LayoutShelf();
1390 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1392 // Create a window and show it in maximized state.
1393 aura::Window
* window
= CreateTestWindow();
1394 window
->SetBounds(gfx::Rect(0, 0, 100, 100));
1395 window
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
1397 wm::ActivateWindow(window
);
1399 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
1400 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1403 shell
->ShowAppList(NULL
);
1404 // The shelf's auto hide state won't be changed until the timer fires, so
1405 // calling shell->UpdateShelfVisibility() is kind of manually helping it to
1406 // update the state.
1407 shell
->UpdateShelfVisibility();
1408 EXPECT_TRUE(shell
->GetAppListTargetVisibility());
1409 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1410 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1413 shell
->DismissAppList();
1414 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
1415 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1418 // Makes sure that when we have dual displays, with one or both shelves are set
1419 // to AutoHide, viewing the AppList on one of them doesn't unhide the other
1421 TEST_F(ShelfLayoutManagerTest
, DualDisplayOpenAppListWithShelfAutoHideState
) {
1422 if (!SupportsMultipleDisplays())
1425 // Create two displays.
1426 Shell
* shell
= Shell::GetInstance();
1427 DisplayManager
* display_manager
= shell
->display_manager();
1428 EXPECT_EQ(1U, display_manager
->GetNumDisplays());
1429 UpdateDisplay("0+0-200x200,+200+0-100x100");
1430 EXPECT_EQ(2U, display_manager
->GetNumDisplays());
1432 DisplayController
* display_controller
= shell
->display_controller();
1433 aura::Window::Windows root_windows
= display_controller
->GetAllRootWindows();
1434 EXPECT_EQ(root_windows
.size(), 2U);
1436 // Get the shelves in both displays and set them to be 'AutoHide'.
1437 ShelfLayoutManager
* shelf_1
=
1438 GetRootWindowController(root_windows
[0])->GetShelfLayoutManager();
1439 ShelfLayoutManager
* shelf_2
=
1440 GetRootWindowController(root_windows
[1])->GetShelfLayoutManager();
1441 EXPECT_NE(shelf_1
, shelf_2
);
1442 EXPECT_NE(shelf_1
->shelf_widget()->GetNativeWindow()->GetRootWindow(),
1443 shelf_2
->shelf_widget()->GetNativeWindow()->
1445 shelf_1
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1446 shelf_1
->LayoutShelf();
1447 shelf_2
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1448 shelf_2
->LayoutShelf();
1450 // Create a window in each display and show them in maximized state.
1451 aura::Window
* window_1
=
1452 CreateTestWindowInParent(root_windows
[0]);
1453 window_1
->SetBounds(gfx::Rect(0, 0, 100, 100));
1454 window_1
->SetProperty(aura::client::kShowStateKey
,
1455 ui::SHOW_STATE_MAXIMIZED
);
1457 aura::Window
* window_2
=
1458 CreateTestWindowInParent(root_windows
[1]);
1459 window_2
->SetBounds(gfx::Rect(201, 0, 100, 100));
1460 window_2
->SetProperty(aura::client::kShowStateKey
,
1461 ui::SHOW_STATE_MAXIMIZED
);
1464 EXPECT_EQ(shelf_1
->shelf_widget()->GetNativeWindow()->GetRootWindow(),
1465 window_1
->GetRootWindow());
1466 EXPECT_EQ(shelf_2
->shelf_widget()->GetNativeWindow()->GetRootWindow(),
1467 window_2
->GetRootWindow());
1469 // Activate one window in one display and manually trigger the update of shelf
1471 wm::ActivateWindow(window_1
);
1472 shell
->UpdateShelfVisibility();
1474 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
1475 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf_1
->visibility_state());
1476 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf_2
->visibility_state());
1477 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf_1
->auto_hide_state());
1478 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf_2
->auto_hide_state());
1481 shell
->ShowAppList(NULL
);
1482 shell
->UpdateShelfVisibility();
1484 // Only the shelf in the active display should be shown, the other is hidden.
1485 EXPECT_TRUE(shell
->GetAppListTargetVisibility());
1486 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf_1
->visibility_state());
1487 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf_1
->auto_hide_state());
1488 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf_2
->visibility_state());
1489 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf_2
->auto_hide_state());
1491 // Hide app list, both shelves should be hidden.
1492 shell
->DismissAppList();
1493 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
1494 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf_1
->visibility_state());
1495 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf_2
->visibility_state());
1496 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf_1
->auto_hide_state());
1497 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf_2
->auto_hide_state());
1500 // Makes sure shelf will be hidden when app list opens as shelf is in HIDDEN
1501 // state, and toggling app list won't change shelf visibility state.
1502 TEST_F(ShelfLayoutManagerTest
, OpenAppListWithShelfHiddenState
) {
1503 Shell
* shell
= Shell::GetInstance();
1504 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1505 // For shelf to be visible, app list is not open in initial state.
1506 shelf
->LayoutShelf();
1508 // Create a window and make it full screen.
1509 aura::Window
* window
= CreateTestWindow();
1510 window
->SetBounds(gfx::Rect(0, 0, 100, 100));
1511 window
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_FULLSCREEN
);
1513 wm::ActivateWindow(window
);
1515 // App list and shelf is not shown.
1516 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
1517 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
1520 shell
->ShowAppList(NULL
);
1521 EXPECT_TRUE(shell
->GetAppListTargetVisibility());
1522 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
1525 shell
->DismissAppList();
1526 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
1527 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
1530 // Tests the correct behavior of the shelf when there is a system modal window
1531 // open when we have a single display.
1532 TEST_F(ShelfLayoutManagerTest
, ShelfWithSystemModalWindowSingleDisplay
) {
1533 Shell
* shell
= Shell::GetInstance();
1534 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1535 shelf
->LayoutShelf();
1536 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1538 aura::Window
* window
= CreateTestWindow();
1539 window
->SetBounds(gfx::Rect(0, 0, 100, 100));
1540 window
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
1542 wm::ActivateWindow(window
);
1544 // Enable system modal dialog, and make sure shelf is still hidden.
1545 shell
->SimulateModalWindowOpenForTesting(true);
1546 EXPECT_TRUE(shell
->IsSystemModalWindowOpen());
1547 EXPECT_FALSE(wm::CanActivateWindow(window
));
1548 shell
->UpdateShelfVisibility();
1549 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1550 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1553 // Tests the correct behavior of the shelf when there is a system modal window
1554 // open when we have dual display.
1555 TEST_F(ShelfLayoutManagerTest
, ShelfWithSystemModalWindowDualDisplay
) {
1556 if (!SupportsMultipleDisplays())
1559 // Create two displays.
1560 Shell
* shell
= Shell::GetInstance();
1561 DisplayManager
* display_manager
= shell
->display_manager();
1562 UpdateDisplay("200x200,100x100");
1563 EXPECT_EQ(2U, display_manager
->GetNumDisplays());
1565 DisplayController
* display_controller
= shell
->display_controller();
1566 aura::Window::Windows root_windows
= display_controller
->GetAllRootWindows();
1567 EXPECT_EQ(root_windows
.size(), 2U);
1569 // Get the shelves in both displays and set them to be 'AutoHide'.
1570 ShelfLayoutManager
* shelf_1
=
1571 GetRootWindowController(root_windows
[0])->GetShelfLayoutManager();
1572 ShelfLayoutManager
* shelf_2
=
1573 GetRootWindowController(root_windows
[1])->GetShelfLayoutManager();
1574 EXPECT_NE(shelf_1
, shelf_2
);
1575 EXPECT_NE(shelf_1
->shelf_widget()->GetNativeWindow()->GetRootWindow(),
1576 shelf_2
->shelf_widget()->GetNativeWindow()->GetRootWindow());
1577 shelf_1
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1578 shelf_1
->LayoutShelf();
1579 shelf_2
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1580 shelf_2
->LayoutShelf();
1582 // Create a window in each display and show them in maximized state.
1583 aura::Window
* window_1
= CreateTestWindowInParent(root_windows
[0]);
1584 window_1
->SetBounds(gfx::Rect(0, 0, 100, 100));
1585 window_1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
1587 aura::Window
* window_2
= CreateTestWindowInParent(root_windows
[1]);
1588 window_2
->SetBounds(gfx::Rect(201, 0, 100, 100));
1589 window_2
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
1592 EXPECT_EQ(shelf_1
->shelf_widget()->GetNativeWindow()->GetRootWindow(),
1593 window_1
->GetRootWindow());
1594 EXPECT_EQ(shelf_2
->shelf_widget()->GetNativeWindow()->GetRootWindow(),
1595 window_2
->GetRootWindow());
1596 EXPECT_TRUE(window_1
->IsVisible());
1597 EXPECT_TRUE(window_2
->IsVisible());
1599 // Enable system modal dialog, and make sure both shelves are still hidden.
1600 shell
->SimulateModalWindowOpenForTesting(true);
1601 EXPECT_TRUE(shell
->IsSystemModalWindowOpen());
1602 EXPECT_FALSE(wm::CanActivateWindow(window_1
));
1603 EXPECT_FALSE(wm::CanActivateWindow(window_2
));
1604 shell
->UpdateShelfVisibility();
1605 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf_1
->visibility_state());
1606 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf_1
->auto_hide_state());
1607 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf_2
->visibility_state());
1608 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf_2
->auto_hide_state());
1611 // Tests that the shelf is only hidden for a fullscreen window at the front and
1612 // toggles visibility when another window is activated.
1613 TEST_F(ShelfLayoutManagerTest
, FullscreenWindowInFrontHidesShelf
) {
1614 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1616 // Create a window and make it full screen.
1617 aura::Window
* window1
= CreateTestWindow();
1618 window1
->SetBounds(gfx::Rect(0, 0, 100, 100));
1619 window1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_FULLSCREEN
);
1622 aura::Window
* window2
= CreateTestWindow();
1623 window2
->SetBounds(gfx::Rect(0, 0, 100, 100));
1626 wm::GetWindowState(window1
)->Activate();
1627 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
1629 wm::GetWindowState(window2
)->Activate();
1630 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1632 wm::GetWindowState(window1
)->Activate();
1633 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
1636 // Test the behavior of the shelf when a window on one display is fullscreen
1637 // but the other display has the active window.
1638 TEST_F(ShelfLayoutManagerTest
, FullscreenWindowOnSecondDisplay
) {
1639 if (!SupportsMultipleDisplays())
1642 UpdateDisplay("800x600,800x600");
1643 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
1644 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
1645 Shell::RootWindowControllerList root_window_controllers
=
1646 Shell::GetAllRootWindowControllers();
1648 // Create windows on either display.
1649 aura::Window
* window1
= CreateTestWindow();
1650 window1
->SetBoundsInScreen(
1651 gfx::Rect(0, 0, 100, 100),
1652 display_manager
->GetDisplayAt(0));
1653 window1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_FULLSCREEN
);
1656 aura::Window
* window2
= CreateTestWindow();
1657 window2
->SetBoundsInScreen(
1658 gfx::Rect(800, 0, 100, 100),
1659 display_manager
->GetDisplayAt(1));
1662 EXPECT_EQ(root_windows
[0], window1
->GetRootWindow());
1663 EXPECT_EQ(root_windows
[1], window2
->GetRootWindow());
1665 wm::GetWindowState(window2
)->Activate();
1666 EXPECT_EQ(SHELF_HIDDEN
,
1667 root_window_controllers
[0]->GetShelfLayoutManager()->visibility_state());
1668 EXPECT_EQ(SHELF_VISIBLE
,
1669 root_window_controllers
[1]->GetShelfLayoutManager()->visibility_state());
1674 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1675 #define MAYBE_SetAlignment DISABLED_SetAlignment
1677 #define MAYBE_SetAlignment SetAlignment
1680 // Tests SHELF_ALIGNMENT_(LEFT, RIGHT, TOP).
1681 TEST_F(ShelfLayoutManagerTest
, MAYBE_SetAlignment
) {
1682 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1683 // Force an initial layout.
1684 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
1685 shelf
->LayoutShelf();
1686 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1688 shelf
->SetAlignment(SHELF_ALIGNMENT_LEFT
);
1689 gfx::Rect
shelf_bounds(
1690 GetShelfWidget()->GetWindowBoundsInScreen());
1691 const gfx::Screen
* screen
= Shell::GetScreen();
1692 gfx::Display display
=
1693 screen
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1694 ASSERT_NE(-1, display
.id());
1695 EXPECT_EQ(shelf
->GetIdealBounds().width(),
1696 display
.GetWorkAreaInsets().left());
1698 shelf_bounds
.width(),
1699 GetShelfWidget()->GetContentsView()->GetPreferredSize().width());
1700 EXPECT_EQ(SHELF_ALIGNMENT_LEFT
, GetSystemTray()->shelf_alignment());
1701 StatusAreaWidget
* status_area_widget
= GetShelfWidget()->status_area_widget();
1702 gfx::Rect
status_bounds(status_area_widget
->GetWindowBoundsInScreen());
1703 EXPECT_GE(status_bounds
.width(),
1704 status_area_widget
->GetContentsView()->GetPreferredSize().width());
1705 EXPECT_EQ(shelf
->GetIdealBounds().width(),
1706 display
.GetWorkAreaInsets().left());
1707 EXPECT_EQ(0, display
.GetWorkAreaInsets().top());
1708 EXPECT_EQ(0, display
.GetWorkAreaInsets().bottom());
1709 EXPECT_EQ(0, display
.GetWorkAreaInsets().right());
1710 EXPECT_EQ(display
.bounds().x(), shelf_bounds
.x());
1711 EXPECT_EQ(display
.bounds().y(), shelf_bounds
.y());
1712 EXPECT_EQ(display
.bounds().height(), shelf_bounds
.height());
1713 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1714 display
= screen
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1715 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
,
1716 display
.GetWorkAreaInsets().left());
1717 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
, display
.work_area().x());
1719 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
1720 shelf
->SetAlignment(SHELF_ALIGNMENT_RIGHT
);
1721 display
= screen
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1722 shelf_bounds
= GetShelfWidget()->GetWindowBoundsInScreen();
1723 display
= screen
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1724 ASSERT_NE(-1, display
.id());
1725 EXPECT_EQ(shelf
->GetIdealBounds().width(),
1726 display
.GetWorkAreaInsets().right());
1727 EXPECT_GE(shelf_bounds
.width(),
1728 GetShelfWidget()->GetContentsView()->GetPreferredSize().width());
1729 EXPECT_EQ(SHELF_ALIGNMENT_RIGHT
, GetSystemTray()->shelf_alignment());
1730 status_bounds
= gfx::Rect(status_area_widget
->GetWindowBoundsInScreen());
1731 EXPECT_GE(status_bounds
.width(),
1732 status_area_widget
->GetContentsView()->GetPreferredSize().width());
1733 EXPECT_EQ(shelf
->GetIdealBounds().width(),
1734 display
.GetWorkAreaInsets().right());
1735 EXPECT_EQ(0, display
.GetWorkAreaInsets().top());
1736 EXPECT_EQ(0, display
.GetWorkAreaInsets().bottom());
1737 EXPECT_EQ(0, display
.GetWorkAreaInsets().left());
1738 EXPECT_EQ(display
.work_area().right(), shelf_bounds
.x());
1739 EXPECT_EQ(display
.bounds().y(), shelf_bounds
.y());
1740 EXPECT_EQ(display
.bounds().height(), shelf_bounds
.height());
1741 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1742 display
= screen
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1743 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
,
1744 display
.GetWorkAreaInsets().right());
1745 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
,
1746 display
.bounds().right() - display
.work_area().right());
1748 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
1749 shelf
->SetAlignment(SHELF_ALIGNMENT_TOP
);
1750 display
= screen
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1751 shelf_bounds
= GetShelfWidget()->GetWindowBoundsInScreen();
1752 display
= screen
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1753 ASSERT_NE(-1, display
.id());
1754 EXPECT_EQ(shelf
->GetIdealBounds().height(),
1755 display
.GetWorkAreaInsets().top());
1756 EXPECT_GE(shelf_bounds
.height(),
1757 GetShelfWidget()->GetContentsView()->GetPreferredSize().height());
1758 EXPECT_EQ(SHELF_ALIGNMENT_TOP
, GetSystemTray()->shelf_alignment());
1759 status_bounds
= gfx::Rect(status_area_widget
->GetWindowBoundsInScreen());
1760 EXPECT_GE(status_bounds
.height(),
1761 status_area_widget
->GetContentsView()->GetPreferredSize().height());
1762 EXPECT_EQ(shelf
->GetIdealBounds().height(),
1763 display
.GetWorkAreaInsets().top());
1764 EXPECT_EQ(0, display
.GetWorkAreaInsets().right());
1765 EXPECT_EQ(0, display
.GetWorkAreaInsets().bottom());
1766 EXPECT_EQ(0, display
.GetWorkAreaInsets().left());
1767 EXPECT_EQ(display
.work_area().y(), shelf_bounds
.bottom());
1768 EXPECT_EQ(display
.bounds().x(), shelf_bounds
.x());
1769 EXPECT_EQ(display
.bounds().width(), shelf_bounds
.width());
1770 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1771 display
= screen
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1772 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
,
1773 display
.GetWorkAreaInsets().top());
1774 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
,
1775 display
.work_area().y() - display
.bounds().y());
1778 TEST_F(ShelfLayoutManagerTest
, GestureEdgeSwipe
) {
1779 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1780 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
1781 views::Widget
* widget
= new views::Widget
;
1782 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
1783 params
.bounds
= gfx::Rect(0, 0, 200, 200);
1784 params
.context
= CurrentContext();
1785 widget
->Init(params
);
1789 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
1791 aura::Window
* window
= widget
->GetNativeWindow();
1792 shelf
->LayoutShelf();
1794 gfx::Rect shelf_shown
= GetShelfWidget()->GetWindowBoundsInScreen();
1795 gfx::Rect bounds_shelf
= window
->bounds();
1797 // Edge swipe when SHELF_VISIBLE should not change visibility state.
1798 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1799 generator
.GestureEdgeSwipe();
1800 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1802 // Edge swipe when AUTO_HIDE_HIDDEN should change to AUTO_HIDE_SHOWN.
1803 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1804 shelf
->LayoutShelf();
1805 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1806 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1807 generator
.GestureEdgeSwipe();
1808 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1809 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1811 widget
->SetFullscreen(true);
1812 wm::GetWindowState(window
)->set_hide_shelf_when_fullscreen(false);
1813 shelf
->UpdateVisibilityState();
1815 // Edge swipe in fullscreen + AUTO_HIDE_HIDDEN should show the shelf and
1816 // remain fullscreen.
1817 EXPECT_TRUE(widget
->IsFullscreen());
1818 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1819 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1820 generator
.GestureEdgeSwipe();
1821 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1822 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1823 EXPECT_TRUE(widget
->IsFullscreen());
1827 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1828 #define MAYBE_GestureDrag DISABLED_GestureDrag
1830 #define MAYBE_GestureDrag GestureDrag
1833 TEST_F(ShelfLayoutManagerTest
, MAYBE_GestureDrag
) {
1834 // Slop is an implementation detail of gesture recognition, and complicates
1835 // these tests. Ignore it.
1836 ui::GestureConfiguration::GetInstance()
1837 ->set_max_touch_move_in_pixels_for_click(0);
1838 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1840 SCOPED_TRACE("BOTTOM");
1841 RunGestureDragTests(gfx::Vector2d(0, 120));
1845 SCOPED_TRACE("LEFT");
1846 shelf
->SetAlignment(SHELF_ALIGNMENT_LEFT
);
1847 RunGestureDragTests(gfx::Vector2d(-120, 0));
1851 SCOPED_TRACE("RIGHT");
1852 shelf
->SetAlignment(SHELF_ALIGNMENT_RIGHT
);
1853 RunGestureDragTests(gfx::Vector2d(120, 0));
1857 TEST_F(ShelfLayoutManagerTest
, WindowVisibilityDisablesAutoHide
) {
1858 if (!SupportsMultipleDisplays())
1861 UpdateDisplay("800x600,800x600");
1862 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1863 shelf
->LayoutShelf();
1864 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1866 // Create a visible window so auto-hide behavior is enforced
1867 views::Widget
* dummy
= CreateTestWidget();
1869 // Window visible => auto hide behaves normally.
1870 shelf
->UpdateVisibilityState();
1871 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1873 // Window minimized => auto hide disabled.
1875 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1877 // Window closed => auto hide disabled.
1879 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1881 // Multiple window test
1882 views::Widget
* window1
= CreateTestWidget();
1883 views::Widget
* window2
= CreateTestWidget();
1885 // both visible => normal autohide
1886 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1888 // either minimzed => normal autohide
1889 window2
->Minimize();
1890 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1892 window1
->Minimize();
1893 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1895 // both minimized => disable auto hide
1896 window2
->Minimize();
1897 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1899 // Test moving windows to/from other display.
1901 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1902 // Move to second display.
1903 window2
->SetBounds(gfx::Rect(850, 50, 50, 50));
1904 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1905 // Move back to primary display.
1906 window2
->SetBounds(gfx::Rect(50, 50, 50, 50));
1907 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1910 // Test that the shelf animates back to its normal position upon a user
1911 // completing a gesture drag.
1912 TEST_F(ShelfLayoutManagerTest
, ShelfAnimatesWhenGestureComplete
) {
1913 if (!SupportsHostWindowResize())
1916 // Test the shelf animates back to its original visible bounds when it is
1917 // dragged when there are no visible windows.
1918 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1919 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1920 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1921 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1922 gfx::Rect visible_bounds
= GetShelfWidget()->GetWindowBoundsInScreen();
1924 // Enable animations so that we can make sure that they occur.
1925 ui::ScopedAnimationDurationScaleMode
regular_animations(
1926 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION
);
1928 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
1929 gfx::Rect shelf_bounds_in_screen
=
1930 GetShelfWidget()->GetWindowBoundsInScreen();
1931 gfx::Point
start(shelf_bounds_in_screen
.CenterPoint());
1932 gfx::Point
end(start
.x(), shelf_bounds_in_screen
.bottom());
1933 generator
.GestureScrollSequence(start
, end
,
1934 base::TimeDelta::FromMilliseconds(10), 5);
1935 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1936 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
1938 ShelfAnimationWaiter
waiter(visible_bounds
);
1939 // Wait till the animation completes and check that it occurred.
1940 waiter
.WaitTillDoneAnimating();
1941 EXPECT_TRUE(waiter
.WasValidAnimation());
1944 // Create a visible window so auto-hide behavior is enforced.
1947 // Get the bounds of the shelf when it is hidden.
1948 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1949 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1950 gfx::Rect auto_hidden_bounds
= GetShelfWidget()->GetWindowBoundsInScreen();
1953 // Enable the animations so that we can make sure they do occur.
1954 ui::ScopedAnimationDurationScaleMode
regular_animations(
1955 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION
);
1958 GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint();
1959 gfx::Point
end(start
.x(), start
.y() - 100);
1960 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
1962 // Test that the shelf animates to the visible bounds after a swipe up on
1963 // the auto hidden shelf.
1964 generator
.GestureScrollSequence(start
, end
,
1965 base::TimeDelta::FromMilliseconds(10), 1);
1966 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1967 ShelfAnimationWaiter
waiter1(visible_bounds
);
1968 waiter1
.WaitTillDoneAnimating();
1969 EXPECT_TRUE(waiter1
.WasValidAnimation());
1971 // Test that the shelf animates to the auto hidden bounds after a swipe up
1972 // on the visible shelf.
1973 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
1974 generator
.GestureScrollSequence(start
, end
,
1975 base::TimeDelta::FromMilliseconds(10), 1);
1976 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
1977 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
1978 ShelfAnimationWaiter
waiter2(auto_hidden_bounds
);
1979 waiter2
.WaitTillDoneAnimating();
1980 EXPECT_TRUE(waiter2
.WasValidAnimation());
1984 TEST_F(ShelfLayoutManagerTest
, GestureRevealsTrayBubble
) {
1985 if (!SupportsHostWindowResize())
1988 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
1989 shelf
->LayoutShelf();
1991 // Create a visible window so auto-hide behavior is enforced.
1994 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
1995 SystemTray
* tray
= GetSystemTray();
1997 // First, make sure the shelf is visible.
1998 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
1999 EXPECT_FALSE(tray
->HasSystemBubble());
2001 // Now, drag up on the tray to show the bubble.
2002 gfx::Point start
= GetShelfWidget()->status_area_widget()->
2003 GetWindowBoundsInScreen().CenterPoint();
2004 gfx::Point
end(start
.x(), start
.y() - 100);
2005 generator
.GestureScrollSequence(start
, end
,
2006 base::TimeDelta::FromMilliseconds(10), 1);
2007 EXPECT_TRUE(tray
->HasSystemBubble());
2008 tray
->CloseSystemBubble();
2009 RunAllPendingInMessageLoop();
2010 EXPECT_FALSE(tray
->HasSystemBubble());
2012 // Drag again, but only a small amount, and slowly. The bubble should not be
2014 end
.set_y(start
.y() - 30);
2015 generator
.GestureScrollSequence(start
, end
,
2016 base::TimeDelta::FromMilliseconds(500), 100);
2017 EXPECT_FALSE(tray
->HasSystemBubble());
2019 // Now, hide the shelf.
2020 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
2022 // Start a drag from the bezel, and drag up to show both the shelf and the
2024 start
.set_y(start
.y() + 100);
2025 end
.set_y(start
.y() - 400);
2026 generator
.GestureScrollSequence(start
, end
,
2027 base::TimeDelta::FromMilliseconds(10), 1);
2028 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
2029 EXPECT_TRUE(tray
->HasSystemBubble());
2032 TEST_F(ShelfLayoutManagerTest
, ShelfFlickerOnTrayActivation
) {
2033 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
2035 // Create a visible window so auto-hide behavior is enforced.
2038 // Turn on auto-hide for the shelf.
2039 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
2040 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
2041 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
2043 // Show the status menu. That should make the shelf visible again.
2044 Shell::GetInstance()->accelerator_controller()->PerformActionIfEnabled(
2045 SHOW_SYSTEM_TRAY_BUBBLE
);
2046 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
2047 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
2048 EXPECT_TRUE(GetSystemTray()->HasSystemBubble());
2051 TEST_F(ShelfLayoutManagerTest
, WorkAreaChangeWorkspace
) {
2052 // Make sure the shelf is always visible.
2053 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
2054 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
2055 shelf
->LayoutShelf();
2057 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
2058 params
.bounds
= gfx::Rect(0, 0, 200, 200);
2059 params
.context
= CurrentContext();
2060 views::Widget
* widget_one
= CreateTestWidgetWithParams(params
);
2061 widget_one
->Maximize();
2063 views::Widget
* widget_two
= CreateTestWidgetWithParams(params
);
2064 widget_two
->Maximize();
2065 widget_two
->Activate();
2067 // Both windows are maximized. They should be of the same size.
2068 EXPECT_EQ(widget_one
->GetNativeWindow()->bounds().ToString(),
2069 widget_two
->GetNativeWindow()->bounds().ToString());
2070 int area_when_shelf_shown
=
2071 widget_one
->GetNativeWindow()->bounds().size().GetArea();
2073 // Now hide the shelf.
2074 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
2076 // Both windows should be resized according to the shelf status.
2077 EXPECT_EQ(widget_one
->GetNativeWindow()->bounds().ToString(),
2078 widget_two
->GetNativeWindow()->bounds().ToString());
2079 // Resized to small.
2080 EXPECT_LT(area_when_shelf_shown
,
2081 widget_one
->GetNativeWindow()->bounds().size().GetArea());
2083 // Now show the shelf.
2084 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
2086 // Again both windows should be of the same size.
2087 EXPECT_EQ(widget_one
->GetNativeWindow()->bounds().ToString(),
2088 widget_two
->GetNativeWindow()->bounds().ToString());
2089 EXPECT_EQ(area_when_shelf_shown
,
2090 widget_one
->GetNativeWindow()->bounds().size().GetArea());
2093 // Confirm that the shelf is dimmed only when content is maximized and
2094 // shelf is not autohidden.
2095 TEST_F(ShelfLayoutManagerTest
, Dimming
) {
2096 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
2097 scoped_ptr
<aura::Window
> w1(CreateTestWindow());
2099 wm::ActivateWindow(w1
.get());
2101 // Normal window doesn't dim shelf.
2102 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_NORMAL
);
2103 ShelfWidget
* shelf
= GetShelfWidget();
2104 EXPECT_FALSE(shelf
->GetDimsShelf());
2106 // Maximized window does.
2107 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
2108 EXPECT_TRUE(shelf
->GetDimsShelf());
2110 // Change back to normal stops dimming.
2111 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_NORMAL
);
2112 EXPECT_FALSE(shelf
->GetDimsShelf());
2114 // Changing back to maximized dims again.
2115 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
2116 EXPECT_TRUE(shelf
->GetDimsShelf());
2118 // Changing shelf to autohide stops dimming.
2119 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
2120 EXPECT_FALSE(shelf
->GetDimsShelf());
2123 // Make sure that the shelf will not hide if the mouse is between a bubble and
2125 TEST_F(ShelfLayoutManagerTest
, BubbleEnlargesShelfMouseHitArea
) {
2126 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
2127 StatusAreaWidget
* status_area_widget
=
2128 Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
2129 SystemTray
* tray
= GetSystemTray();
2131 // Create a visible window so auto-hide behavior is enforced.
2134 shelf
->LayoutShelf();
2135 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
2137 // Make two iterations - first without a message bubble which should make
2138 // the shelf disappear and then with a message bubble which should keep it
2140 for (int i
= 0; i
< 2; i
++) {
2141 // Make sure the shelf is visible and position the mouse over it. Then
2143 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
2144 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
2146 status_area_widget
->GetWindowBoundsInScreen().CenterPoint();
2147 generator
.MoveMouseTo(center
.x(), center
.y());
2148 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
2149 EXPECT_TRUE(shelf
->IsVisible());
2151 // In our first iteration we make sure there is no bubble.
2152 tray
->CloseSystemBubble();
2153 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
2155 // In our second iteration we show a bubble.
2156 TestItem
*item
= new TestItem
;
2157 tray
->AddTrayItem(item
);
2158 tray
->ShowNotificationView(item
);
2159 EXPECT_TRUE(status_area_widget
->IsMessageBubbleShown());
2161 // Move the pointer over the edge of the shelf.
2162 generator
.MoveMouseTo(
2163 center
.x(), status_area_widget
->GetWindowBoundsInScreen().y() - 8);
2164 shelf
->UpdateVisibilityState();
2166 EXPECT_TRUE(shelf
->IsVisible());
2167 EXPECT_TRUE(status_area_widget
->IsMessageBubbleShown());
2169 EXPECT_FALSE(shelf
->IsVisible());
2170 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
2175 TEST_F(ShelfLayoutManagerTest
, ShelfBackgroundColor
) {
2176 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT
, GetShelfWidget()->GetBackgroundType());
2178 scoped_ptr
<aura::Window
> w1(CreateTestWindow());
2180 wm::ActivateWindow(w1
.get());
2181 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT
, GetShelfWidget()->GetBackgroundType());
2182 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
2183 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED
, GetShelfWidget()->GetBackgroundType());
2185 scoped_ptr
<aura::Window
> w2(CreateTestWindow());
2187 wm::ActivateWindow(w2
.get());
2188 // Overlaps with shelf.
2189 w2
->SetBounds(GetShelfLayoutManager()->GetIdealBounds());
2191 // Still background is 'maximized'.
2192 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED
, GetShelfWidget()->GetBackgroundType());
2194 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MINIMIZED
);
2195 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP
, GetShelfWidget()->GetBackgroundType());
2196 w2
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MINIMIZED
);
2197 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT
, GetShelfWidget()->GetBackgroundType());
2199 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
2200 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED
, GetShelfWidget()->GetBackgroundType());
2202 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT
, GetShelfWidget()->GetBackgroundType());
2205 // Verify that the shelf doesn't have the opaque background if it's auto-hide
2207 TEST_F(ShelfLayoutManagerTest
, ShelfBackgroundColorAutoHide
) {
2208 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT
, GetShelfWidget ()->GetBackgroundType());
2210 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
2211 scoped_ptr
<aura::Window
> w1(CreateTestWindow());
2213 wm::ActivateWindow(w1
.get());
2214 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP
, GetShelfWidget()->GetBackgroundType());
2215 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
2216 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP
, GetShelfWidget()->GetBackgroundType());
2219 #if defined(OS_CHROMEOS)
2220 #define MAYBE_StatusAreaHitBoxCoversEdge StatusAreaHitBoxCoversEdge
2222 #define MAYBE_StatusAreaHitBoxCoversEdge DISABLED_StatusAreaHitBoxCoversEdge
2225 // Verify the hit bounds of the status area extend to the edge of the shelf.
2226 TEST_F(ShelfLayoutManagerTest
, MAYBE_StatusAreaHitBoxCoversEdge
) {
2227 UpdateDisplay("400x400");
2228 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
2229 StatusAreaWidget
* status_area_widget
=
2230 Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
2231 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
2232 generator
.MoveMouseTo(399,399);
2234 // Test bottom right pixel for bottom alignment.
2235 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
2236 generator
.ClickLeftButton();
2237 EXPECT_TRUE(status_area_widget
->IsMessageBubbleShown());
2238 generator
.ClickLeftButton();
2239 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
2241 // Test bottom right pixel for right alignment.
2242 shelf
->SetAlignment(SHELF_ALIGNMENT_RIGHT
);
2243 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
2244 generator
.ClickLeftButton();
2245 EXPECT_TRUE(status_area_widget
->IsMessageBubbleShown());
2246 generator
.ClickLeftButton();
2247 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
2249 // Test bottom left pixel for left alignment.
2250 generator
.MoveMouseTo(0, 399);
2251 shelf
->SetAlignment(SHELF_ALIGNMENT_LEFT
);
2252 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
2253 generator
.ClickLeftButton();
2254 EXPECT_TRUE(status_area_widget
->IsMessageBubbleShown());
2255 generator
.ClickLeftButton();
2256 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
2259 // Tests that when the auto-hide behaviour is changed during an animation the
2260 // target bounds are updated to reflect the new state.
2261 TEST_F(ShelfLayoutManagerTest
,
2262 ShelfAutoHideToggleDuringAnimationUpdatesBounds
) {
2263 ShelfLayoutManager
* shelf_manager
= GetShelfLayoutManager();
2264 aura::Window
* status_window
= GetShelfWidget()->status_area_widget()->
2266 gfx::Rect initial_bounds
= status_window
->bounds();
2268 ui::ScopedAnimationDurationScaleMode
regular_animations(
2269 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION
);
2270 shelf_manager
->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN
);
2271 gfx::Rect hide_target_bounds
= status_window
->GetTargetBounds();
2272 EXPECT_GT(hide_target_bounds
.y(), initial_bounds
.y());
2274 shelf_manager
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
2275 gfx::Rect reshow_target_bounds
= status_window
->GetTargetBounds();
2276 EXPECT_EQ(initial_bounds
, reshow_target_bounds
);