Don't preload rarely seen large images
[chromium-blink-merge.git] / ash / shelf / shelf_layout_manager_unittest.cc
blobb737e80e136a1255e6ec80ba107bc52bccb0bb54
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/display_manager_test_api.h"
26 #include "ash/test/shelf_test_api.h"
27 #include "ash/wm/window_state.h"
28 #include "ash/wm/window_util.h"
29 #include "base/command_line.h"
30 #include "base/strings/utf_string_conversions.h"
31 #include "ui/aura/client/aura_constants.h"
32 #include "ui/aura/client/window_tree_client.h"
33 #include "ui/aura/window.h"
34 #include "ui/aura/window_event_dispatcher.h"
35 #include "ui/compositor/layer.h"
36 #include "ui/compositor/layer_animator.h"
37 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
38 #include "ui/events/gesture_detection/gesture_configuration.h"
39 #include "ui/events/test/event_generator.h"
40 #include "ui/gfx/display.h"
41 #include "ui/gfx/screen.h"
42 #include "ui/views/controls/label.h"
43 #include "ui/views/layout/fill_layout.h"
44 #include "ui/views/view.h"
45 #include "ui/views/widget/widget.h"
47 #if defined(OS_WIN)
48 #include "base/win/windows_version.h"
49 #endif
51 namespace ash {
52 namespace {
54 void StepWidgetLayerAnimatorToEnd(views::Widget* widget) {
55 widget->GetNativeView()->layer()->GetAnimator()->Step(
56 base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1));
59 ShelfWidget* GetShelfWidget() {
60 return Shell::GetPrimaryRootWindowController()->shelf();
63 ShelfLayoutManager* GetShelfLayoutManager() {
64 return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
67 SystemTray* GetSystemTray() {
68 return Shell::GetPrimaryRootWindowController()->GetSystemTray();
71 // Class which waits till the shelf finishes animating to the target size and
72 // counts the number of animation steps.
73 class ShelfAnimationWaiter : views::WidgetObserver {
74 public:
75 explicit ShelfAnimationWaiter(const gfx::Rect& target_bounds)
76 : target_bounds_(target_bounds),
77 animation_steps_(0),
78 done_waiting_(false) {
79 GetShelfWidget()->AddObserver(this);
82 ~ShelfAnimationWaiter() override { GetShelfWidget()->RemoveObserver(this); }
84 // Wait till the shelf finishes animating to its expected bounds.
85 void WaitTillDoneAnimating() {
86 if (IsDoneAnimating())
87 done_waiting_ = true;
88 else
89 base::MessageLoop::current()->Run();
92 // Returns true if the animation has completed and it was valid.
93 bool WasValidAnimation() const {
94 return done_waiting_ && animation_steps_ > 0;
97 private:
98 // Returns true if shelf has finished animating to the target size.
99 bool IsDoneAnimating() const {
100 ShelfLayoutManager* layout_manager = GetShelfLayoutManager();
101 gfx::Rect current_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
102 int size = layout_manager->PrimaryAxisValue(current_bounds.height(),
103 current_bounds.width());
104 int desired_size = layout_manager->PrimaryAxisValue(target_bounds_.height(),
105 target_bounds_.width());
106 return (size == desired_size);
109 // views::WidgetObserver override.
110 void OnWidgetBoundsChanged(views::Widget* widget,
111 const gfx::Rect& new_bounds) override {
112 if (done_waiting_)
113 return;
115 ++animation_steps_;
116 if (IsDoneAnimating()) {
117 done_waiting_ = true;
118 base::MessageLoop::current()->Quit();
122 gfx::Rect target_bounds_;
123 int animation_steps_;
124 bool done_waiting_;
126 DISALLOW_COPY_AND_ASSIGN(ShelfAnimationWaiter);
129 class ShelfDragCallback {
130 public:
131 ShelfDragCallback(const gfx::Rect& not_visible, const gfx::Rect& visible)
132 : not_visible_bounds_(not_visible),
133 visible_bounds_(visible),
134 was_visible_on_drag_start_(false) {
135 EXPECT_EQ(not_visible_bounds_.bottom(), visible_bounds_.bottom());
138 virtual ~ShelfDragCallback() {
141 void ProcessScroll(ui::EventType type, const gfx::Vector2dF& delta) {
142 if (GetShelfLayoutManager()->visibility_state() == ash::SHELF_HIDDEN)
143 return;
145 if (type == ui::ET_GESTURE_SCROLL_BEGIN) {
146 scroll_ = gfx::Vector2dF();
147 was_visible_on_drag_start_ = GetShelfLayoutManager()->IsVisible();
148 return;
151 // The state of the shelf at the end of the gesture is tested separately.
152 if (type == ui::ET_GESTURE_SCROLL_END)
153 return;
155 if (type == ui::ET_GESTURE_SCROLL_UPDATE)
156 scroll_.Add(delta);
158 gfx::Rect shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
159 if (GetShelfLayoutManager()->IsHorizontalAlignment()) {
160 EXPECT_EQ(not_visible_bounds_.bottom(), shelf_bounds.bottom());
161 EXPECT_EQ(visible_bounds_.bottom(), shelf_bounds.bottom());
162 } else if (SHELF_ALIGNMENT_RIGHT ==
163 GetShelfLayoutManager()->GetAlignment()){
164 EXPECT_EQ(not_visible_bounds_.right(), shelf_bounds.right());
165 EXPECT_EQ(visible_bounds_.right(), shelf_bounds.right());
166 } else if (SHELF_ALIGNMENT_LEFT ==
167 GetShelfLayoutManager()->GetAlignment()) {
168 EXPECT_EQ(not_visible_bounds_.x(), shelf_bounds.x());
169 EXPECT_EQ(visible_bounds_.x(), shelf_bounds.x());
172 // if the shelf is being dimmed test dimmer bounds as well.
173 if (GetShelfWidget()->GetDimsShelf())
174 EXPECT_EQ(GetShelfWidget()->GetWindowBoundsInScreen(),
175 GetShelfWidget()->GetDimmerBoundsForTest());
177 // The shelf should never be smaller than the hidden state.
178 EXPECT_GE(shelf_bounds.height(), not_visible_bounds_.height());
179 float scroll_delta = GetShelfLayoutManager()->PrimaryAxisValue(
180 scroll_.y(),
181 scroll_.x());
182 bool increasing_drag =
183 GetShelfLayoutManager()->SelectValueForShelfAlignment(
184 scroll_delta < 0,
185 scroll_delta > 0,
186 scroll_delta < 0,
187 scroll_delta > 0);
188 int shelf_size = GetShelfLayoutManager()->PrimaryAxisValue(
189 shelf_bounds.height(),
190 shelf_bounds.width());
191 int visible_bounds_size = GetShelfLayoutManager()->PrimaryAxisValue(
192 visible_bounds_.height(),
193 visible_bounds_.width());
194 int not_visible_bounds_size = GetShelfLayoutManager()->PrimaryAxisValue(
195 not_visible_bounds_.height(),
196 not_visible_bounds_.width());
197 if (was_visible_on_drag_start_) {
198 if (increasing_drag) {
199 // If dragging inwards from the visible state, then the shelf should
200 // increase in size, but not more than the scroll delta.
201 EXPECT_LE(visible_bounds_size, shelf_size);
202 EXPECT_LE(std::abs(shelf_size - visible_bounds_size),
203 std::abs(scroll_delta));
204 } else {
205 if (shelf_size > not_visible_bounds_size) {
206 // If dragging outwards from the visible state, then the shelf
207 // should decrease in size, until it reaches the minimum size.
208 EXPECT_EQ(shelf_size, visible_bounds_size - std::abs(scroll_delta));
211 } else {
212 if (std::abs(scroll_delta) <
213 visible_bounds_size - not_visible_bounds_size) {
214 // Tests that the shelf sticks with the touch point during the drag
215 // until the shelf is completely visible.
216 EXPECT_EQ(shelf_size, not_visible_bounds_size + std::abs(scroll_delta));
217 } else {
218 // Tests that after the shelf is completely visible, the shelf starts
219 // resisting the drag.
220 EXPECT_LT(shelf_size, not_visible_bounds_size + std::abs(scroll_delta));
225 private:
226 const gfx::Rect not_visible_bounds_;
227 const gfx::Rect visible_bounds_;
228 gfx::Vector2dF scroll_;
229 bool was_visible_on_drag_start_;
231 DISALLOW_COPY_AND_ASSIGN(ShelfDragCallback);
234 class ShelfLayoutObserverTest : public ShelfLayoutManagerObserver {
235 public:
236 ShelfLayoutObserverTest()
237 : changed_auto_hide_state_(false) {
240 ~ShelfLayoutObserverTest() override {}
242 bool changed_auto_hide_state() const { return changed_auto_hide_state_; }
244 private:
245 void OnAutoHideStateChanged(ShelfAutoHideState new_state) override {
246 changed_auto_hide_state_ = true;
249 bool changed_auto_hide_state_;
251 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutObserverTest);
254 // Trivial item implementation that tracks its views for testing.
255 class TestItem : public SystemTrayItem {
256 public:
257 TestItem()
258 : SystemTrayItem(GetSystemTray()),
259 tray_view_(NULL),
260 default_view_(NULL),
261 detailed_view_(NULL),
262 notification_view_(NULL) {}
264 views::View* CreateTrayView(user::LoginStatus status) override {
265 tray_view_ = new views::View;
266 // Add a label so it has non-zero width.
267 tray_view_->SetLayoutManager(new views::FillLayout);
268 tray_view_->AddChildView(new views::Label(base::UTF8ToUTF16("Tray")));
269 return tray_view_;
272 views::View* CreateDefaultView(user::LoginStatus status) override {
273 default_view_ = new views::View;
274 default_view_->SetLayoutManager(new views::FillLayout);
275 default_view_->AddChildView(new views::Label(base::UTF8ToUTF16("Default")));
276 return default_view_;
279 views::View* CreateDetailedView(user::LoginStatus status) override {
280 detailed_view_ = new views::View;
281 detailed_view_->SetLayoutManager(new views::FillLayout);
282 detailed_view_->AddChildView(
283 new views::Label(base::UTF8ToUTF16("Detailed")));
284 return detailed_view_;
287 views::View* CreateNotificationView(user::LoginStatus status) override {
288 notification_view_ = new views::View;
289 return notification_view_;
292 void DestroyTrayView() override { tray_view_ = NULL; }
294 void DestroyDefaultView() override { default_view_ = NULL; }
296 void DestroyDetailedView() override { detailed_view_ = NULL; }
298 void DestroyNotificationView() override { notification_view_ = NULL; }
300 void UpdateAfterLoginStatusChange(user::LoginStatus status) override {}
302 views::View* tray_view() const { return tray_view_; }
303 views::View* default_view() const { return default_view_; }
304 views::View* detailed_view() const { return detailed_view_; }
305 views::View* notification_view() const { return notification_view_; }
307 private:
308 views::View* tray_view_;
309 views::View* default_view_;
310 views::View* detailed_view_;
311 views::View* notification_view_;
313 DISALLOW_COPY_AND_ASSIGN(TestItem);
316 } // namespace
318 class ShelfLayoutManagerTest : public ash::test::AshTestBase {
319 public:
320 ShelfLayoutManagerTest() {}
322 void SetState(ShelfLayoutManager* shelf,
323 ShelfVisibilityState state) {
324 shelf->SetState(state);
327 void UpdateAutoHideStateNow() {
328 GetShelfLayoutManager()->UpdateAutoHideStateNow();
331 aura::Window* CreateTestWindow() {
332 aura::Window* window = new aura::Window(NULL);
333 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
334 window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
335 window->Init(ui::LAYER_TEXTURED);
336 ParentWindowInPrimaryRootWindow(window);
337 return window;
340 aura::Window* CreateTestWindowInParent(aura::Window* root_window) {
341 aura::Window* window = new aura::Window(NULL);
342 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
343 window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
344 window->Init(ui::LAYER_TEXTURED);
345 aura::client::ParentWindowWithContext(window, root_window, gfx::Rect());
346 return window;
349 views::Widget* CreateTestWidgetWithParams(
350 const views::Widget::InitParams& params) {
351 views::Widget* out = new views::Widget;
352 out->Init(params);
353 out->Show();
354 return out;
357 // Create a simple widget attached to the current context (will
358 // delete on TearDown).
359 views::Widget* CreateTestWidget() {
360 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
361 params.bounds = gfx::Rect(0, 0, 200, 200);
362 params.context = CurrentContext();
363 return CreateTestWidgetWithParams(params);
366 void RunGestureDragTests(gfx::Vector2d);
368 // Turn on the lock screen.
369 void LockScreen() {
370 Shell::GetInstance()->session_state_delegate()->LockScreen();
371 // The test session state delegate does not fire the lock state change.
372 Shell::GetInstance()->OnLockStateChanged(true);
375 // Turn off the lock screen.
376 void UnlockScreen() {
377 Shell::GetInstance()->session_state_delegate()->UnlockScreen();
378 // The test session state delegate does not fire the lock state change.
379 Shell::GetInstance()->OnLockStateChanged(false);
382 // Open the add user screen if |show| is true, otherwise end it.
383 void ShowAddUserScreen(bool show) {
384 SetUserAddingScreenRunning(show);
385 ShelfLayoutManager* manager = GetShelfWidget()->shelf_layout_manager();
386 manager->SessionStateChanged(
387 show ? SessionStateDelegate::SESSION_STATE_LOGIN_SECONDARY :
388 SessionStateDelegate::SESSION_STATE_ACTIVE);
391 private:
392 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerTest);
395 void ShelfLayoutManagerTest::RunGestureDragTests(gfx::Vector2d delta) {
396 ShelfLayoutManager* shelf = GetShelfLayoutManager();
397 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
398 views::Widget* widget = new views::Widget;
399 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
400 params.bounds = gfx::Rect(0, 0, 200, 200);
401 params.context = CurrentContext();
402 widget->Init(params);
403 widget->Show();
404 widget->Maximize();
406 // The time delta should be large enough to prevent accidental fling creation.
407 const base::TimeDelta kTimeDelta = base::TimeDelta::FromMilliseconds(100);
409 aura::Window* window = widget->GetNativeWindow();
410 shelf->LayoutShelf();
412 gfx::Rect shelf_shown = GetShelfWidget()->GetWindowBoundsInScreen();
413 gfx::Rect bounds_shelf = window->bounds();
414 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
416 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
417 shelf->LayoutShelf();
418 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
420 gfx::Rect bounds_noshelf = window->bounds();
421 gfx::Rect shelf_hidden = GetShelfWidget()->GetWindowBoundsInScreen();
423 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
424 shelf->LayoutShelf();
426 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
427 const int kNumScrollSteps = 4;
428 ShelfDragCallback handler(shelf_hidden, shelf_shown);
430 // Swipe up on the shelf. This should not change any state.
431 gfx::Point start = GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint();
432 gfx::Point end = start + delta;
434 // Swipe down on the shelf to hide it.
435 generator.GestureScrollSequenceWithCallback(
436 start,
437 end,
438 kTimeDelta,
439 kNumScrollSteps,
440 base::Bind(&ShelfDragCallback::ProcessScroll,
441 base::Unretained(&handler)));
442 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
443 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
444 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
445 EXPECT_NE(bounds_shelf.ToString(), window->bounds().ToString());
446 EXPECT_NE(shelf_shown.ToString(),
447 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
449 // Swipe up to show the shelf.
450 generator.GestureScrollSequenceWithCallback(
451 end,
452 start,
453 kTimeDelta,
454 kNumScrollSteps,
455 base::Bind(&ShelfDragCallback::ProcessScroll,
456 base::Unretained(&handler)));
457 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
458 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
459 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
460 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
461 GetShelfWidget()->GetWindowBoundsInScreen());
462 EXPECT_EQ(shelf_shown.ToString(),
463 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
465 // Swipe up again. The shelf should hide.
466 end = start - delta;
467 generator.GestureScrollSequenceWithCallback(
468 start,
469 end,
470 kTimeDelta,
471 kNumScrollSteps,
472 base::Bind(&ShelfDragCallback::ProcessScroll,
473 base::Unretained(&handler)));
474 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
475 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
476 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
477 EXPECT_EQ(shelf_hidden.ToString(),
478 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
480 // Swipe up yet again to show it.
481 end = start + delta;
482 generator.GestureScrollSequenceWithCallback(
483 end,
484 start,
485 kTimeDelta,
486 kNumScrollSteps,
487 base::Bind(&ShelfDragCallback::ProcessScroll,
488 base::Unretained(&handler)));
490 // Swipe down very little. It shouldn't change any state.
491 if (GetShelfLayoutManager()->IsHorizontalAlignment())
492 end.set_y(start.y() + shelf_shown.height() * 3 / 10);
493 else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment())
494 end.set_x(start.x() - shelf_shown.width() * 3 / 10);
495 else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment())
496 end.set_x(start.x() + shelf_shown.width() * 3 / 10);
497 generator.GestureScrollSequence(start, end, kTimeDelta, 5);
498 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
499 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
500 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
501 EXPECT_EQ(shelf_shown.ToString(),
502 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
504 // Swipe down again to hide.
505 end = start + delta;
506 generator.GestureScrollSequenceWithCallback(
507 start,
508 end,
509 kTimeDelta,
510 kNumScrollSteps,
511 base::Bind(&ShelfDragCallback::ProcessScroll,
512 base::Unretained(&handler)));
513 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
514 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
515 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
516 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
517 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
518 EXPECT_EQ(shelf_hidden.ToString(),
519 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
521 // Swipe up in extended hit region to show it.
522 gfx::Point extended_start = start;
523 if (GetShelfLayoutManager()->IsHorizontalAlignment())
524 extended_start.set_y(GetShelfWidget()->GetWindowBoundsInScreen().y() -1);
525 else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment())
526 extended_start.set_x(
527 GetShelfWidget()->GetWindowBoundsInScreen().right() + 1);
528 else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment())
529 extended_start.set_x(GetShelfWidget()->GetWindowBoundsInScreen().x() - 1);
530 end = extended_start - delta;
531 generator.GestureScrollSequenceWithCallback(
532 extended_start,
533 end,
534 kTimeDelta,
535 kNumScrollSteps,
536 base::Bind(&ShelfDragCallback::ProcessScroll,
537 base::Unretained(&handler)));
538 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
539 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
540 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
541 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
542 GetShelfWidget()->GetWindowBoundsInScreen());
543 EXPECT_EQ(shelf_shown.ToString(),
544 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
546 // Swipe down again to hide.
547 end = start + delta;
548 generator.GestureScrollSequenceWithCallback(
549 start,
550 end,
551 kTimeDelta,
552 kNumScrollSteps,
553 base::Bind(&ShelfDragCallback::ProcessScroll,
554 base::Unretained(&handler)));
555 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
556 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
557 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
558 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
559 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
560 EXPECT_EQ(shelf_hidden.ToString(),
561 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
563 // Swipe up outside the hit area. This should not change anything.
564 gfx::Point outside_start = gfx::Point(
565 (GetShelfWidget()->GetWindowBoundsInScreen().x() +
566 GetShelfWidget()->GetWindowBoundsInScreen().right())/2,
567 GetShelfWidget()->GetWindowBoundsInScreen().y() - 50);
568 end = outside_start + delta;
569 generator.GestureScrollSequence(
570 outside_start, end, kTimeDelta, kNumScrollSteps);
571 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
572 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
573 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
574 EXPECT_EQ(shelf_hidden.ToString(),
575 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
577 // Swipe up from below the shelf where a bezel would be, this should show the
578 // shelf.
579 gfx::Point below_start = start;
580 if (GetShelfLayoutManager()->IsHorizontalAlignment())
581 below_start.set_y(GetShelfWidget()->GetWindowBoundsInScreen().bottom() + 1);
582 else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment())
583 below_start.set_x(
584 GetShelfWidget()->GetWindowBoundsInScreen().x() - 1);
585 else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment())
586 below_start.set_x(GetShelfWidget()->GetWindowBoundsInScreen().right() + 1);
587 end = below_start - delta;
588 generator.GestureScrollSequence(
589 below_start, end, kTimeDelta, kNumScrollSteps);
590 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
591 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
592 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
593 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
594 GetShelfWidget()->GetWindowBoundsInScreen());
595 EXPECT_EQ(shelf_shown.ToString(),
596 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
598 // Swipe down again to hide.
599 end = start + delta;
600 generator.GestureScrollSequenceWithCallback(
601 start,
602 end,
603 kTimeDelta,
604 kNumScrollSteps,
605 base::Bind(&ShelfDragCallback::ProcessScroll,
606 base::Unretained(&handler)));
607 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
608 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
609 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
610 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
611 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
612 EXPECT_EQ(shelf_hidden.ToString(),
613 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
615 // Put |widget| into fullscreen. Set the shelf to be auto hidden when |widget|
616 // is fullscreen. (eg browser immersive fullscreen).
617 widget->SetFullscreen(true);
618 wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(false);
619 shelf->UpdateVisibilityState();
621 gfx::Rect bounds_fullscreen = window->bounds();
622 EXPECT_TRUE(widget->IsFullscreen());
623 EXPECT_NE(bounds_noshelf.ToString(), bounds_fullscreen.ToString());
625 // Swipe up. This should show the shelf.
626 end = below_start - delta;
627 generator.GestureScrollSequenceWithCallback(
628 below_start,
629 end,
630 kTimeDelta,
631 kNumScrollSteps,
632 base::Bind(&ShelfDragCallback::ProcessScroll,
633 base::Unretained(&handler)));
634 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
635 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
636 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
637 EXPECT_EQ(shelf_shown.ToString(),
638 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
639 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString());
641 // Swipe up again. This should hide the shelf.
642 generator.GestureScrollSequenceWithCallback(
643 below_start,
644 end,
645 kTimeDelta,
646 kNumScrollSteps,
647 base::Bind(&ShelfDragCallback::ProcessScroll,
648 base::Unretained(&handler)));
649 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
650 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
651 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
652 EXPECT_EQ(shelf_hidden.ToString(),
653 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
654 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString());
656 // Set the shelf to be hidden when |widget| is fullscreen. (eg tab fullscreen
657 // with or without immersive browser fullscreen).
658 wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(true);
659 shelf->UpdateVisibilityState();
660 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
661 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
663 // Swipe-up. This should not change anything.
664 end = start - delta;
665 generator.GestureScrollSequenceWithCallback(
666 below_start,
667 end,
668 kTimeDelta,
669 kNumScrollSteps,
670 base::Bind(&ShelfDragCallback::ProcessScroll,
671 base::Unretained(&handler)));
672 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
673 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
674 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString());
676 // Close actually, otherwise further event may be affected since widget
677 // is fullscreen status.
678 widget->Close();
679 RunAllPendingInMessageLoop();
681 // The shelf should be shown because there are no more visible windows.
682 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
683 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
684 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
686 // Swipe-up to hide. This should have no effect because there are no visible
687 // windows.
688 end = below_start - delta;
689 generator.GestureScrollSequenceWithCallback(
690 below_start,
691 end,
692 kTimeDelta,
693 kNumScrollSteps,
694 base::Bind(&ShelfDragCallback::ProcessScroll,
695 base::Unretained(&handler)));
696 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
697 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
698 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
701 // Need to be implemented. http://crbug.com/111279.
702 #if defined(OS_WIN)
703 #define MAYBE_SetVisible DISABLED_SetVisible
704 #else
705 #define MAYBE_SetVisible SetVisible
706 #endif
707 // Makes sure SetVisible updates work area and widget appropriately.
708 TEST_F(ShelfLayoutManagerTest, MAYBE_SetVisible) {
709 ShelfWidget* shelf = GetShelfWidget();
710 ShelfLayoutManager* manager = shelf->shelf_layout_manager();
711 // Force an initial layout.
712 manager->LayoutShelf();
713 EXPECT_EQ(SHELF_VISIBLE, manager->visibility_state());
715 gfx::Rect status_bounds(
716 shelf->status_area_widget()->GetWindowBoundsInScreen());
717 gfx::Rect shelf_bounds(
718 shelf->GetWindowBoundsInScreen());
719 int shelf_height = manager->GetIdealBounds().height();
720 gfx::Screen* screen = Shell::GetScreen();
721 gfx::Display display = screen->GetDisplayNearestWindow(
722 Shell::GetPrimaryRootWindow());
723 ASSERT_NE(-1, display.id());
724 // Bottom inset should be the max of widget heights.
725 EXPECT_EQ(shelf_height, display.GetWorkAreaInsets().bottom());
727 // Hide the shelf.
728 SetState(manager, SHELF_HIDDEN);
729 // Run the animation to completion.
730 StepWidgetLayerAnimatorToEnd(shelf);
731 StepWidgetLayerAnimatorToEnd(shelf->status_area_widget());
732 EXPECT_EQ(SHELF_HIDDEN, manager->visibility_state());
733 display = screen->GetDisplayNearestWindow(
734 Shell::GetPrimaryRootWindow());
736 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
738 // Make sure the bounds of the two widgets changed.
739 EXPECT_GE(shelf->GetNativeView()->bounds().y(),
740 screen->GetPrimaryDisplay().bounds().bottom());
741 EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(),
742 screen->GetPrimaryDisplay().bounds().bottom());
744 // And show it again.
745 SetState(manager, SHELF_VISIBLE);
746 // Run the animation to completion.
747 StepWidgetLayerAnimatorToEnd(shelf);
748 StepWidgetLayerAnimatorToEnd(shelf->status_area_widget());
749 EXPECT_EQ(SHELF_VISIBLE, manager->visibility_state());
750 display = screen->GetDisplayNearestWindow(
751 Shell::GetPrimaryRootWindow());
752 EXPECT_EQ(shelf_height, display.GetWorkAreaInsets().bottom());
754 // Make sure the bounds of the two widgets changed.
755 shelf_bounds = shelf->GetNativeView()->bounds();
756 EXPECT_LT(shelf_bounds.y(), screen->GetPrimaryDisplay().bounds().bottom());
757 status_bounds = shelf->status_area_widget()->GetNativeView()->bounds();
758 EXPECT_LT(status_bounds.y(),
759 screen->GetPrimaryDisplay().bounds().bottom());
762 // Makes sure shelf alignment is correct for lock screen.
763 TEST_F(ShelfLayoutManagerTest, SideAlignmentInteractionWithLockScreen) {
764 ShelfLayoutManager* manager = GetShelfWidget()->shelf_layout_manager();
765 manager->SetAlignment(SHELF_ALIGNMENT_LEFT);
766 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, manager->GetAlignment());
767 LockScreen();
768 EXPECT_EQ(SHELF_ALIGNMENT_BOTTOM, manager->GetAlignment());
769 UnlockScreen();
770 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, manager->GetAlignment());
773 // Makes sure shelf alignment is correct for add user screen.
774 TEST_F(ShelfLayoutManagerTest, SideAlignmentInteractionWithAddUserScreen) {
775 ShelfLayoutManager* manager = GetShelfWidget()->shelf_layout_manager();
776 manager->SetAlignment(SHELF_ALIGNMENT_LEFT);
777 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, manager->GetAlignment());
778 ShowAddUserScreen(true);
779 EXPECT_EQ(SHELF_ALIGNMENT_BOTTOM, manager->GetAlignment());
780 ShowAddUserScreen(false);
781 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, manager->GetAlignment());
784 // Makes sure shelf alignment is correct for login screen.
785 TEST_F(ShelfLayoutManagerTest, SideAlignmentInteractionWithLoginScreen) {
786 ShelfLayoutManager* manager = GetShelfWidget()->shelf_layout_manager();
787 ASSERT_EQ(SHELF_ALIGNMENT_BOTTOM, manager->GetAlignment());
788 SetUserLoggedIn(false);
789 SetSessionStarted(false);
791 // The test session state delegate does not fire state changes.
792 SetSessionStarting();
793 manager->SessionStateChanged(
794 Shell::GetInstance()->session_state_delegate()->GetSessionState());
796 // Login sets alignment preferences before the session completes startup.
797 manager->SetAlignment(SHELF_ALIGNMENT_LEFT);
798 SetUserLoggedIn(true);
799 SetSessionStarted(true);
801 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, manager->GetAlignment());
802 // Ensure that the shelf has been notified.
803 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, GetShelfWidget()->shelf()->alignment());
806 // Makes sure LayoutShelf invoked while animating cleans things up.
807 TEST_F(ShelfLayoutManagerTest, LayoutShelfWhileAnimating) {
808 ShelfWidget* shelf = GetShelfWidget();
809 // Force an initial layout.
810 shelf->shelf_layout_manager()->LayoutShelf();
811 EXPECT_EQ(SHELF_VISIBLE, shelf->shelf_layout_manager()->visibility_state());
813 // Hide the shelf.
814 SetState(shelf->shelf_layout_manager(), SHELF_HIDDEN);
815 shelf->shelf_layout_manager()->LayoutShelf();
816 EXPECT_EQ(SHELF_HIDDEN, shelf->shelf_layout_manager()->visibility_state());
817 gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow(
818 Shell::GetPrimaryRootWindow());
819 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
821 // Make sure the bounds of the two widgets changed.
822 EXPECT_GE(shelf->GetNativeView()->bounds().y(),
823 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
824 EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(),
825 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
828 // Test that switching to a different visibility state does not restart the
829 // shelf show / hide animation if it is already running. (crbug.com/250918)
830 TEST_F(ShelfLayoutManagerTest, SetStateWhileAnimating) {
831 ShelfWidget* shelf = GetShelfWidget();
832 SetState(shelf->shelf_layout_manager(), SHELF_VISIBLE);
833 gfx::Rect initial_shelf_bounds = shelf->GetWindowBoundsInScreen();
834 gfx::Rect initial_status_bounds =
835 shelf->status_area_widget()->GetWindowBoundsInScreen();
837 ui::ScopedAnimationDurationScaleMode normal_animation_duration(
838 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
839 SetState(shelf->shelf_layout_manager(), SHELF_HIDDEN);
840 SetState(shelf->shelf_layout_manager(), SHELF_VISIBLE);
842 gfx::Rect current_shelf_bounds = shelf->GetWindowBoundsInScreen();
843 gfx::Rect current_status_bounds =
844 shelf->status_area_widget()->GetWindowBoundsInScreen();
846 const int small_change = initial_shelf_bounds.height() / 2;
847 EXPECT_LE(
848 std::abs(initial_shelf_bounds.height() - current_shelf_bounds.height()),
849 small_change);
850 EXPECT_LE(
851 std::abs(initial_status_bounds.height() - current_status_bounds.height()),
852 small_change);
855 // Makes sure the shelf is sized when the status area changes size.
856 TEST_F(ShelfLayoutManagerTest, ShelfUpdatedWhenStatusAreaChangesSize) {
857 Shelf* shelf = Shelf::ForPrimaryDisplay();
858 ASSERT_TRUE(shelf);
859 ShelfWidget* shelf_widget = GetShelfWidget();
860 ASSERT_TRUE(shelf_widget);
861 ASSERT_TRUE(shelf_widget->status_area_widget());
862 shelf_widget->status_area_widget()->SetBounds(
863 gfx::Rect(0, 0, 200, 200));
864 EXPECT_EQ(200, shelf_widget->GetContentsView()->width() -
865 test::ShelfTestAPI(shelf).shelf_view()->width());
869 #if defined(OS_WIN)
870 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
871 #define MAYBE_AutoHide DISABLED_AutoHide
872 #else
873 #define MAYBE_AutoHide AutoHide
874 #endif
876 // Various assertions around auto-hide.
877 TEST_F(ShelfLayoutManagerTest, MAYBE_AutoHide) {
878 aura::Window* root = Shell::GetPrimaryRootWindow();
879 ui::test::EventGenerator generator(root, root);
880 generator.MoveMouseTo(0, 0);
882 ShelfLayoutManager* shelf = GetShelfLayoutManager();
883 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
884 views::Widget* widget = new views::Widget;
885 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
886 params.bounds = gfx::Rect(0, 0, 200, 200);
887 params.context = CurrentContext();
888 // Widget is now owned by the parent window.
889 widget->Init(params);
890 widget->Maximize();
891 widget->Show();
892 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
893 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
895 // LayoutShelf() forces the animation to completion, at which point the
896 // shelf should go off the screen.
897 shelf->LayoutShelf();
898 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
899 GetShelfWidget()->GetWindowBoundsInScreen().y());
900 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
901 Shell::GetScreen()->GetDisplayNearestWindow(
902 root).work_area().bottom());
904 // Move the mouse to the bottom of the screen.
905 generator.MoveMouseTo(0, root->bounds().bottom() - 1);
907 // Shelf should be shown again (but it shouldn't have changed the work area).
908 SetState(shelf, SHELF_AUTO_HIDE);
909 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
910 shelf->LayoutShelf();
911 EXPECT_EQ(root->bounds().bottom() - shelf->GetIdealBounds().height(),
912 GetShelfWidget()->GetWindowBoundsInScreen().y());
913 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
914 Shell::GetScreen()->GetDisplayNearestWindow(
915 root).work_area().bottom());
917 // Move mouse back up.
918 generator.MoveMouseTo(0, 0);
919 SetState(shelf, SHELF_AUTO_HIDE);
920 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
921 shelf->LayoutShelf();
922 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
923 GetShelfWidget()->GetWindowBoundsInScreen().y());
925 // Drag mouse to bottom of screen.
926 generator.PressLeftButton();
927 generator.MoveMouseTo(0, root->bounds().bottom() - 1);
928 UpdateAutoHideStateNow();
929 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
931 generator.ReleaseLeftButton();
932 generator.MoveMouseTo(1, root->bounds().bottom() - 1);
933 UpdateAutoHideStateNow();
934 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
935 generator.PressLeftButton();
936 generator.MoveMouseTo(1, root->bounds().bottom() - 1);
937 UpdateAutoHideStateNow();
938 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
941 // Test the behavior of the shelf when it is auto hidden and it is on the
942 // boundary between the primary and the secondary display.
943 TEST_F(ShelfLayoutManagerTest, AutoHideShelfOnScreenBoundary) {
944 if (!SupportsMultipleDisplays())
945 return;
947 UpdateDisplay("800x600,800x600");
948 DisplayLayout display_layout(DisplayLayout::RIGHT, 0);
949 Shell::GetInstance()->display_manager()->SetLayoutForCurrentDisplays(
950 display_layout);
951 // Put the primary monitor's shelf on the display boundary.
952 ShelfLayoutManager* shelf = GetShelfLayoutManager();
953 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
955 // Create a window because the shelf is always shown when no windows are
956 // visible.
957 CreateTestWidget();
959 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
960 ASSERT_EQ(root_windows[0],
961 GetShelfWidget()->GetNativeWindow()->GetRootWindow());
963 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
964 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
966 int right_edge = root_windows[0]->GetBoundsInScreen().right() - 1;
967 int y = root_windows[0]->GetBoundsInScreen().y();
969 // Start off the mouse nowhere near the shelf; the shelf should be hidden.
970 ui::test::EventGenerator& generator(GetEventGenerator());
971 generator.MoveMouseTo(right_edge - 50, y);
972 UpdateAutoHideStateNow();
973 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
975 // Moving the mouse over the light bar (but not to the edge of the screen)
976 // should show the shelf.
977 generator.MoveMouseTo(right_edge - 1, y);
978 UpdateAutoHideStateNow();
979 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
980 EXPECT_EQ(right_edge - 1, Shell::GetScreen()->GetCursorScreenPoint().x());
982 // Moving the mouse off the light bar should hide the shelf.
983 generator.MoveMouseTo(right_edge - 50, y);
984 UpdateAutoHideStateNow();
985 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
987 // Moving the mouse to the right edge of the screen crossing the light bar
988 // should show the shelf despite the mouse cursor getting warped to the
989 // secondary display.
990 generator.MoveMouseTo(right_edge - 1, y);
991 generator.MoveMouseTo(right_edge, y);
992 UpdateAutoHideStateNow();
993 EXPECT_NE(right_edge - 1, Shell::GetScreen()->GetCursorScreenPoint().x());
994 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
996 // Hide the shelf.
997 generator.MoveMouseTo(right_edge - 50, y);
998 UpdateAutoHideStateNow();
999 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1001 // Moving the mouse to the right edge of the screen crossing the light bar and
1002 // overshooting by a lot should keep the shelf hidden.
1003 generator.MoveMouseTo(right_edge - 1, y);
1004 generator.MoveMouseTo(right_edge + 50, y);
1005 UpdateAutoHideStateNow();
1006 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1008 // Moving the mouse to the right edge of the screen crossing the light bar and
1009 // overshooting a bit should show the shelf.
1010 generator.MoveMouseTo(right_edge - 1, y);
1011 generator.MoveMouseTo(right_edge + 2, y);
1012 UpdateAutoHideStateNow();
1013 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1015 // Keeping the mouse close to the left edge of the secondary display after the
1016 // shelf is shown should keep the shelf shown.
1017 generator.MoveMouseTo(right_edge + 2, y + 1);
1018 UpdateAutoHideStateNow();
1019 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1021 // Moving the mouse far from the left edge of the secondary display should
1022 // hide the shelf.
1023 generator.MoveMouseTo(right_edge + 50, y);
1024 UpdateAutoHideStateNow();
1025 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1027 // Moving to the left edge of the secondary display without first crossing
1028 // the primary display's right aligned shelf first should not show the shelf.
1029 generator.MoveMouseTo(right_edge + 2, y);
1030 UpdateAutoHideStateNow();
1031 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1034 // Assertions around the lock screen showing.
1035 TEST_F(ShelfLayoutManagerTest, VisibleWhenLockScreenShowing) {
1036 if (!SupportsHostWindowResize())
1037 return;
1039 // Since ShelfLayoutManager queries for mouse location, move the mouse so
1040 // it isn't over the shelf.
1041 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1042 gfx::Point());
1043 generator.MoveMouseTo(0, 0);
1045 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1046 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1047 views::Widget* widget = new views::Widget;
1048 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1049 params.bounds = gfx::Rect(0, 0, 200, 200);
1050 params.context = CurrentContext();
1051 // Widget is now owned by the parent window.
1052 widget->Init(params);
1053 widget->Maximize();
1054 widget->Show();
1055 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1056 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1058 aura::Window* root = Shell::GetPrimaryRootWindow();
1059 // LayoutShelf() forces the animation to completion, at which point the
1060 // shelf should go off the screen.
1061 shelf->LayoutShelf();
1062 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
1063 GetShelfWidget()->GetWindowBoundsInScreen().y());
1065 aura::Window* lock_container = Shell::GetContainer(
1066 Shell::GetPrimaryRootWindow(), kShellWindowId_LockScreenContainer);
1068 views::Widget* lock_widget = new views::Widget;
1069 views::Widget::InitParams lock_params(
1070 views::Widget::InitParams::TYPE_WINDOW);
1071 lock_params.bounds = gfx::Rect(0, 0, 200, 200);
1072 params.context = CurrentContext();
1073 lock_params.parent = lock_container;
1074 // Widget is now owned by the parent window.
1075 lock_widget->Init(lock_params);
1076 lock_widget->Maximize();
1077 lock_widget->Show();
1079 // Lock the screen.
1080 LockScreen();
1081 // Showing a widget in the lock screen should force the shelf to be visibile.
1082 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1084 UnlockScreen();
1085 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1088 // Assertions around SetAutoHideBehavior.
1089 TEST_F(ShelfLayoutManagerTest, SetAutoHideBehavior) {
1090 // Since ShelfLayoutManager queries for mouse location, move the mouse so
1091 // it isn't over the shelf.
1092 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1093 gfx::Point());
1094 generator.MoveMouseTo(0, 0);
1096 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1097 views::Widget* widget = new views::Widget;
1098 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1099 params.bounds = gfx::Rect(0, 0, 200, 200);
1100 params.context = CurrentContext();
1101 // Widget is now owned by the parent window.
1102 widget->Init(params);
1103 widget->Show();
1104 aura::Window* window = widget->GetNativeWindow();
1105 gfx::Rect display_bounds(
1106 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
1108 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1109 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1111 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1112 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1114 widget->Maximize();
1115 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1116 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
1117 window).work_area().bottom(),
1118 widget->GetWorkAreaBoundsInScreen().bottom());
1120 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1121 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1122 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
1123 window).work_area().bottom(),
1124 widget->GetWorkAreaBoundsInScreen().bottom());
1126 ui::ScopedAnimationDurationScaleMode animation_duration(
1127 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
1129 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1130 ShelfWidget* shelf_widget = GetShelfWidget();
1131 EXPECT_TRUE(shelf_widget->status_area_widget()->IsVisible());
1132 StepWidgetLayerAnimatorToEnd(shelf_widget);
1133 StepWidgetLayerAnimatorToEnd(shelf_widget->status_area_widget());
1134 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1135 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
1136 window).work_area().bottom(),
1137 widget->GetWorkAreaBoundsInScreen().bottom());
1140 // Basic assertions around the dimming of the shelf.
1141 TEST_F(ShelfLayoutManagerTest, DimmingBehavior) {
1142 // Since ShelfLayoutManager queries for mouse location, move the mouse so
1143 // it isn't over the shelf.
1144 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1145 gfx::Point());
1146 generator.MoveMouseTo(0, 0);
1148 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1149 shelf->shelf_widget()->DisableDimmingAnimationsForTest();
1151 views::Widget* widget = new views::Widget;
1152 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1153 params.bounds = gfx::Rect(0, 0, 200, 200);
1154 params.context = CurrentContext();
1155 // Widget is now owned by the parent window.
1156 widget->Init(params);
1157 widget->Show();
1158 aura::Window* window = widget->GetNativeWindow();
1159 gfx::Rect display_bounds(
1160 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
1162 gfx::Point off_shelf = display_bounds.CenterPoint();
1163 gfx::Point on_shelf =
1164 shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
1166 // Test there is no dimming object active at this point.
1167 generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
1168 EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
1169 generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
1170 EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
1172 // After maximization, the shelf should be visible and the dimmer created.
1173 widget->Maximize();
1175 on_shelf = shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
1176 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1178 // Moving the mouse off the shelf should dim the bar.
1179 generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
1180 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1182 // Adding touch events outside the shelf should still keep the shelf in
1183 // dimmed state.
1184 generator.PressTouch();
1185 generator.MoveTouch(off_shelf);
1186 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1187 // Move the touch into the shelf area should undim.
1188 generator.MoveTouch(on_shelf);
1189 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1190 generator.ReleaseTouch();
1191 // And a release dims again.
1192 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1194 // Moving the mouse on the shelf should undim the bar.
1195 generator.MoveMouseTo(on_shelf);
1196 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1198 // No matter what the touch events do, the shelf should stay undimmed.
1199 generator.PressTouch();
1200 generator.MoveTouch(off_shelf);
1201 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1202 generator.MoveTouch(on_shelf);
1203 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1204 generator.MoveTouch(off_shelf);
1205 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1206 generator.MoveTouch(on_shelf);
1207 generator.ReleaseTouch();
1209 // After restore, the dimming object should be deleted again.
1210 widget->Restore();
1211 EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
1214 // Test that dimming works correctly with multiple displays.
1215 TEST_F(ShelfLayoutManagerTest, DimmingBehaviorDualDisplay) {
1216 if (!SupportsMultipleDisplays())
1217 return;
1219 // Create two displays.
1220 Shell* shell = Shell::GetInstance();
1221 UpdateDisplay("0+0-200x200,+200+0-100x100");
1222 EXPECT_EQ(2U, shell->display_manager()->GetNumDisplays());
1224 DisplayController* display_controller = shell->display_controller();
1225 aura::Window::Windows root_windows = display_controller->GetAllRootWindows();
1226 EXPECT_EQ(root_windows.size(), 2U);
1228 std::vector<ShelfWidget*> shelf_widgets;
1229 for (auto& root_window : root_windows) {
1230 ShelfLayoutManager* shelf =
1231 GetRootWindowController(root_window)->GetShelfLayoutManager();
1232 shelf_widgets.push_back(shelf->shelf_widget());
1234 // For disabling the dimming animation to work, the animation must be
1235 // disabled prior to creating the dimmer.
1236 shelf_widgets.back()->DisableDimmingAnimationsForTest();
1238 // Create a maximized window to create the dimmer.
1239 views::Widget* widget = new views::Widget;
1240 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1241 params.context = root_window;
1242 params.bounds = root_window->GetBoundsInScreen();
1243 params.show_state = ui::SHOW_STATE_MAXIMIZED;
1244 widget->Init(params);
1245 widget->Show();
1248 ui::test::EventGenerator& generator(GetEventGenerator());
1250 generator.MoveMouseTo(root_windows[0]->GetBoundsInScreen().CenterPoint());
1251 EXPECT_LT(0, shelf_widgets[0]->GetDimmingAlphaForTest());
1252 EXPECT_LT(0, shelf_widgets[1]->GetDimmingAlphaForTest());
1254 generator.MoveMouseTo(
1255 shelf_widgets[0]->GetWindowBoundsInScreen().CenterPoint());
1256 EXPECT_EQ(0, shelf_widgets[0]->GetDimmingAlphaForTest());
1257 EXPECT_LT(0, shelf_widgets[1]->GetDimmingAlphaForTest());
1259 generator.MoveMouseTo(
1260 shelf_widgets[1]->GetWindowBoundsInScreen().CenterPoint());
1261 EXPECT_LT(0, shelf_widgets[0]->GetDimmingAlphaForTest());
1262 EXPECT_EQ(0, shelf_widgets[1]->GetDimmingAlphaForTest());
1264 generator.MoveMouseTo(root_windows[1]->GetBoundsInScreen().CenterPoint());
1265 EXPECT_LT(0, shelf_widgets[0]->GetDimmingAlphaForTest());
1266 EXPECT_LT(0, shelf_widgets[1]->GetDimmingAlphaForTest());
1269 // Assertions around the dimming of the shelf in conjunction with menus.
1270 TEST_F(ShelfLayoutManagerTest, DimmingBehaviorWithMenus) {
1271 // Since ShelfLayoutManager queries for mouse location, move the mouse so
1272 // it isn't over the shelf.
1273 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1274 gfx::Point());
1275 generator.MoveMouseTo(0, 0);
1277 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1278 shelf->shelf_widget()->DisableDimmingAnimationsForTest();
1280 views::Widget* widget = new views::Widget;
1281 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1282 params.bounds = gfx::Rect(0, 0, 200, 200);
1283 params.context = CurrentContext();
1284 // Widget is now owned by the parent window.
1285 widget->Init(params);
1286 widget->Show();
1287 aura::Window* window = widget->GetNativeWindow();
1288 gfx::Rect display_bounds(
1289 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
1291 // After maximization, the shelf should be visible and the dimmer created.
1292 widget->Maximize();
1294 gfx::Point off_shelf = display_bounds.CenterPoint();
1295 gfx::Point on_shelf =
1296 shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
1298 // Moving the mouse on the shelf should undim the bar.
1299 generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
1300 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1302 // Simulate a menu opening.
1303 shelf->shelf_widget()->ForceUndimming(true);
1305 // Moving the mouse off the shelf should not dim the bar.
1306 generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
1307 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1309 // No matter what the touch events do, the shelf should stay undimmed.
1310 generator.PressTouch();
1311 generator.MoveTouch(off_shelf);
1312 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1313 generator.MoveTouch(on_shelf);
1314 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1315 generator.MoveTouch(off_shelf);
1316 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1317 generator.ReleaseTouch();
1318 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1320 // "Closing the menu" should now turn off the menu since no event is inside
1321 // the shelf any longer.
1322 shelf->shelf_widget()->ForceUndimming(false);
1323 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1325 // Moving the mouse again on the shelf which should undim the bar again.
1326 // This time we check that the bar stays undimmed when the mouse remains on
1327 // the bar and the "menu gets closed".
1328 generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
1329 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1330 shelf->shelf_widget()->ForceUndimming(true);
1331 generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
1332 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1333 generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
1334 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1335 shelf->shelf_widget()->ForceUndimming(true);
1336 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1339 // Verifies the shelf is visible when status/shelf is focused.
1340 TEST_F(ShelfLayoutManagerTest, VisibleWhenStatusOrShelfFocused) {
1341 // Since ShelfLayoutManager queries for mouse location, move the mouse so
1342 // it isn't over the shelf.
1343 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1344 gfx::Point());
1345 generator.MoveMouseTo(0, 0);
1347 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1348 views::Widget* widget = new views::Widget;
1349 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1350 params.bounds = gfx::Rect(0, 0, 200, 200);
1351 params.context = CurrentContext();
1352 // Widget is now owned by the parent window.
1353 widget->Init(params);
1354 widget->Show();
1355 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1356 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1357 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1359 // Focus the shelf. Have to go through the focus cycler as normal focus
1360 // requests to it do nothing.
1361 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD);
1362 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1364 widget->Activate();
1365 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1367 // Trying to activate the status should fail, since we only allow activating
1368 // it when the user is using the keyboard (i.e. through FocusCycler).
1369 GetShelfWidget()->status_area_widget()->Activate();
1370 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1372 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD);
1373 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1376 // Makes sure shelf will be visible when app list opens as shelf is in
1377 // SHELF_VISIBLE state,and toggling app list won't change shelf
1378 // visibility state.
1379 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfVisibleState) {
1380 Shell* shell = Shell::GetInstance();
1381 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1382 shelf->LayoutShelf();
1383 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1385 // Create a normal unmaximized windowm shelf should be visible.
1386 aura::Window* window = CreateTestWindow();
1387 window->SetBounds(gfx::Rect(0, 0, 100, 100));
1388 window->Show();
1389 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1390 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1392 // Show app list and the shelf stays visible.
1393 shell->ShowAppList(NULL);
1394 EXPECT_TRUE(shell->GetAppListTargetVisibility());
1395 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1397 // Hide app list and the shelf stays visible.
1398 shell->DismissAppList();
1399 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1400 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1403 // Makes sure shelf will be shown with SHELF_AUTO_HIDE_SHOWN state
1404 // when app list opens as shelf is in SHELF_AUTO_HIDE state, and
1405 // toggling app list won't change shelf visibility state.
1406 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfAutoHideState) {
1407 Shell* shell = Shell::GetInstance();
1408 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1409 shelf->LayoutShelf();
1410 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1412 // Create a window and show it in maximized state.
1413 aura::Window* window = CreateTestWindow();
1414 window->SetBounds(gfx::Rect(0, 0, 100, 100));
1415 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1416 window->Show();
1417 wm::ActivateWindow(window);
1419 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1420 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1422 // Show app list.
1423 shell->ShowAppList(NULL);
1424 // The shelf's auto hide state won't be changed until the timer fires, so
1425 // calling shell->UpdateShelfVisibility() is kind of manually helping it to
1426 // update the state.
1427 shell->UpdateShelfVisibility();
1428 EXPECT_TRUE(shell->GetAppListTargetVisibility());
1429 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1430 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1432 // Hide app list.
1433 shell->DismissAppList();
1434 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1435 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1438 // Makes sure that when we have dual displays, with one or both shelves are set
1439 // to AutoHide, viewing the AppList on one of them doesn't unhide the other
1440 // hidden shelf.
1441 TEST_F(ShelfLayoutManagerTest, DualDisplayOpenAppListWithShelfAutoHideState) {
1442 if (!SupportsMultipleDisplays())
1443 return;
1445 // Create two displays.
1446 Shell* shell = Shell::GetInstance();
1447 DisplayManager* display_manager = shell->display_manager();
1448 EXPECT_EQ(1U, display_manager->GetNumDisplays());
1449 UpdateDisplay("0+0-200x200,+200+0-100x100");
1450 EXPECT_EQ(2U, display_manager->GetNumDisplays());
1452 DisplayController* display_controller = shell->display_controller();
1453 aura::Window::Windows root_windows = display_controller->GetAllRootWindows();
1454 EXPECT_EQ(root_windows.size(), 2U);
1456 // Get the shelves in both displays and set them to be 'AutoHide'.
1457 ShelfLayoutManager* shelf_1 =
1458 GetRootWindowController(root_windows[0])->GetShelfLayoutManager();
1459 ShelfLayoutManager* shelf_2 =
1460 GetRootWindowController(root_windows[1])->GetShelfLayoutManager();
1461 EXPECT_NE(shelf_1, shelf_2);
1462 EXPECT_NE(shelf_1->shelf_widget()->GetNativeWindow()->GetRootWindow(),
1463 shelf_2->shelf_widget()->GetNativeWindow()->
1464 GetRootWindow());
1465 shelf_1->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1466 shelf_1->LayoutShelf();
1467 shelf_2->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1468 shelf_2->LayoutShelf();
1470 // Create a window in each display and show them in maximized state.
1471 aura::Window* window_1 =
1472 CreateTestWindowInParent(root_windows[0]);
1473 window_1->SetBounds(gfx::Rect(0, 0, 100, 100));
1474 window_1->SetProperty(aura::client::kShowStateKey,
1475 ui::SHOW_STATE_MAXIMIZED);
1476 window_1->Show();
1477 aura::Window* window_2 =
1478 CreateTestWindowInParent(root_windows[1]);
1479 window_2->SetBounds(gfx::Rect(201, 0, 100, 100));
1480 window_2->SetProperty(aura::client::kShowStateKey,
1481 ui::SHOW_STATE_MAXIMIZED);
1482 window_2->Show();
1484 EXPECT_EQ(shelf_1->shelf_widget()->GetNativeWindow()->GetRootWindow(),
1485 window_1->GetRootWindow());
1486 EXPECT_EQ(shelf_2->shelf_widget()->GetNativeWindow()->GetRootWindow(),
1487 window_2->GetRootWindow());
1489 // Activate one window in one display and manually trigger the update of shelf
1490 // visibility.
1491 wm::ActivateWindow(window_1);
1492 shell->UpdateShelfVisibility();
1494 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1495 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->visibility_state());
1496 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->visibility_state());
1497 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_1->auto_hide_state());
1498 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->auto_hide_state());
1500 // Show app list.
1501 shell->ShowAppList(NULL);
1502 shell->UpdateShelfVisibility();
1504 // Only the shelf in the active display should be shown, the other is hidden.
1505 EXPECT_TRUE(shell->GetAppListTargetVisibility());
1506 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->visibility_state());
1507 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf_1->auto_hide_state());
1508 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->visibility_state());
1509 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->auto_hide_state());
1511 // Hide app list, both shelves should be hidden.
1512 shell->DismissAppList();
1513 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1514 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->visibility_state());
1515 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->visibility_state());
1516 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_1->auto_hide_state());
1517 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->auto_hide_state());
1520 // Makes sure the shelf will be hidden when we have a fullscreen window, and it
1521 // will unhide when we open the app list.
1522 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfHiddenState) {
1523 Shell* shell = Shell::GetInstance();
1524 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1525 // For shelf to be visible, app list is not open in initial state.
1526 shelf->LayoutShelf();
1528 // Create a window and make it full screen.
1529 aura::Window* window = CreateTestWindow();
1530 window->SetBounds(gfx::Rect(0, 0, 100, 100));
1531 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
1532 window->Show();
1533 wm::ActivateWindow(window);
1535 // App list and shelf is not shown.
1536 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1537 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
1539 // Show app list.
1540 shell->ShowAppList(NULL);
1541 EXPECT_TRUE(shell->GetAppListTargetVisibility());
1542 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1544 // Hide app list.
1545 shell->DismissAppList();
1546 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1547 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
1550 // Tests the correct behavior of the shelf when there is a system modal window
1551 // open when we have a single display.
1552 TEST_F(ShelfLayoutManagerTest, ShelfWithSystemModalWindowSingleDisplay) {
1553 Shell* shell = Shell::GetInstance();
1554 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1555 shelf->LayoutShelf();
1556 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1558 aura::Window* window = CreateTestWindow();
1559 window->SetBounds(gfx::Rect(0, 0, 100, 100));
1560 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1561 window->Show();
1562 wm::ActivateWindow(window);
1564 // Enable system modal dialog, and make sure shelf is still hidden.
1565 shell->SimulateModalWindowOpenForTesting(true);
1566 EXPECT_TRUE(shell->IsSystemModalWindowOpen());
1567 EXPECT_FALSE(wm::CanActivateWindow(window));
1568 shell->UpdateShelfVisibility();
1569 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1570 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1573 // Tests the correct behavior of the shelf when there is a system modal window
1574 // open when we have dual display.
1575 TEST_F(ShelfLayoutManagerTest, ShelfWithSystemModalWindowDualDisplay) {
1576 if (!SupportsMultipleDisplays())
1577 return;
1579 // Create two displays.
1580 Shell* shell = Shell::GetInstance();
1581 DisplayManager* display_manager = shell->display_manager();
1582 UpdateDisplay("200x200,100x100");
1583 EXPECT_EQ(2U, display_manager->GetNumDisplays());
1585 DisplayController* display_controller = shell->display_controller();
1586 aura::Window::Windows root_windows = display_controller->GetAllRootWindows();
1587 EXPECT_EQ(2U, root_windows.size());
1589 // Get the shelves in both displays and set them to be 'AutoHide'.
1590 ShelfLayoutManager* shelf_1 =
1591 GetRootWindowController(root_windows[0])->GetShelfLayoutManager();
1592 ShelfLayoutManager* shelf_2 =
1593 GetRootWindowController(root_windows[1])->GetShelfLayoutManager();
1594 EXPECT_NE(shelf_1, shelf_2);
1595 EXPECT_NE(shelf_1->shelf_widget()->GetNativeWindow()->GetRootWindow(),
1596 shelf_2->shelf_widget()->GetNativeWindow()->GetRootWindow());
1597 shelf_1->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1598 shelf_1->LayoutShelf();
1599 shelf_2->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1600 shelf_2->LayoutShelf();
1602 // Create a window in each display and show them in maximized state.
1603 aura::Window* window_1 = CreateTestWindowInParent(root_windows[0]);
1604 window_1->SetBounds(gfx::Rect(0, 0, 100, 100));
1605 window_1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1606 window_1->Show();
1607 aura::Window* window_2 = CreateTestWindowInParent(root_windows[1]);
1608 window_2->SetBounds(gfx::Rect(201, 0, 100, 100));
1609 window_2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1610 window_2->Show();
1612 EXPECT_EQ(shelf_1->shelf_widget()->GetNativeWindow()->GetRootWindow(),
1613 window_1->GetRootWindow());
1614 EXPECT_EQ(shelf_2->shelf_widget()->GetNativeWindow()->GetRootWindow(),
1615 window_2->GetRootWindow());
1616 EXPECT_TRUE(window_1->IsVisible());
1617 EXPECT_TRUE(window_2->IsVisible());
1619 // Enable system modal dialog, and make sure both shelves are still hidden.
1620 shell->SimulateModalWindowOpenForTesting(true);
1621 EXPECT_TRUE(shell->IsSystemModalWindowOpen());
1622 EXPECT_FALSE(wm::CanActivateWindow(window_1));
1623 EXPECT_FALSE(wm::CanActivateWindow(window_2));
1624 shell->UpdateShelfVisibility();
1625 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->visibility_state());
1626 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_1->auto_hide_state());
1627 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->visibility_state());
1628 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->auto_hide_state());
1631 // Tests that the shelf is only hidden for a fullscreen window at the front and
1632 // toggles visibility when another window is activated.
1633 TEST_F(ShelfLayoutManagerTest, FullscreenWindowInFrontHidesShelf) {
1634 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1636 // Create a window and make it full screen.
1637 aura::Window* window1 = CreateTestWindow();
1638 window1->SetBounds(gfx::Rect(0, 0, 100, 100));
1639 window1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
1640 window1->Show();
1642 aura::Window* window2 = CreateTestWindow();
1643 window2->SetBounds(gfx::Rect(0, 0, 100, 100));
1644 window2->Show();
1646 wm::GetWindowState(window1)->Activate();
1647 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
1649 wm::GetWindowState(window2)->Activate();
1650 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1652 wm::GetWindowState(window1)->Activate();
1653 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
1656 // Test the behavior of the shelf when a window on one display is fullscreen
1657 // but the other display has the active window.
1658 TEST_F(ShelfLayoutManagerTest, FullscreenWindowOnSecondDisplay) {
1659 if (!SupportsMultipleDisplays())
1660 return;
1662 UpdateDisplay("800x600,800x600");
1663 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
1664 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1665 Shell::RootWindowControllerList root_window_controllers =
1666 Shell::GetAllRootWindowControllers();
1668 // Create windows on either display.
1669 aura::Window* window1 = CreateTestWindow();
1670 window1->SetBoundsInScreen(
1671 gfx::Rect(0, 0, 100, 100),
1672 display_manager->GetDisplayAt(0));
1673 window1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
1674 window1->Show();
1676 aura::Window* window2 = CreateTestWindow();
1677 window2->SetBoundsInScreen(
1678 gfx::Rect(800, 0, 100, 100),
1679 display_manager->GetDisplayAt(1));
1680 window2->Show();
1682 EXPECT_EQ(root_windows[0], window1->GetRootWindow());
1683 EXPECT_EQ(root_windows[1], window2->GetRootWindow());
1685 wm::GetWindowState(window2)->Activate();
1686 EXPECT_EQ(SHELF_HIDDEN,
1687 root_window_controllers[0]->GetShelfLayoutManager()->visibility_state());
1688 EXPECT_EQ(SHELF_VISIBLE,
1689 root_window_controllers[1]->GetShelfLayoutManager()->visibility_state());
1693 #if defined(OS_WIN)
1694 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1695 #define MAYBE_SetAlignment DISABLED_SetAlignment
1696 #else
1697 #define MAYBE_SetAlignment SetAlignment
1698 #endif
1700 // Tests SHELF_ALIGNMENT_(LEFT, RIGHT, TOP).
1701 TEST_F(ShelfLayoutManagerTest, MAYBE_SetAlignment) {
1702 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1703 // Force an initial layout.
1704 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1705 shelf->LayoutShelf();
1706 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1708 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
1709 gfx::Rect shelf_bounds(
1710 GetShelfWidget()->GetWindowBoundsInScreen());
1711 const gfx::Screen* screen = Shell::GetScreen();
1712 gfx::Display display =
1713 screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1714 ASSERT_NE(-1, display.id());
1715 EXPECT_EQ(shelf->GetIdealBounds().width(),
1716 display.GetWorkAreaInsets().left());
1717 EXPECT_GE(
1718 shelf_bounds.width(),
1719 GetShelfWidget()->GetContentsView()->GetPreferredSize().width());
1720 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, GetSystemTray()->shelf_alignment());
1721 StatusAreaWidget* status_area_widget = GetShelfWidget()->status_area_widget();
1722 gfx::Rect status_bounds(status_area_widget->GetWindowBoundsInScreen());
1723 EXPECT_GE(status_bounds.width(),
1724 status_area_widget->GetContentsView()->GetPreferredSize().width());
1725 EXPECT_EQ(shelf->GetIdealBounds().width(),
1726 display.GetWorkAreaInsets().left());
1727 EXPECT_EQ(0, display.GetWorkAreaInsets().top());
1728 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
1729 EXPECT_EQ(0, display.GetWorkAreaInsets().right());
1730 EXPECT_EQ(display.bounds().x(), shelf_bounds.x());
1731 EXPECT_EQ(display.bounds().y(), shelf_bounds.y());
1732 EXPECT_EQ(display.bounds().height(), shelf_bounds.height());
1733 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1734 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1735 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
1736 display.GetWorkAreaInsets().left());
1737 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, display.work_area().x());
1739 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1740 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
1741 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1742 shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
1743 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1744 ASSERT_NE(-1, display.id());
1745 EXPECT_EQ(shelf->GetIdealBounds().width(),
1746 display.GetWorkAreaInsets().right());
1747 EXPECT_GE(shelf_bounds.width(),
1748 GetShelfWidget()->GetContentsView()->GetPreferredSize().width());
1749 EXPECT_EQ(SHELF_ALIGNMENT_RIGHT, GetSystemTray()->shelf_alignment());
1750 status_bounds = gfx::Rect(status_area_widget->GetWindowBoundsInScreen());
1751 EXPECT_GE(status_bounds.width(),
1752 status_area_widget->GetContentsView()->GetPreferredSize().width());
1753 EXPECT_EQ(shelf->GetIdealBounds().width(),
1754 display.GetWorkAreaInsets().right());
1755 EXPECT_EQ(0, display.GetWorkAreaInsets().top());
1756 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
1757 EXPECT_EQ(0, display.GetWorkAreaInsets().left());
1758 EXPECT_EQ(display.work_area().right(), shelf_bounds.x());
1759 EXPECT_EQ(display.bounds().y(), shelf_bounds.y());
1760 EXPECT_EQ(display.bounds().height(), shelf_bounds.height());
1761 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1762 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1763 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
1764 display.GetWorkAreaInsets().right());
1765 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
1766 display.bounds().right() - display.work_area().right());
1768 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1769 shelf->SetAlignment(SHELF_ALIGNMENT_TOP);
1770 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1771 shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
1772 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1773 ASSERT_NE(-1, display.id());
1774 EXPECT_EQ(shelf->GetIdealBounds().height(),
1775 display.GetWorkAreaInsets().top());
1776 EXPECT_GE(shelf_bounds.height(),
1777 GetShelfWidget()->GetContentsView()->GetPreferredSize().height());
1778 EXPECT_EQ(SHELF_ALIGNMENT_TOP, GetSystemTray()->shelf_alignment());
1779 status_bounds = gfx::Rect(status_area_widget->GetWindowBoundsInScreen());
1780 EXPECT_GE(status_bounds.height(),
1781 status_area_widget->GetContentsView()->GetPreferredSize().height());
1782 EXPECT_EQ(shelf->GetIdealBounds().height(),
1783 display.GetWorkAreaInsets().top());
1784 EXPECT_EQ(0, display.GetWorkAreaInsets().right());
1785 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
1786 EXPECT_EQ(0, display.GetWorkAreaInsets().left());
1787 EXPECT_EQ(display.work_area().y(), shelf_bounds.bottom());
1788 EXPECT_EQ(display.bounds().x(), shelf_bounds.x());
1789 EXPECT_EQ(display.bounds().width(), shelf_bounds.width());
1790 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1791 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1792 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
1793 display.GetWorkAreaInsets().top());
1794 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
1795 display.work_area().y() - display.bounds().y());
1798 TEST_F(ShelfLayoutManagerTest, GestureEdgeSwipe) {
1799 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1800 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1801 views::Widget* widget = new views::Widget;
1802 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1803 params.bounds = gfx::Rect(0, 0, 200, 200);
1804 params.context = CurrentContext();
1805 widget->Init(params);
1806 widget->Show();
1807 widget->Maximize();
1809 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1811 aura::Window* window = widget->GetNativeWindow();
1812 shelf->LayoutShelf();
1814 gfx::Rect shelf_shown = GetShelfWidget()->GetWindowBoundsInScreen();
1815 gfx::Rect bounds_shelf = window->bounds();
1817 // Edge swipe when SHELF_VISIBLE should not change visibility state.
1818 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1819 generator.GestureEdgeSwipe();
1820 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1822 // Edge swipe when AUTO_HIDE_HIDDEN should change to AUTO_HIDE_SHOWN.
1823 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1824 shelf->LayoutShelf();
1825 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1826 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1827 generator.GestureEdgeSwipe();
1828 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1829 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1831 widget->SetFullscreen(true);
1832 wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(false);
1833 shelf->UpdateVisibilityState();
1835 // Edge swipe in fullscreen + AUTO_HIDE_HIDDEN should show the shelf and
1836 // remain fullscreen.
1837 EXPECT_TRUE(widget->IsFullscreen());
1838 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1839 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1840 generator.GestureEdgeSwipe();
1841 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1842 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1843 EXPECT_TRUE(widget->IsFullscreen());
1846 // Tests that gesture edge swipe events are forwarded to the right shelf on the
1847 // right monitor (crbug.com/449851).
1848 TEST_F(ShelfLayoutManagerTest, GestureEdgeSwipeMultiMonitor) {
1849 if (!SupportsMultipleDisplays())
1850 return;
1852 // Create two displays.
1853 Shell* shell = Shell::GetInstance();
1854 DisplayManager* display_manager = shell->display_manager();
1855 UpdateDisplay("200x200,100x100");
1856 ASSERT_EQ(2U, display_manager->GetNumDisplays());
1858 auto root_window_controllers = Shell::GetAllRootWindowControllers();
1859 ASSERT_EQ(2U, root_window_controllers.size());
1860 ShelfLayoutManager* shelf_1 =
1861 root_window_controllers[0]->GetShelfLayoutManager();
1862 ShelfLayoutManager* shelf_2 =
1863 root_window_controllers[1]->GetShelfLayoutManager();
1865 // Create two maximized windows, one in each display.
1866 aura::Window* window_1 =
1867 CreateTestWindowInParent(root_window_controllers[0]->GetRootWindow());
1868 window_1->SetBounds(gfx::Rect(0, 0, 100, 100));
1869 window_1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1870 window_1->Show();
1871 aura::Window* window_2 =
1872 CreateTestWindowInParent(root_window_controllers[1]->GetRootWindow());
1873 window_2->SetBounds(gfx::Rect(201, 0, 100, 100));
1874 window_2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1875 window_2->Show();
1877 // Make sure both are set to auto-hide and both are hidden.
1878 shelf_1->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1879 shelf_2->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1880 shelf_1->LayoutShelf();
1881 shelf_2->LayoutShelf();
1882 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->visibility_state());
1883 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->visibility_state());
1884 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_1->auto_hide_state());
1885 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->auto_hide_state());
1887 ui::test::EventGenerator monitor_1_generator(
1888 root_window_controllers[0]->GetRootWindow());
1889 ui::test::EventGenerator monitor_2_generator(
1890 root_window_controllers[1]->GetRootWindow());
1892 // An edge swipe in one display should only affect the shelf in that display.
1893 monitor_1_generator.GestureEdgeSwipe();
1894 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->visibility_state());
1895 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->visibility_state());
1896 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf_1->auto_hide_state());
1897 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->auto_hide_state());
1899 // Back to normal after an update.
1900 shell->UpdateShelfVisibility();
1901 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->visibility_state());
1902 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->visibility_state());
1903 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_1->auto_hide_state());
1904 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->auto_hide_state());
1906 monitor_2_generator.GestureEdgeSwipe();
1907 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->visibility_state());
1908 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->visibility_state());
1909 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_1->auto_hide_state());
1910 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf_2->auto_hide_state());
1913 #if defined(OS_WIN)
1914 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1915 #define MAYBE_GestureDrag DISABLED_GestureDrag
1916 #else
1917 #define MAYBE_GestureDrag GestureDrag
1918 #endif
1920 TEST_F(ShelfLayoutManagerTest, MAYBE_GestureDrag) {
1921 // Slop is an implementation detail of gesture recognition, and complicates
1922 // these tests. Ignore it.
1923 ui::GestureConfiguration::GetInstance()
1924 ->set_max_touch_move_in_pixels_for_click(0);
1925 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1927 SCOPED_TRACE("BOTTOM");
1928 RunGestureDragTests(gfx::Vector2d(0, 120));
1932 SCOPED_TRACE("LEFT");
1933 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
1934 RunGestureDragTests(gfx::Vector2d(-120, 0));
1938 SCOPED_TRACE("RIGHT");
1939 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
1940 RunGestureDragTests(gfx::Vector2d(120, 0));
1944 TEST_F(ShelfLayoutManagerTest, WindowVisibilityDisablesAutoHide) {
1945 if (!SupportsMultipleDisplays())
1946 return;
1948 UpdateDisplay("800x600,800x600");
1949 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1950 shelf->LayoutShelf();
1951 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1953 // Create a visible window so auto-hide behavior is enforced
1954 views::Widget* dummy = CreateTestWidget();
1956 // Window visible => auto hide behaves normally.
1957 shelf->UpdateVisibilityState();
1958 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1960 // Window minimized => auto hide disabled.
1961 dummy->Minimize();
1962 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1964 // Window closed => auto hide disabled.
1965 dummy->CloseNow();
1966 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1968 // Multiple window test
1969 views::Widget* window1 = CreateTestWidget();
1970 views::Widget* window2 = CreateTestWidget();
1972 // both visible => normal autohide
1973 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1975 // either minimzed => normal autohide
1976 window2->Minimize();
1977 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1978 window2->Restore();
1979 window1->Minimize();
1980 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1982 // both minimized => disable auto hide
1983 window2->Minimize();
1984 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1986 // Test moving windows to/from other display.
1987 window2->Restore();
1988 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1989 // Move to second display.
1990 window2->SetBounds(gfx::Rect(850, 50, 50, 50));
1991 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1992 // Move back to primary display.
1993 window2->SetBounds(gfx::Rect(50, 50, 50, 50));
1994 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1997 // Test that the shelf animates back to its normal position upon a user
1998 // completing a gesture drag.
1999 TEST_F(ShelfLayoutManagerTest, ShelfAnimatesWhenGestureComplete) {
2000 if (!SupportsHostWindowResize())
2001 return;
2003 // Test the shelf animates back to its original visible bounds when it is
2004 // dragged when there are no visible windows.
2005 ShelfLayoutManager* shelf = GetShelfLayoutManager();
2006 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
2007 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
2008 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
2009 gfx::Rect visible_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
2011 // Enable animations so that we can make sure that they occur.
2012 ui::ScopedAnimationDurationScaleMode regular_animations(
2013 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
2015 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
2016 gfx::Rect shelf_bounds_in_screen =
2017 GetShelfWidget()->GetWindowBoundsInScreen();
2018 gfx::Point start(shelf_bounds_in_screen.CenterPoint());
2019 gfx::Point end(start.x(), shelf_bounds_in_screen.bottom());
2020 generator.GestureScrollSequence(start, end,
2021 base::TimeDelta::FromMilliseconds(10), 5);
2022 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
2023 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
2025 ShelfAnimationWaiter waiter(visible_bounds);
2026 // Wait till the animation completes and check that it occurred.
2027 waiter.WaitTillDoneAnimating();
2028 EXPECT_TRUE(waiter.WasValidAnimation());
2031 // Create a visible window so auto-hide behavior is enforced.
2032 CreateTestWidget();
2034 // Get the bounds of the shelf when it is hidden.
2035 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
2036 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
2037 gfx::Rect auto_hidden_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
2040 // Enable the animations so that we can make sure they do occur.
2041 ui::ScopedAnimationDurationScaleMode regular_animations(
2042 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
2044 gfx::Point start =
2045 GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint();
2046 gfx::Point end(start.x(), start.y() - 100);
2047 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
2049 // Test that the shelf animates to the visible bounds after a swipe up on
2050 // the auto hidden shelf.
2051 generator.GestureScrollSequence(start, end,
2052 base::TimeDelta::FromMilliseconds(10), 1);
2053 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
2054 ShelfAnimationWaiter waiter1(visible_bounds);
2055 waiter1.WaitTillDoneAnimating();
2056 EXPECT_TRUE(waiter1.WasValidAnimation());
2058 // Test that the shelf animates to the auto hidden bounds after a swipe up
2059 // on the visible shelf.
2060 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
2061 generator.GestureScrollSequence(start, end,
2062 base::TimeDelta::FromMilliseconds(10), 1);
2063 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
2064 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
2065 ShelfAnimationWaiter waiter2(auto_hidden_bounds);
2066 waiter2.WaitTillDoneAnimating();
2067 EXPECT_TRUE(waiter2.WasValidAnimation());
2071 TEST_F(ShelfLayoutManagerTest, ShelfFlickerOnTrayActivation) {
2072 ShelfLayoutManager* shelf = GetShelfLayoutManager();
2074 // Create a visible window so auto-hide behavior is enforced.
2075 CreateTestWidget();
2077 // Turn on auto-hide for the shelf.
2078 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
2079 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
2080 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
2082 // Show the status menu. That should make the shelf visible again.
2083 Shell::GetInstance()->accelerator_controller()->PerformActionIfEnabled(
2084 SHOW_SYSTEM_TRAY_BUBBLE);
2085 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
2086 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
2087 EXPECT_TRUE(GetSystemTray()->HasSystemBubble());
2090 TEST_F(ShelfLayoutManagerTest, WorkAreaChangeWorkspace) {
2091 // Make sure the shelf is always visible.
2092 ShelfLayoutManager* shelf = GetShelfLayoutManager();
2093 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
2094 shelf->LayoutShelf();
2096 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
2097 params.bounds = gfx::Rect(0, 0, 200, 200);
2098 params.context = CurrentContext();
2099 views::Widget* widget_one = CreateTestWidgetWithParams(params);
2100 widget_one->Maximize();
2102 views::Widget* widget_two = CreateTestWidgetWithParams(params);
2103 widget_two->Maximize();
2104 widget_two->Activate();
2106 // Both windows are maximized. They should be of the same size.
2107 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
2108 widget_two->GetNativeWindow()->bounds().ToString());
2109 int area_when_shelf_shown =
2110 widget_one->GetNativeWindow()->bounds().size().GetArea();
2112 // Now hide the shelf.
2113 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
2115 // Both windows should be resized according to the shelf status.
2116 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
2117 widget_two->GetNativeWindow()->bounds().ToString());
2118 // Resized to small.
2119 EXPECT_LT(area_when_shelf_shown,
2120 widget_one->GetNativeWindow()->bounds().size().GetArea());
2122 // Now show the shelf.
2123 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
2125 // Again both windows should be of the same size.
2126 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
2127 widget_two->GetNativeWindow()->bounds().ToString());
2128 EXPECT_EQ(area_when_shelf_shown,
2129 widget_one->GetNativeWindow()->bounds().size().GetArea());
2132 // Confirm that the shelf is dimmed only when content is maximized and
2133 // shelf is not autohidden.
2134 TEST_F(ShelfLayoutManagerTest, Dimming) {
2135 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
2136 scoped_ptr<aura::Window> w1(CreateTestWindow());
2137 w1->Show();
2138 wm::ActivateWindow(w1.get());
2140 // Normal window doesn't dim shelf.
2141 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
2142 ShelfWidget* shelf = GetShelfWidget();
2143 EXPECT_FALSE(shelf->GetDimsShelf());
2145 // Maximized window does.
2146 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
2147 EXPECT_TRUE(shelf->GetDimsShelf());
2149 // Change back to normal stops dimming.
2150 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
2151 EXPECT_FALSE(shelf->GetDimsShelf());
2153 // Changing back to maximized dims again.
2154 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
2155 EXPECT_TRUE(shelf->GetDimsShelf());
2157 // Changing shelf to autohide stops dimming.
2158 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
2159 EXPECT_FALSE(shelf->GetDimsShelf());
2162 // Make sure that the shelf will not hide if the mouse is between a bubble and
2163 // the shelf.
2164 TEST_F(ShelfLayoutManagerTest, BubbleEnlargesShelfMouseHitArea) {
2165 ShelfLayoutManager* shelf = GetShelfLayoutManager();
2166 StatusAreaWidget* status_area_widget =
2167 Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
2168 SystemTray* tray = GetSystemTray();
2170 // Create a visible window so auto-hide behavior is enforced.
2171 CreateTestWidget();
2173 shelf->LayoutShelf();
2174 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
2176 // Make two iterations - first without a message bubble which should make
2177 // the shelf disappear and then with a message bubble which should keep it
2178 // visible.
2179 for (int i = 0; i < 2; i++) {
2180 // Make sure the shelf is visible and position the mouse over it. Then
2181 // allow auto hide.
2182 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
2183 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
2184 gfx::Point center =
2185 status_area_widget->GetWindowBoundsInScreen().CenterPoint();
2186 generator.MoveMouseTo(center.x(), center.y());
2187 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
2188 EXPECT_TRUE(shelf->IsVisible());
2189 if (!i) {
2190 // In our first iteration we make sure there is no bubble.
2191 tray->CloseSystemBubble();
2192 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
2193 } else {
2194 // In our second iteration we show a bubble.
2195 TestItem *item = new TestItem;
2196 tray->AddTrayItem(item);
2197 tray->ShowNotificationView(item);
2198 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
2200 // Move the pointer over the edge of the shelf.
2201 generator.MoveMouseTo(
2202 center.x(), status_area_widget->GetWindowBoundsInScreen().y() - 8);
2203 shelf->UpdateVisibilityState();
2204 if (i) {
2205 EXPECT_TRUE(shelf->IsVisible());
2206 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
2207 } else {
2208 EXPECT_FALSE(shelf->IsVisible());
2209 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
2214 TEST_F(ShelfLayoutManagerTest, ShelfBackgroundColor) {
2215 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
2217 scoped_ptr<aura::Window> w1(CreateTestWindow());
2218 w1->Show();
2219 wm::ActivateWindow(w1.get());
2220 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
2221 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
2222 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType());
2224 scoped_ptr<aura::Window> w2(CreateTestWindow());
2225 w2->Show();
2226 wm::ActivateWindow(w2.get());
2227 // Overlaps with shelf.
2228 w2->SetBounds(GetShelfLayoutManager()->GetIdealBounds());
2230 // Still background is 'maximized'.
2231 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType());
2233 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
2234 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType());
2235 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
2236 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
2238 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
2239 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType());
2240 w1.reset();
2241 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
2244 // Verify that the shelf doesn't have the opaque background if it's auto-hide
2245 // status.
2246 TEST_F(ShelfLayoutManagerTest, ShelfBackgroundColorAutoHide) {
2247 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget ()->GetBackgroundType());
2249 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
2250 scoped_ptr<aura::Window> w1(CreateTestWindow());
2251 w1->Show();
2252 wm::ActivateWindow(w1.get());
2253 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType());
2254 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
2255 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType());
2258 #if defined(OS_CHROMEOS)
2259 #define MAYBE_StatusAreaHitBoxCoversEdge StatusAreaHitBoxCoversEdge
2260 #else
2261 #define MAYBE_StatusAreaHitBoxCoversEdge DISABLED_StatusAreaHitBoxCoversEdge
2262 #endif
2264 // Verify the hit bounds of the status area extend to the edge of the shelf.
2265 TEST_F(ShelfLayoutManagerTest, MAYBE_StatusAreaHitBoxCoversEdge) {
2266 UpdateDisplay("400x400");
2267 ShelfLayoutManager* shelf = GetShelfLayoutManager();
2268 StatusAreaWidget* status_area_widget =
2269 Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
2270 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
2271 generator.MoveMouseTo(399,399);
2273 // Test bottom right pixel for bottom alignment.
2274 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
2275 generator.ClickLeftButton();
2276 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
2277 generator.ClickLeftButton();
2278 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
2280 // Test bottom right pixel for right alignment.
2281 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
2282 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
2283 generator.ClickLeftButton();
2284 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
2285 generator.ClickLeftButton();
2286 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
2288 // Test bottom left pixel for left alignment.
2289 generator.MoveMouseTo(0, 399);
2290 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
2291 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
2292 generator.ClickLeftButton();
2293 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
2294 generator.ClickLeftButton();
2295 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
2298 // Tests that when the auto-hide behaviour is changed during an animation the
2299 // target bounds are updated to reflect the new state.
2300 TEST_F(ShelfLayoutManagerTest,
2301 ShelfAutoHideToggleDuringAnimationUpdatesBounds) {
2302 ShelfLayoutManager* shelf_manager = GetShelfLayoutManager();
2303 aura::Window* status_window = GetShelfWidget()->status_area_widget()->
2304 GetNativeView();
2305 gfx::Rect initial_bounds = status_window->bounds();
2307 ui::ScopedAnimationDurationScaleMode regular_animations(
2308 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
2309 shelf_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
2310 gfx::Rect hide_target_bounds = status_window->GetTargetBounds();
2311 EXPECT_GT(hide_target_bounds.y(), initial_bounds.y());
2313 shelf_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
2314 gfx::Rect reshow_target_bounds = status_window->GetTargetBounds();
2315 EXPECT_EQ(initial_bounds, reshow_target_bounds);
2318 // Tests that during shutdown, that window activation changes are properly
2319 // handled, and do not crash (crbug.com/458768)
2320 TEST_F(ShelfLayoutManagerTest, ShutdownHandlesWindowActivation) {
2321 ShelfLayoutManager* shelf_manager = GetShelfLayoutManager();
2322 ShelfWidget* shelf = GetShelfWidget();
2323 shelf_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
2325 aura::Window* window1 = CreateTestWindowInShellWithId(0);
2326 window1->SetBounds(gfx::Rect(0, 0, 100, 100));
2327 window1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
2328 window1->Show();
2329 scoped_ptr<aura::Window> window2(CreateTestWindowInShellWithId(0));
2330 window2->SetBounds(gfx::Rect(0, 0, 100, 100));
2331 window2->Show();
2332 wm::ActivateWindow(window1);
2334 shelf->ShutdownStatusAreaWidget();
2335 shelf_manager->PrepareForShutdown();
2337 // Deleting a focused maximized window will switch focus to |window2|. This
2338 // would normally cause the ShelfLayoutManager to update its state. However
2339 // during shutdown we want to handle this without crashing.
2340 delete window1;
2343 TEST_F(ShelfLayoutManagerTest, ShelfLayoutInUnifiedDesktop) {
2344 if (!SupportsMultipleDisplays())
2345 return;
2346 test::DisplayManagerTestApi::EnableUnifiedDesktopForTest();
2348 UpdateDisplay("500x500, 500x500");
2350 StatusAreaWidget* status_area_widget =
2351 Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
2352 EXPECT_TRUE(status_area_widget->IsVisible());
2353 // Shelf should be in the first display's area.
2354 EXPECT_EQ("348,453 152x47",
2355 status_area_widget->GetWindowBoundsInScreen().ToString());
2358 } // namespace ash