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/wm/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/root_window_controller.h"
14 #include "ash/screen_ash.h"
15 #include "ash/shell.h"
16 #include "ash/shell_delegate.h"
17 #include "ash/shell_window_ids.h"
18 #include "ash/system/status_area_widget.h"
19 #include "ash/system/tray/system_tray.h"
20 #include "ash/system/tray/system_tray_item.h"
21 #include "ash/test/ash_test_base.h"
22 #include "ash/wm/window_util.h"
23 #include "base/command_line.h"
24 #include "base/utf_string_conversions.h"
25 #include "ui/aura/client/aura_constants.h"
26 #include "ui/aura/root_window.h"
27 #include "ui/aura/test/event_generator.h"
28 #include "ui/aura/window.h"
29 #include "ui/base/animation/animation_container_element.h"
30 #include "ui/compositor/layer.h"
31 #include "ui/compositor/layer_animator.h"
32 #include "ui/gfx/display.h"
33 #include "ui/gfx/screen.h"
34 #include "ui/views/controls/label.h"
35 #include "ui/views/layout/fill_layout.h"
36 #include "ui/views/view.h"
37 #include "ui/views/widget/widget.h"
44 void StepWidgetLayerAnimatorToEnd(views::Widget
* widget
) {
45 ui::AnimationContainerElement
* element
=
46 static_cast<ui::AnimationContainerElement
*>(
47 widget
->GetNativeView()->layer()->GetAnimator());
48 element
->Step(base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1));
51 ShelfLayoutManager
* GetShelfLayoutManager() {
52 return Shell::GetPrimaryRootWindowController()->shelf();
55 SystemTray
* GetSystemTray() {
56 return Shell::GetPrimaryRootWindowController()->GetSystemTray();
59 class ShelfLayoutObserverTest
: public ShelfLayoutManager::Observer
{
61 ShelfLayoutObserverTest()
62 : changed_auto_hide_state_(false) {
65 virtual ~ShelfLayoutObserverTest() {}
67 bool changed_auto_hide_state() const { return changed_auto_hide_state_
; }
70 virtual void OnAutoHideStateChanged(
71 ShelfAutoHideState new_state
) OVERRIDE
{
72 changed_auto_hide_state_
= true;
75 bool changed_auto_hide_state_
;
77 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutObserverTest
);
80 // Trivial item implementation that tracks its views for testing.
81 class TestItem
: public SystemTrayItem
{
84 : SystemTrayItem(GetSystemTray()),
88 notification_view_(NULL
) {}
90 virtual views::View
* CreateTrayView(user::LoginStatus status
) OVERRIDE
{
91 tray_view_
= new views::View
;
92 // Add a label so it has non-zero width.
93 tray_view_
->SetLayoutManager(new views::FillLayout
);
94 tray_view_
->AddChildView(new views::Label(UTF8ToUTF16("Tray")));
98 virtual views::View
* CreateDefaultView(user::LoginStatus status
) OVERRIDE
{
99 default_view_
= new views::View
;
100 default_view_
->SetLayoutManager(new views::FillLayout
);
101 default_view_
->AddChildView(new views::Label(UTF8ToUTF16("Default")));
102 return default_view_
;
105 virtual views::View
* CreateDetailedView(user::LoginStatus status
) OVERRIDE
{
106 detailed_view_
= new views::View
;
107 detailed_view_
->SetLayoutManager(new views::FillLayout
);
108 detailed_view_
->AddChildView(new views::Label(UTF8ToUTF16("Detailed")));
109 return detailed_view_
;
112 virtual views::View
* CreateNotificationView(
113 user::LoginStatus status
) OVERRIDE
{
114 notification_view_
= new views::View
;
115 return notification_view_
;
118 virtual void DestroyTrayView() OVERRIDE
{
122 virtual void DestroyDefaultView() OVERRIDE
{
123 default_view_
= NULL
;
126 virtual void DestroyDetailedView() OVERRIDE
{
127 detailed_view_
= NULL
;
130 virtual void DestroyNotificationView() OVERRIDE
{
131 notification_view_
= NULL
;
134 virtual void UpdateAfterLoginStatusChange(
135 user::LoginStatus status
) OVERRIDE
{}
137 views::View
* tray_view() const { return tray_view_
; }
138 views::View
* default_view() const { return default_view_
; }
139 views::View
* detailed_view() const { return detailed_view_
; }
140 views::View
* notification_view() const { return notification_view_
; }
143 views::View
* tray_view_
;
144 views::View
* default_view_
;
145 views::View
* detailed_view_
;
146 views::View
* notification_view_
;
148 DISALLOW_COPY_AND_ASSIGN(TestItem
);
153 class ShelfLayoutManagerTest
: public ash::test::AshTestBase
{
155 ShelfLayoutManagerTest() {}
157 void SetState(ShelfLayoutManager
* shelf
,
158 ShelfVisibilityState state
) {
159 shelf
->SetState(state
);
162 void UpdateAutoHideStateNow() {
163 GetShelfLayoutManager()->UpdateAutoHideStateNow();
166 aura::Window
* CreateTestWindow() {
167 aura::Window
* window
= new aura::Window(NULL
);
168 window
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_NORMAL
);
169 window
->SetType(aura::client::WINDOW_TYPE_NORMAL
);
170 window
->Init(ui::LAYER_TEXTURED
);
171 SetDefaultParentByPrimaryRootWindow(window
);
175 // Overridden from AshTestBase:
176 virtual void SetUp() OVERRIDE
{
177 CommandLine::ForCurrentProcess()->AppendSwitch(
178 ash::switches::kAshEnableTrayDragging
);
179 test::AshTestBase::SetUp();
182 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerTest
);
185 // Fails on Mac only. Need to be implemented. http://crbug.com/111279.
186 #if defined(OS_MACOSX)
187 #define MAYBE_SetVisible DISABLED_SetVisible
189 #define MAYBE_SetVisible SetVisible
191 // Makes sure SetVisible updates work area and widget appropriately.
192 TEST_F(ShelfLayoutManagerTest
, MAYBE_SetVisible
) {
193 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
194 // Force an initial layout.
195 shelf
->LayoutShelf();
196 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
198 gfx::Rect
status_bounds(
199 shelf
->status_area_widget()->GetWindowBoundsInScreen());
200 gfx::Rect
launcher_bounds(
201 shelf
->launcher_widget()->GetWindowBoundsInScreen());
202 int shelf_height
= shelf
->GetIdealBounds().height();
204 const gfx::Display
& display
= Shell::GetInstance()->display_manager()->
205 GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
206 ASSERT_NE(-1, display
.id());
207 // Bottom inset should be the max of widget heights.
208 EXPECT_EQ(shelf_height
,
209 display
.bounds().bottom() - display
.work_area().bottom());
212 SetState(shelf
, SHELF_HIDDEN
);
213 // Run the animation to completion.
214 StepWidgetLayerAnimatorToEnd(shelf
->launcher_widget());
215 StepWidgetLayerAnimatorToEnd(shelf
->status_area_widget());
216 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
218 display
.bounds().bottom() - display
.work_area().bottom());
220 // Make sure the bounds of the two widgets changed.
221 EXPECT_GE(shelf
->launcher_widget()->GetNativeView()->bounds().y(),
222 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
223 EXPECT_GE(shelf
->status_area_widget()->GetNativeView()->bounds().y(),
224 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
226 // And show it again.
227 SetState(shelf
, SHELF_VISIBLE
);
228 // Run the animation to completion.
229 StepWidgetLayerAnimatorToEnd(shelf
->launcher_widget());
230 StepWidgetLayerAnimatorToEnd(shelf
->status_area_widget());
231 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
232 EXPECT_EQ(shelf_height
,
233 display
.bounds().bottom() - display
.work_area().bottom());
235 // Make sure the bounds of the two widgets changed.
236 launcher_bounds
= shelf
->launcher_widget()->GetNativeView()->bounds();
238 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom() - shelf_height
;
239 EXPECT_EQ(launcher_bounds
.y(),
240 bottom
+ (shelf
->GetIdealBounds().height() -
241 launcher_bounds
.height()) / 2);
242 status_bounds
= shelf
->status_area_widget()->GetNativeView()->bounds();
243 EXPECT_EQ(status_bounds
.y(),
244 bottom
+ shelf_height
- status_bounds
.height());
247 // Makes sure LayoutShelf invoked while animating cleans things up.
248 TEST_F(ShelfLayoutManagerTest
, LayoutShelfWhileAnimating
) {
249 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
250 // Force an initial layout.
251 shelf
->LayoutShelf();
252 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
254 const gfx::Display
& display
= Shell::GetInstance()->display_manager()->
255 GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
258 SetState(shelf
, SHELF_HIDDEN
);
259 shelf
->LayoutShelf();
260 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
261 EXPECT_EQ(0, display
.bounds().bottom() - display
.work_area().bottom());
263 // Make sure the bounds of the two widgets changed.
264 EXPECT_GE(shelf
->launcher_widget()->GetNativeView()->bounds().y(),
265 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
266 EXPECT_GE(shelf
->status_area_widget()->GetNativeView()->bounds().y(),
267 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
270 // Makes sure the launcher is initially sized correctly.
271 TEST_F(ShelfLayoutManagerTest
, LauncherInitiallySized
) {
272 Launcher
* launcher
= Launcher::ForPrimaryDisplay();
273 ASSERT_TRUE(launcher
);
274 ShelfLayoutManager
* shelf_layout_manager
= GetShelfLayoutManager();
275 ASSERT_TRUE(shelf_layout_manager
);
276 ASSERT_TRUE(shelf_layout_manager
->status_area_widget());
277 int status_width
= shelf_layout_manager
->status_area_widget()->
278 GetWindowBoundsInScreen().width();
279 // Test only makes sense if the status is > 0, which is better be.
280 EXPECT_GT(status_width
, 0);
281 EXPECT_EQ(status_width
, launcher
->status_size().width());
284 // Makes sure the launcher is sized when the status area changes size.
285 TEST_F(ShelfLayoutManagerTest
, LauncherUpdatedWhenStatusAreaChangesSize
) {
286 Launcher
* launcher
= Launcher::ForPrimaryDisplay();
287 ASSERT_TRUE(launcher
);
288 ShelfLayoutManager
* shelf_layout_manager
= GetShelfLayoutManager();
289 ASSERT_TRUE(shelf_layout_manager
);
290 ASSERT_TRUE(shelf_layout_manager
->status_area_widget());
291 shelf_layout_manager
->status_area_widget()->SetBounds(
292 gfx::Rect(0, 0, 200, 200));
293 EXPECT_EQ(200, launcher
->status_size().width());
296 // Verifies when the shell is deleted with a full screen window we don't
297 // crash. This test is here as originally the crash was in ShelfLayoutManager.
298 TEST_F(ShelfLayoutManagerTest
, DontReferenceLauncherAfterDeletion
) {
299 views::Widget
* widget
= new views::Widget
;
300 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
301 params
.bounds
= gfx::Rect(0, 0, 200, 200);
302 params
.context
= CurrentContext();
303 // Widget is now owned by the parent window.
304 widget
->Init(params
);
305 widget
->SetFullscreen(true);
308 // Various assertions around auto-hide.
309 TEST_F(ShelfLayoutManagerTest
, AutoHide
) {
310 aura::RootWindow
* root
= Shell::GetPrimaryRootWindow();
311 aura::test::EventGenerator
generator(root
, root
);
312 generator
.MoveMouseTo(0, 0);
314 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
315 shelf
->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
316 views::Widget
* widget
= new views::Widget
;
317 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
318 params
.bounds
= gfx::Rect(0, 0, 200, 200);
319 params
.context
= CurrentContext();
320 // Widget is now owned by the parent window.
321 widget
->Init(params
);
324 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
325 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
327 // LayoutShelf() forces the animation to completion, at which point the
328 // launcher should go off the screen.
329 shelf
->LayoutShelf();
330 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
331 shelf
->launcher_widget()->GetWindowBoundsInScreen().y());
332 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
333 Shell::GetScreen()->GetDisplayNearestWindow(
334 root
).work_area().bottom());
336 // Move the mouse to the bottom of the screen.
337 generator
.MoveMouseTo(0, root
->bounds().bottom() - 1);
339 // Shelf should be shown again (but it shouldn't have changed the work area).
340 SetState(shelf
, SHELF_AUTO_HIDE
);
341 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
342 shelf
->LayoutShelf();
343 EXPECT_EQ(root
->bounds().bottom() - shelf
->GetIdealBounds().height(),
344 shelf
->launcher_widget()->GetWindowBoundsInScreen().y());
345 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
346 Shell::GetScreen()->GetDisplayNearestWindow(
347 root
).work_area().bottom());
349 // Move mouse back up.
350 generator
.MoveMouseTo(0, 0);
351 SetState(shelf
, SHELF_AUTO_HIDE
);
352 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
353 shelf
->LayoutShelf();
354 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
355 shelf
->launcher_widget()->GetWindowBoundsInScreen().y());
357 // Drag mouse to bottom of screen.
358 generator
.PressLeftButton();
359 generator
.MoveMouseTo(0, root
->bounds().bottom() - 1);
360 UpdateAutoHideStateNow();
361 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
363 generator
.ReleaseLeftButton();
364 generator
.MoveMouseTo(1, root
->bounds().bottom() - 1);
365 UpdateAutoHideStateNow();
366 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
367 generator
.PressLeftButton();
368 generator
.MoveMouseTo(1, root
->bounds().bottom() - 1);
369 UpdateAutoHideStateNow();
370 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
373 // Assertions around the lock screen showing.
374 TEST_F(ShelfLayoutManagerTest
, VisibleWhenLockScreenShowing
) {
375 // Since ShelfLayoutManager queries for mouse location, move the mouse so
376 // it isn't over the shelf.
377 aura::test::EventGenerator
generator(
378 Shell::GetPrimaryRootWindow(), gfx::Point());
379 generator
.MoveMouseTo(0, 0);
381 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
382 shelf
->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
383 views::Widget
* widget
= new views::Widget
;
384 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
385 params
.bounds
= gfx::Rect(0, 0, 200, 200);
386 params
.context
= CurrentContext();
387 // Widget is now owned by the parent window.
388 widget
->Init(params
);
391 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
392 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
394 aura::RootWindow
* root
= Shell::GetPrimaryRootWindow();
395 // LayoutShelf() forces the animation to completion, at which point the
396 // launcher should go off the screen.
397 shelf
->LayoutShelf();
398 EXPECT_EQ(root
->bounds().bottom() - ShelfLayoutManager::kAutoHideSize
,
399 shelf
->launcher_widget()->GetWindowBoundsInScreen().y());
401 aura::Window
* lock_container
= Shell::GetContainer(
402 Shell::GetPrimaryRootWindow(),
403 internal::kShellWindowId_LockScreenContainer
);
405 views::Widget
* lock_widget
= new views::Widget
;
406 views::Widget::InitParams
lock_params(
407 views::Widget::InitParams::TYPE_WINDOW
);
408 lock_params
.bounds
= gfx::Rect(0, 0, 200, 200);
409 params
.context
= CurrentContext();
410 lock_params
.parent
= lock_container
;
411 // Widget is now owned by the parent window.
412 lock_widget
->Init(lock_params
);
413 lock_widget
->Maximize();
417 Shell::GetInstance()->delegate()->LockScreen();
418 shelf
->UpdateVisibilityState();
419 // Showing a widget in the lock screen should force the shelf to be visibile.
420 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
422 Shell::GetInstance()->delegate()->UnlockScreen();
423 shelf
->UpdateVisibilityState();
424 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
427 // Assertions around SetAutoHideBehavior.
428 TEST_F(ShelfLayoutManagerTest
, SetAutoHideBehavior
) {
429 // Since ShelfLayoutManager queries for mouse location, move the mouse so
430 // it isn't over the shelf.
431 aura::test::EventGenerator
generator(
432 Shell::GetPrimaryRootWindow(), gfx::Point());
433 generator
.MoveMouseTo(0, 0);
435 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
436 views::Widget
* widget
= new views::Widget
;
437 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
438 params
.bounds
= gfx::Rect(0, 0, 200, 200);
439 params
.context
= CurrentContext();
440 // Widget is now owned by the parent window.
441 widget
->Init(params
);
443 aura::Window
* window
= widget
->GetNativeWindow();
444 gfx::Rect
display_bounds(
445 Shell::GetScreen()->GetDisplayNearestWindow(window
).bounds());
447 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
448 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
450 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
451 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
454 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
455 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
456 window
).work_area().bottom(),
457 widget
->GetWorkAreaBoundsInScreen().bottom());
459 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
460 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
461 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
462 window
).work_area().bottom(),
463 widget
->GetWorkAreaBoundsInScreen().bottom());
465 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
466 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
467 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
468 window
).work_area().bottom(),
469 widget
->GetWorkAreaBoundsInScreen().bottom());
472 // Verifies the shelf is visible when status/launcher is focused.
473 TEST_F(ShelfLayoutManagerTest
, VisibleWhenStatusOrLauncherFocused
) {
474 // Since ShelfLayoutManager queries for mouse location, move the mouse so
475 // it isn't over the shelf.
476 aura::test::EventGenerator
generator(
477 Shell::GetPrimaryRootWindow(), gfx::Point());
478 generator
.MoveMouseTo(0, 0);
480 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
481 views::Widget
* widget
= new views::Widget
;
482 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
483 params
.bounds
= gfx::Rect(0, 0, 200, 200);
484 params
.context
= CurrentContext();
485 // Widget is now owned by the parent window.
486 widget
->Init(params
);
488 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
489 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
490 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
492 // Focus the launcher. Have to go through the focus cycler as normal focus
493 // requests to it do nothing.
494 shelf
->launcher()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD
);
495 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
498 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
500 // Trying to activate the status should fail, since we only allow activating
501 // it when the user is using the keyboard (i.e. through FocusCycler).
502 shelf
->status_area_widget()->Activate();
503 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
505 shelf
->launcher()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD
);
506 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
509 // Makes sure shelf will be visible when app list opens as shelf is in
510 // SHELF_VISIBLE state,and toggling app list won't change shelf
512 TEST_F(ShelfLayoutManagerTest
, OpenAppListWithShelfVisibleState
) {
513 Shell
* shell
= Shell::GetInstance();
514 internal::RootWindowController
* controller
=
515 Shell::GetPrimaryRootWindowController();
516 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
517 shelf
->LayoutShelf();
518 controller
->SetShelfAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
520 // Create a normal unmaximized windowm shelf should be visible.
521 aura::Window
* window
= CreateTestWindow();
522 window
->SetBounds(gfx::Rect(0, 0, 100, 100));
524 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
525 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
527 // Toggle app list to show, and the shelf stays visible.
528 shell
->ToggleAppList(NULL
);
529 EXPECT_TRUE(shell
->GetAppListTargetVisibility());
530 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
532 // Toggle app list to hide, and the shelf stays visible.
533 shell
->ToggleAppList(NULL
);
534 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
535 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
538 // Makes sure shelf will be shown with SHELF_AUTO_HIDE_SHOWN state
539 // when app list opens as shelf is in SHELF_AUTO_HIDE state, and
540 // toggling app list won't change shelf visibility state.
541 TEST_F(ShelfLayoutManagerTest
, OpenAppListWithShelfAutoHideState
) {
542 Shell
* shell
= Shell::GetInstance();
543 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
544 internal::RootWindowController
* controller
=
545 Shell::GetPrimaryRootWindowController();
546 shelf
->LayoutShelf();
547 controller
->SetShelfAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
549 // Create a window and show it in maximized state.
550 aura::Window
* window
= CreateTestWindow();
551 window
->SetBounds(gfx::Rect(0, 0, 100, 100));
552 window
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
554 wm::ActivateWindow(window
);
556 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
557 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
559 // Toggle app list to show.
560 shell
->ToggleAppList(NULL
);
561 // The shelf's auto hide state won't be changed until the timer fires, so
562 // calling shell->UpdateShelfVisibility() is kind of manually helping it to
564 shell
->UpdateShelfVisibility();
565 EXPECT_TRUE(shell
->GetAppListTargetVisibility());
566 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
567 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
569 // Toggle app list to hide.
570 shell
->ToggleAppList(NULL
);
571 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
572 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
575 // Makes sure shelf will be hidden when app list opens as shelf is in HIDDEN
576 // state, and toggling app list won't change shelf visibility state.
577 TEST_F(ShelfLayoutManagerTest
, OpenAppListWithShelfHiddenState
) {
578 Shell
* shell
= Shell::GetInstance();
579 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
580 // For shelf to be visible, app list is not open in initial state.
581 shelf
->LayoutShelf();
583 // Create a window and make it full screen.
584 aura::Window
* window
= CreateTestWindow();
585 window
->SetBounds(gfx::Rect(0, 0, 100, 100));
586 window
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_FULLSCREEN
);
588 wm::ActivateWindow(window
);
590 // App list and shelf is not shown.
591 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
592 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
594 // Toggle app list to show.
595 shell
->ToggleAppList(NULL
);
596 EXPECT_TRUE(shell
->GetAppListTargetVisibility());
597 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
599 // Toggle app list to hide.
600 shell
->ToggleAppList(NULL
);
601 EXPECT_FALSE(shell
->GetAppListTargetVisibility());
602 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
605 // Tests SHELF_ALIGNMENT_LEFT and SHELF_ALIGNMENT_RIGHT.
606 TEST_F(ShelfLayoutManagerTest
, SetAlignment
) {
607 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
608 // Force an initial layout.
609 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
610 shelf
->LayoutShelf();
611 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
613 shelf
->SetAlignment(SHELF_ALIGNMENT_LEFT
);
614 gfx::Rect
launcher_bounds(
615 shelf
->launcher_widget()->GetWindowBoundsInScreen());
616 const internal::DisplayManager
* manager
=
617 Shell::GetInstance()->display_manager();
618 gfx::Display display
=
619 manager
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
620 ASSERT_NE(-1, display
.id());
621 EXPECT_EQ(shelf
->GetIdealBounds().width(),
622 display
.GetWorkAreaInsets().left());
624 launcher_bounds
.width(),
625 shelf
->launcher_widget()->GetContentsView()->GetPreferredSize().width());
626 EXPECT_EQ(SHELF_ALIGNMENT_LEFT
, GetSystemTray()->shelf_alignment());
627 StatusAreaWidget
* status_area_widget
= shelf
->status_area_widget();
628 gfx::Rect
status_bounds(status_area_widget
->GetWindowBoundsInScreen());
629 EXPECT_GE(status_bounds
.width(),
630 status_area_widget
->GetContentsView()->GetPreferredSize().width());
631 EXPECT_EQ(shelf
->GetIdealBounds().width(),
632 display
.GetWorkAreaInsets().left());
633 EXPECT_EQ(0, display
.GetWorkAreaInsets().top());
634 EXPECT_EQ(0, display
.GetWorkAreaInsets().bottom());
635 EXPECT_EQ(0, display
.GetWorkAreaInsets().right());
636 EXPECT_EQ(display
.bounds().x(), launcher_bounds
.x());
637 EXPECT_EQ(display
.bounds().y(), launcher_bounds
.y());
638 EXPECT_EQ(display
.bounds().height(), launcher_bounds
.height());
639 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
640 display
= manager
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
641 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
,
642 display
.GetWorkAreaInsets().left());
643 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
, display
.work_area().x());
645 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
646 shelf
->SetAlignment(SHELF_ALIGNMENT_RIGHT
);
647 display
= manager
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
648 launcher_bounds
= shelf
->launcher_widget()->GetWindowBoundsInScreen();
649 display
= manager
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
650 ASSERT_NE(-1, display
.id());
651 EXPECT_EQ(shelf
->GetIdealBounds().width(),
652 display
.GetWorkAreaInsets().right());
653 EXPECT_GE(launcher_bounds
.width(),
654 shelf
->launcher_widget()->GetContentsView()->GetPreferredSize().width());
655 EXPECT_EQ(SHELF_ALIGNMENT_RIGHT
, GetSystemTray()->shelf_alignment());
656 status_bounds
= gfx::Rect(status_area_widget
->GetWindowBoundsInScreen());
657 EXPECT_GE(status_bounds
.width(),
658 status_area_widget
->GetContentsView()->GetPreferredSize().width());
659 EXPECT_EQ(shelf
->GetIdealBounds().width(),
660 display
.GetWorkAreaInsets().right());
661 EXPECT_EQ(0, display
.GetWorkAreaInsets().top());
662 EXPECT_EQ(0, display
.GetWorkAreaInsets().bottom());
663 EXPECT_EQ(0, display
.GetWorkAreaInsets().left());
664 EXPECT_EQ(display
.work_area().right(), launcher_bounds
.x());
665 EXPECT_EQ(display
.bounds().y(), launcher_bounds
.y());
666 EXPECT_EQ(display
.bounds().height(), launcher_bounds
.height());
667 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
668 display
= manager
->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
669 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
,
670 display
.GetWorkAreaInsets().right());
671 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize
,
672 display
.bounds().right() - display
.work_area().right());
675 TEST_F(ShelfLayoutManagerTest
, GestureDrag
) {
676 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
677 internal::RootWindowController
* controller
=
678 Shell::GetPrimaryRootWindowController();
679 controller
->SetShelfAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
680 shelf
->LayoutShelf();
682 views::Widget
* widget
= new views::Widget
;
683 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
684 params
.bounds
= gfx::Rect(0, 0, 200, 200);
685 params
.context
= CurrentContext();
686 widget
->Init(params
);
690 aura::Window
* window
= widget
->GetNativeWindow();
692 gfx::Rect shelf_shown
= shelf
->launcher_widget()->GetWindowBoundsInScreen();
693 gfx::Rect bounds_shelf
= window
->bounds();
694 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
696 aura::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
698 // Swipe up on the shelf. This should not change any state.
700 shelf
->launcher_widget()->GetWindowBoundsInScreen().CenterPoint();
701 gfx::Point
end(start
.x(), start
.y() + 100);
703 // Swipe down on the shelf to hide it.
704 end
.set_y(start
.y() + 100);
705 generator
.GestureScrollSequence(start
, end
,
706 base::TimeDelta::FromMilliseconds(10), 1);
707 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
708 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
709 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
710 EXPECT_NE(bounds_shelf
.ToString(), window
->bounds().ToString());
711 EXPECT_NE(shelf_shown
.ToString(),
712 shelf
->launcher_widget()->GetWindowBoundsInScreen().ToString());
714 gfx::Rect bounds_noshelf
= window
->bounds();
715 gfx::Rect shelf_hidden
= shelf
->launcher_widget()->GetWindowBoundsInScreen();
717 // Swipe up to show the shelf.
718 generator
.GestureScrollSequence(end
, start
,
719 base::TimeDelta::FromMilliseconds(10), 1);
720 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
721 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
, shelf
->auto_hide_behavior());
722 EXPECT_EQ(bounds_shelf
.ToString(), window
->bounds().ToString());
723 EXPECT_EQ(shelf_shown
.ToString(),
724 shelf
->launcher_widget()->GetWindowBoundsInScreen().ToString());
726 // Swipe up again. The shelf should hide.
727 end
.set_y(start
.y() - 100);
728 generator
.GestureScrollSequence(start
, end
,
729 base::TimeDelta::FromMilliseconds(10), 1);
730 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
731 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
732 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
733 EXPECT_EQ(shelf_hidden
.ToString(),
734 shelf
->launcher_widget()->GetWindowBoundsInScreen().ToString());
736 // Swipe up yet again to show it.
737 end
.set_y(start
.y() + 100);
738 generator
.GestureScrollSequence(end
, start
,
739 base::TimeDelta::FromMilliseconds(10), 1);
741 // Swipe down very little. It shouldn't change any state.
742 end
.set_y(start
.y() + shelf_shown
.height() * 3 / 10);
743 generator
.GestureScrollSequence(start
, end
,
744 base::TimeDelta::FromMilliseconds(100), 1);
745 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
746 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
, shelf
->auto_hide_behavior());
747 EXPECT_EQ(bounds_shelf
.ToString(), window
->bounds().ToString());
748 EXPECT_EQ(shelf_shown
.ToString(),
749 shelf
->launcher_widget()->GetWindowBoundsInScreen().ToString());
751 // Swipe down again to hide.
752 end
.set_y(start
.y() + 100);
753 generator
.GestureScrollSequence(start
, end
,
754 base::TimeDelta::FromMilliseconds(10), 1);
755 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
756 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
757 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
758 EXPECT_EQ(bounds_noshelf
.ToString(), window
->bounds().ToString());
759 EXPECT_EQ(shelf_hidden
.ToString(),
760 shelf
->launcher_widget()->GetWindowBoundsInScreen().ToString());
762 // Make the window fullscreen.
763 widget
->SetFullscreen(true);
764 gfx::Rect bounds_fullscreen
= window
->bounds();
765 EXPECT_TRUE(widget
->IsFullscreen());
766 EXPECT_NE(bounds_noshelf
.ToString(), bounds_fullscreen
.ToString());
767 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
769 // Swipe-up. This should not change anything.
770 generator
.GestureScrollSequence(end
, start
,
771 base::TimeDelta::FromMilliseconds(10), 1);
772 EXPECT_EQ(SHELF_HIDDEN
, shelf
->visibility_state());
773 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
, shelf
->auto_hide_behavior());
774 EXPECT_EQ(bounds_fullscreen
.ToString(), window
->bounds().ToString());
777 TEST_F(ShelfLayoutManagerTest
, GestureRevealsTrayBubble
) {
778 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
779 shelf
->LayoutShelf();
781 aura::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
782 SystemTray
* tray
= GetSystemTray();
784 // First, make sure the shelf is visible.
785 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
786 EXPECT_FALSE(tray
->HasSystemBubble());
788 // Now, drag up on the tray to show the bubble.
790 shelf
->status_area_widget()->GetWindowBoundsInScreen().CenterPoint();
791 gfx::Point
end(start
.x(), start
.y() - 100);
792 generator
.GestureScrollSequence(start
, end
,
793 base::TimeDelta::FromMilliseconds(10), 1);
794 EXPECT_TRUE(tray
->HasSystemBubble());
795 tray
->CloseBubbleForTest();
796 RunAllPendingInMessageLoop();
797 EXPECT_FALSE(tray
->HasSystemBubble());
799 // Drag again, but only a small amount, and slowly. The bubble should not be
801 end
.set_y(start
.y() - 30);
802 generator
.GestureScrollSequence(start
, end
,
803 base::TimeDelta::FromMilliseconds(500), 100);
804 EXPECT_FALSE(tray
->HasSystemBubble());
806 // Now, hide the shelf.
807 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
809 // Start a drag from the bezel, and drag up to show both the shelf and the
811 start
.set_y(start
.y() + 100);
812 end
.set_y(start
.y() - 400);
813 generator
.GestureScrollSequence(start
, end
,
814 base::TimeDelta::FromMilliseconds(10), 1);
815 EXPECT_EQ(SHELF_VISIBLE
, shelf
->visibility_state());
816 EXPECT_TRUE(tray
->HasSystemBubble());
819 TEST_F(ShelfLayoutManagerTest
, ShelfFlickerOnTrayActivation
) {
820 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
822 // Turn on auto-hide for the shelf.
823 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
824 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
825 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
827 // Show the status menu. That should make the shelf visible again.
828 Shell::GetInstance()->accelerator_controller()->PerformAction(
829 SHOW_SYSTEM_TRAY_BUBBLE
, ui::Accelerator());
830 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
831 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
832 EXPECT_TRUE(GetSystemTray()->HasSystemBubble());
834 // Now activate the tray (using the keyboard, instead of using the mouse to
835 // make sure the mouse does not alter the auto-hide state in the shelf).
836 // This should not trigger any auto-hide state change in the shelf.
837 ShelfLayoutObserverTest observer
;
838 shelf
->AddObserver(&observer
);
840 aura::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
841 generator
.PressKey(ui::VKEY_SPACE
, 0);
842 generator
.ReleaseKey(ui::VKEY_SPACE
, 0);
843 EXPECT_TRUE(GetSystemTray()->HasSystemBubble());
844 EXPECT_EQ(SHELF_AUTO_HIDE
, shelf
->visibility_state());
845 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN
, shelf
->auto_hide_state());
846 EXPECT_FALSE(observer
.changed_auto_hide_state());
848 shelf
->RemoveObserver(&observer
);
851 TEST_F(ShelfLayoutManagerTest
, WorkAreaChangeWorkspace
) {
852 // Make sure the shelf is always visible.
853 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
854 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
855 shelf
->LayoutShelf();
857 views::Widget
* widget_one
= new views::Widget
;
858 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
859 params
.bounds
= gfx::Rect(0, 0, 200, 200);
860 params
.context
= CurrentContext();
861 widget_one
->Init(params
);
863 widget_one
->Maximize();
865 views::Widget
* widget_two
= new views::Widget
;
866 widget_two
->Init(params
);
868 widget_two
->Maximize();
869 widget_two
->Activate();
871 // Both windows are maximized. They should be of the same size.
872 EXPECT_EQ(widget_one
->GetNativeWindow()->bounds().ToString(),
873 widget_two
->GetNativeWindow()->bounds().ToString());
875 // Now hide the shelf.
876 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
878 // The active maximized window will get resized to the new work area. However,
879 // the inactive window should not get resized.
880 EXPECT_NE(widget_one
->GetNativeWindow()->bounds().ToString(),
881 widget_two
->GetNativeWindow()->bounds().ToString());
883 // Activate the first window. Now, both windows should be of the same size
885 widget_one
->Activate();
886 EXPECT_EQ(widget_one
->GetNativeWindow()->bounds().ToString(),
887 widget_two
->GetNativeWindow()->bounds().ToString());
889 // Now show the shelf.
890 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
892 // The active maximized window will get resized to the new work area. However,
893 // the inactive window should not get resized.
894 EXPECT_NE(widget_one
->GetNativeWindow()->bounds().ToString(),
895 widget_two
->GetNativeWindow()->bounds().ToString());
897 // Activate the first window. Now, both windows should be of the same size
899 widget_two
->Activate();
900 EXPECT_EQ(widget_one
->GetNativeWindow()->bounds().ToString(),
901 widget_two
->GetNativeWindow()->bounds().ToString());
904 // Confirm that the shelf is dimmed only when content is maximized and
905 // shelf is not autohidden.
906 TEST_F(ShelfLayoutManagerTest
, Dimming
) {
907 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
908 scoped_ptr
<aura::Window
> w1(CreateTestWindow());
910 wm::ActivateWindow(w1
.get());
912 // Normal window doesn't dim shelf.
913 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_NORMAL
);
914 Launcher
* launcher
= Launcher::ForPrimaryDisplay();
915 EXPECT_FALSE(launcher
->GetDimsShelf());
917 // Maximized window does.
918 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
919 EXPECT_TRUE(launcher
->GetDimsShelf());
921 // Change back to normal stops dimming.
922 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_NORMAL
);
923 EXPECT_FALSE(launcher
->GetDimsShelf());
925 // Changing back to maximized dims again.
926 w1
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_MAXIMIZED
);
927 EXPECT_TRUE(launcher
->GetDimsShelf());
929 // Changing shelf to autohide stops dimming.
930 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
931 EXPECT_FALSE(launcher
->GetDimsShelf());
934 // Make sure that the shelf will not hide if the mouse is between a bubble and
936 TEST_F(ShelfLayoutManagerTest
, BubbleEnlargesShelfMouseHitArea
) {
937 ShelfLayoutManager
* shelf
= GetShelfLayoutManager();
938 StatusAreaWidget
* status_area_widget
=
939 Shell::GetPrimaryRootWindowController()->status_area_widget();
940 SystemTray
* tray
= GetSystemTray();
942 shelf
->LayoutShelf();
943 aura::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
945 // Make two iterations - first without a message bubble which should make
946 // the shelf disappear and then with a message bubble which should keep it
948 for (int i
= 0; i
< 2; i
++) {
949 // Make sure the shelf is visible and position the mouse over it. Then
951 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
952 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
954 status_area_widget
->GetWindowBoundsInScreen().CenterPoint();
955 generator
.MoveMouseTo(center
.x(), center
.y());
956 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
957 EXPECT_TRUE(shelf
->IsVisible());
959 // In our first iteration we make sure there is no bubble.
960 tray
->CloseBubbleForTest();
961 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
963 // In our second iteration we show a bubble.
964 TestItem
*item
= new TestItem
;
965 tray
->AddTrayItem(item
);
966 tray
->ShowNotificationView(item
);
967 EXPECT_TRUE(status_area_widget
->IsMessageBubbleShown());
969 // Move the pointer over the edge of the shelf.
970 generator
.MoveMouseTo(
971 center
.x(), status_area_widget
->GetWindowBoundsInScreen().y() - 8);
972 shelf
->UpdateVisibilityState();
974 EXPECT_TRUE(shelf
->IsVisible());
975 EXPECT_TRUE(status_area_widget
->IsMessageBubbleShown());
977 EXPECT_FALSE(shelf
->IsVisible());
978 EXPECT_FALSE(status_area_widget
->IsMessageBubbleShown());
983 } // namespace internal