1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/shelf/shelf_layout_manager.h"
7 #include "ash/accelerators/accelerator_controller.h"
8 #include "ash/accelerators/accelerator_table.h"
9 #include "ash/ash_switches.h"
10 #include "ash/display/display_manager.h"
11 #include "ash/focus_cycler.h"
12 #include "ash/root_window_controller.h"
13 #include "ash/session_state_delegate.h"
14 #include "ash/shelf/shelf.h"
15 #include "ash/shelf/shelf_layout_manager_observer.h"
16 #include "ash/shelf/shelf_view.h"
17 #include "ash/shelf/shelf_widget.h"
18 #include "ash/shell.h"
19 #include "ash/shell_window_ids.h"
20 #include "ash/system/status_area_widget.h"
21 #include "ash/system/tray/system_tray.h"
22 #include "ash/system/tray/system_tray_item.h"
23 #include "ash/test/ash_test_base.h"
24 #include "ash/test/shelf_test_api.h"
25 #include "ash/wm/window_state.h"
26 #include "ash/wm/window_util.h"
27 #include "base/command_line.h"
28 #include "base/strings/utf_string_conversions.h"
29 #include "ui/aura/client/aura_constants.h"
30 #include "ui/aura/root_window.h"
31 #include "ui/aura/test/event_generator.h"
32 #include "ui/aura/window.h"
33 #include "ui/compositor/layer.h"
34 #include "ui/compositor/layer_animator.h"
35 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
36 #include "ui/events/gestures/gesture_configuration.h"
37 #include "ui/gfx/animation/animation_container_element.h"
38 #include "ui/gfx/display.h"
39 #include "ui/gfx/screen.h"
40 #include "ui/views/controls/label.h"
41 #include "ui/views/layout/fill_layout.h"
42 #include "ui/views/view.h"
43 #include "ui/views/widget/widget.h"
46 #include "base/win/windows_version.h"
54 void StepWidgetLayerAnimatorToEnd(views::Widget* widget) {
55 gfx::AnimationContainerElement* element =
56 static_cast<gfx::AnimationContainerElement*>(
57 widget->GetNativeView()->layer()->GetAnimator());
58 element->Step(base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1));
61 ShelfWidget* GetShelfWidget() {
62 return Shell::GetPrimaryRootWindowController()->shelf();
65 ShelfLayoutManager* GetShelfLayoutManager() {
66 return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
69 SystemTray* GetSystemTray() {
70 return Shell::GetPrimaryRootWindowController()->GetSystemTray();
73 // Class which waits till the shelf finishes animating to the target size and
74 // counts the number of animation steps.
75 class ShelfAnimationWaiter : views::WidgetObserver {
77 explicit ShelfAnimationWaiter(const gfx::Rect& target_bounds)
78 : target_bounds_(target_bounds),
80 done_waiting_(false) {
81 GetShelfWidget()->AddObserver(this);
84 virtual ~ShelfAnimationWaiter() {
85 GetShelfWidget()->RemoveObserver(this);
88 // Wait till the shelf finishes animating to its expected bounds.
89 void WaitTillDoneAnimating() {
90 if (IsDoneAnimating())
93 base::MessageLoop::current()->Run();
96 // Returns true if the animation has completed and it was valid.
97 bool WasValidAnimation() const {
98 return done_waiting_ && animation_steps_ > 0;
102 // Returns true if shelf has finished animating to the target size.
103 bool IsDoneAnimating() const {
104 ShelfLayoutManager* layout_manager = GetShelfLayoutManager();
105 gfx::Rect current_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
106 int size = layout_manager->PrimaryAxisValue(current_bounds.height(),
107 current_bounds.width());
108 int desired_size = layout_manager->PrimaryAxisValue(target_bounds_.height(),
109 target_bounds_.width());
110 return (size == desired_size);
113 // views::WidgetObserver override.
114 virtual void OnWidgetBoundsChanged(views::Widget* widget,
115 const gfx::Rect& new_bounds) OVERRIDE {
120 if (IsDoneAnimating()) {
121 done_waiting_ = true;
122 base::MessageLoop::current()->Quit();
126 gfx::Rect target_bounds_;
127 int animation_steps_;
130 DISALLOW_COPY_AND_ASSIGN(ShelfAnimationWaiter);
133 class ShelfDragCallback {
135 ShelfDragCallback(const gfx::Rect& not_visible, const gfx::Rect& visible)
136 : not_visible_bounds_(not_visible),
137 visible_bounds_(visible),
138 was_visible_on_drag_start_(false) {
139 EXPECT_EQ(not_visible_bounds_.bottom(), visible_bounds_.bottom());
142 virtual ~ShelfDragCallback() {
145 void ProcessScroll(ui::EventType type, const gfx::Vector2dF& delta) {
146 if (GetShelfLayoutManager()->visibility_state() == ash::SHELF_HIDDEN)
149 if (type == ui::ET_GESTURE_SCROLL_BEGIN) {
150 scroll_ = gfx::Vector2dF();
151 was_visible_on_drag_start_ = GetShelfLayoutManager()->IsVisible();
155 // The state of the shelf at the end of the gesture is tested separately.
156 if (type == ui::ET_GESTURE_SCROLL_END)
159 if (type == ui::ET_GESTURE_SCROLL_UPDATE)
162 gfx::Rect shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
163 if (GetShelfLayoutManager()->IsHorizontalAlignment()) {
164 EXPECT_EQ(not_visible_bounds_.bottom(), shelf_bounds.bottom());
165 EXPECT_EQ(visible_bounds_.bottom(), shelf_bounds.bottom());
166 } else if (SHELF_ALIGNMENT_RIGHT ==
167 GetShelfLayoutManager()->GetAlignment()){
168 EXPECT_EQ(not_visible_bounds_.right(), shelf_bounds.right());
169 EXPECT_EQ(visible_bounds_.right(), shelf_bounds.right());
170 } else if (SHELF_ALIGNMENT_LEFT ==
171 GetShelfLayoutManager()->GetAlignment()) {
172 EXPECT_EQ(not_visible_bounds_.x(), shelf_bounds.x());
173 EXPECT_EQ(visible_bounds_.x(), shelf_bounds.x());
176 // if the shelf is being dimmed test dimmer bounds as well.
177 if (GetShelfWidget()->GetDimsShelf())
178 EXPECT_EQ(GetShelfWidget()->GetWindowBoundsInScreen(),
179 GetShelfWidget()->GetDimmerBoundsForTest());
181 // The shelf should never be smaller than the hidden state.
182 EXPECT_GE(shelf_bounds.height(), not_visible_bounds_.height());
183 float scroll_delta = GetShelfLayoutManager()->PrimaryAxisValue(
186 bool increasing_drag =
187 GetShelfLayoutManager()->SelectValueForShelfAlignment(
192 int shelf_size = GetShelfLayoutManager()->PrimaryAxisValue(
193 shelf_bounds.height(),
194 shelf_bounds.width());
195 int visible_bounds_size = GetShelfLayoutManager()->PrimaryAxisValue(
196 visible_bounds_.height(),
197 visible_bounds_.width());
198 int not_visible_bounds_size = GetShelfLayoutManager()->PrimaryAxisValue(
199 not_visible_bounds_.height(),
200 not_visible_bounds_.width());
201 if (was_visible_on_drag_start_) {
202 if (increasing_drag) {
203 // If dragging inwards from the visible state, then the shelf should
204 // increase in size, but not more than the scroll delta.
205 EXPECT_LE(visible_bounds_size, shelf_size);
206 EXPECT_LE(abs(shelf_size - visible_bounds_size),
209 if (shelf_size > not_visible_bounds_size) {
210 // If dragging outwards from the visible state, then the shelf
211 // should decrease in size, until it reaches the minimum size.
212 EXPECT_EQ(shelf_size, visible_bounds_size - abs(scroll_delta));
216 if (fabs(scroll_delta) <
217 visible_bounds_size - not_visible_bounds_size) {
218 // Tests that the shelf sticks with the touch point during the drag
219 // until the shelf is completely visible.
220 EXPECT_EQ(shelf_size, not_visible_bounds_size + abs(scroll_delta));
222 // Tests that after the shelf is completely visible, the shelf starts
223 // resisting the drag.
224 EXPECT_LT(shelf_size, not_visible_bounds_size + abs(scroll_delta));
230 const gfx::Rect not_visible_bounds_;
231 const gfx::Rect visible_bounds_;
232 gfx::Vector2dF scroll_;
233 bool was_visible_on_drag_start_;
235 DISALLOW_COPY_AND_ASSIGN(ShelfDragCallback);
238 class ShelfLayoutObserverTest : public ShelfLayoutManagerObserver {
240 ShelfLayoutObserverTest()
241 : changed_auto_hide_state_(false) {
244 virtual ~ShelfLayoutObserverTest() {}
246 bool changed_auto_hide_state() const { return changed_auto_hide_state_; }
249 virtual void OnAutoHideStateChanged(
250 ShelfAutoHideState new_state) OVERRIDE {
251 changed_auto_hide_state_ = true;
254 bool changed_auto_hide_state_;
256 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutObserverTest);
259 // Trivial item implementation that tracks its views for testing.
260 class TestItem : public SystemTrayItem {
263 : SystemTrayItem(GetSystemTray()),
266 detailed_view_(NULL),
267 notification_view_(NULL) {}
269 virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE {
270 tray_view_ = new views::View;
271 // Add a label so it has non-zero width.
272 tray_view_->SetLayoutManager(new views::FillLayout);
273 tray_view_->AddChildView(new views::Label(base::UTF8ToUTF16("Tray")));
277 virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE {
278 default_view_ = new views::View;
279 default_view_->SetLayoutManager(new views::FillLayout);
280 default_view_->AddChildView(new views::Label(base::UTF8ToUTF16("Default")));
281 return default_view_;
284 virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE {
285 detailed_view_ = new views::View;
286 detailed_view_->SetLayoutManager(new views::FillLayout);
287 detailed_view_->AddChildView(
288 new views::Label(base::UTF8ToUTF16("Detailed")));
289 return detailed_view_;
292 virtual views::View* CreateNotificationView(
293 user::LoginStatus status) OVERRIDE {
294 notification_view_ = new views::View;
295 return notification_view_;
298 virtual void DestroyTrayView() OVERRIDE {
302 virtual void DestroyDefaultView() OVERRIDE {
303 default_view_ = NULL;
306 virtual void DestroyDetailedView() OVERRIDE {
307 detailed_view_ = NULL;
310 virtual void DestroyNotificationView() OVERRIDE {
311 notification_view_ = NULL;
314 virtual void UpdateAfterLoginStatusChange(
315 user::LoginStatus status) OVERRIDE {}
317 views::View* tray_view() const { return tray_view_; }
318 views::View* default_view() const { return default_view_; }
319 views::View* detailed_view() const { return detailed_view_; }
320 views::View* notification_view() const { return notification_view_; }
323 views::View* tray_view_;
324 views::View* default_view_;
325 views::View* detailed_view_;
326 views::View* notification_view_;
328 DISALLOW_COPY_AND_ASSIGN(TestItem);
333 class ShelfLayoutManagerTest : public ash::test::AshTestBase {
335 ShelfLayoutManagerTest() {}
337 void SetState(ShelfLayoutManager* shelf,
338 ShelfVisibilityState state) {
339 shelf->SetState(state);
342 void UpdateAutoHideStateNow() {
343 GetShelfLayoutManager()->UpdateAutoHideStateNow();
346 aura::Window* CreateTestWindow() {
347 aura::Window* window = new aura::Window(NULL);
348 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
349 window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
350 window->Init(aura::WINDOW_LAYER_TEXTURED);
351 ParentWindowInPrimaryRootWindow(window);
355 views::Widget* CreateTestWidgetWithParams(
356 const views::Widget::InitParams& params) {
357 views::Widget* out = new views::Widget;
363 // Create a simple widget attached to the current context (will
364 // delete on TearDown).
365 views::Widget* CreateTestWidget() {
366 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
367 params.bounds = gfx::Rect(0, 0, 200, 200);
368 params.context = CurrentContext();
369 return CreateTestWidgetWithParams(params);
372 // Overridden from AshTestBase:
373 virtual void SetUp() OVERRIDE {
374 CommandLine::ForCurrentProcess()->AppendSwitch(
375 ash::switches::kAshEnableTrayDragging);
376 test::AshTestBase::SetUp();
379 void RunGestureDragTests(gfx::Vector2d);
382 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerTest);
385 void ShelfLayoutManagerTest::RunGestureDragTests(gfx::Vector2d delta) {
386 ShelfLayoutManager* shelf = GetShelfLayoutManager();
387 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
388 views::Widget* widget = new views::Widget;
389 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
390 params.bounds = gfx::Rect(0, 0, 200, 200);
391 params.context = CurrentContext();
392 widget->Init(params);
396 aura::Window* window = widget->GetNativeWindow();
397 shelf->LayoutShelf();
399 gfx::Rect shelf_shown = GetShelfWidget()->GetWindowBoundsInScreen();
400 gfx::Rect bounds_shelf = window->bounds();
401 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
403 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
404 shelf->LayoutShelf();
405 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
407 gfx::Rect bounds_noshelf = window->bounds();
408 gfx::Rect shelf_hidden = GetShelfWidget()->GetWindowBoundsInScreen();
410 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
411 shelf->LayoutShelf();
413 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
414 const int kNumScrollSteps = 4;
415 ShelfDragCallback handler(shelf_hidden, shelf_shown);
417 // Swipe up on the shelf. This should not change any state.
418 gfx::Point start = GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint();
419 gfx::Point end = start + delta;
421 // Swipe down on the shelf to hide it.
422 generator.GestureScrollSequenceWithCallback(start, end,
423 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
424 base::Bind(&ShelfDragCallback::ProcessScroll,
425 base::Unretained(&handler)));
426 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
427 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
428 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
429 EXPECT_NE(bounds_shelf.ToString(), window->bounds().ToString());
430 EXPECT_NE(shelf_shown.ToString(),
431 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
433 // Swipe up to show the shelf.
434 generator.GestureScrollSequenceWithCallback(end, start,
435 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
436 base::Bind(&ShelfDragCallback::ProcessScroll,
437 base::Unretained(&handler)));
438 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
439 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
440 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
441 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
442 GetShelfWidget()->GetWindowBoundsInScreen());
443 EXPECT_EQ(shelf_shown.ToString(),
444 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
446 // Swipe up again. The shelf should hide.
448 generator.GestureScrollSequenceWithCallback(start, end,
449 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
450 base::Bind(&ShelfDragCallback::ProcessScroll,
451 base::Unretained(&handler)));
452 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
453 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
454 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
455 EXPECT_EQ(shelf_hidden.ToString(),
456 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
458 // Swipe up yet again to show it.
460 generator.GestureScrollSequenceWithCallback(end, start,
461 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
462 base::Bind(&ShelfDragCallback::ProcessScroll,
463 base::Unretained(&handler)));
465 // Swipe down very little. It shouldn't change any state.
466 if (GetShelfLayoutManager()->IsHorizontalAlignment())
467 end.set_y(start.y() + shelf_shown.height() * 3 / 10);
468 else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment())
469 end.set_x(start.x() - shelf_shown.width() * 3 / 10);
470 else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment())
471 end.set_x(start.x() + shelf_shown.width() * 3 / 10);
472 generator.GestureScrollSequence(start, end,
473 base::TimeDelta::FromMilliseconds(10), 5);
474 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
475 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
476 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
477 EXPECT_EQ(shelf_shown.ToString(),
478 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
480 // Swipe down again to hide.
482 generator.GestureScrollSequenceWithCallback(start, end,
483 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
484 base::Bind(&ShelfDragCallback::ProcessScroll,
485 base::Unretained(&handler)));
486 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
487 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
488 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
489 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
490 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
491 EXPECT_EQ(shelf_hidden.ToString(),
492 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
494 // Swipe up in extended hit region to show it.
495 gfx::Point extended_start = start;
496 if (GetShelfLayoutManager()->IsHorizontalAlignment())
497 extended_start.set_y(GetShelfWidget()->GetWindowBoundsInScreen().y() -1);
498 else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment())
499 extended_start.set_x(
500 GetShelfWidget()->GetWindowBoundsInScreen().right() + 1);
501 else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment())
502 extended_start.set_x(GetShelfWidget()->GetWindowBoundsInScreen().x() - 1);
503 end = extended_start - delta;
504 generator.GestureScrollSequenceWithCallback(extended_start, end,
505 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
506 base::Bind(&ShelfDragCallback::ProcessScroll,
507 base::Unretained(&handler)));
508 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
509 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
510 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
511 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
512 GetShelfWidget()->GetWindowBoundsInScreen());
513 EXPECT_EQ(shelf_shown.ToString(),
514 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
516 // Swipe down again to hide.
518 generator.GestureScrollSequenceWithCallback(start, end,
519 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
520 base::Bind(&ShelfDragCallback::ProcessScroll,
521 base::Unretained(&handler)));
522 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
523 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
524 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
525 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
526 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
527 EXPECT_EQ(shelf_hidden.ToString(),
528 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
530 // Swipe up outside the hit area. This should not change anything.
531 gfx::Point outside_start = gfx::Point(
532 (GetShelfWidget()->GetWindowBoundsInScreen().x() +
533 GetShelfWidget()->GetWindowBoundsInScreen().right())/2,
534 GetShelfWidget()->GetWindowBoundsInScreen().y() - 50);
535 end = outside_start + delta;
536 generator.GestureScrollSequence(outside_start,
538 base::TimeDelta::FromMilliseconds(10),
540 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
541 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
542 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
543 EXPECT_EQ(shelf_hidden.ToString(),
544 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
546 // Swipe up from below the shelf where a bezel would be, this should show the
548 gfx::Point below_start = start;
549 if (GetShelfLayoutManager()->IsHorizontalAlignment())
550 below_start.set_y(GetShelfWidget()->GetWindowBoundsInScreen().bottom() + 1);
551 else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment())
553 GetShelfWidget()->GetWindowBoundsInScreen().x() - 1);
554 else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment())
555 below_start.set_x(GetShelfWidget()->GetWindowBoundsInScreen().right() + 1);
556 end = below_start - delta;
557 generator.GestureScrollSequence(below_start,
559 base::TimeDelta::FromMilliseconds(10),
561 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
562 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
563 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
564 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
565 GetShelfWidget()->GetWindowBoundsInScreen());
566 EXPECT_EQ(shelf_shown.ToString(),
567 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
569 // Swipe down again to hide.
571 generator.GestureScrollSequenceWithCallback(start, end,
572 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
573 base::Bind(&ShelfDragCallback::ProcessScroll,
574 base::Unretained(&handler)));
575 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
576 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
577 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
578 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
579 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
580 EXPECT_EQ(shelf_hidden.ToString(),
581 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
583 // Put |widget| into fullscreen. Set the shelf to be auto hidden when |widget|
584 // is fullscreen. (eg browser immersive fullscreen).
585 widget->SetFullscreen(true);
586 wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(false);
587 shelf->UpdateVisibilityState();
589 gfx::Rect bounds_fullscreen = window->bounds();
590 EXPECT_TRUE(widget->IsFullscreen());
591 EXPECT_NE(bounds_noshelf.ToString(), bounds_fullscreen.ToString());
593 // Swipe up. This should show the shelf.
594 end = below_start - delta;
595 generator.GestureScrollSequenceWithCallback(below_start, end,
596 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
597 base::Bind(&ShelfDragCallback::ProcessScroll,
598 base::Unretained(&handler)));
599 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
600 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
601 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
602 EXPECT_EQ(shelf_shown.ToString(),
603 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
604 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString());
606 // Swipe up again. This should hide the shelf.
607 generator.GestureScrollSequenceWithCallback(below_start, end,
608 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
609 base::Bind(&ShelfDragCallback::ProcessScroll,
610 base::Unretained(&handler)));
611 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
612 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
613 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
614 EXPECT_EQ(shelf_hidden.ToString(),
615 GetShelfWidget()->GetWindowBoundsInScreen().ToString());
616 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString());
618 // Set the shelf to be hidden when |widget| is fullscreen. (eg tab fullscreen
619 // with or without immersive browser fullscreen).
620 wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(true);
621 shelf->UpdateVisibilityState();
622 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
623 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
625 // Swipe-up. This should not change anything.
627 generator.GestureScrollSequenceWithCallback(below_start, end,
628 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
629 base::Bind(&ShelfDragCallback::ProcessScroll,
630 base::Unretained(&handler)));
631 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
632 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
633 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString());
635 // Close actually, otherwise further event may be affected since widget
636 // is fullscreen status.
638 RunAllPendingInMessageLoop();
640 // The shelf should be shown because there are no more visible windows.
641 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
642 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
643 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
645 // Swipe-up to hide. This should have no effect because there are no visible
647 end = below_start - delta;
648 generator.GestureScrollSequenceWithCallback(below_start, end,
649 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
650 base::Bind(&ShelfDragCallback::ProcessScroll,
651 base::Unretained(&handler)));
652 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
653 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
654 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
657 // Need to be implemented. http://crbug.com/111279.
659 #define MAYBE_SetVisible DISABLED_SetVisible
661 #define MAYBE_SetVisible SetVisible
663 // Makes sure SetVisible updates work area and widget appropriately.
664 TEST_F(ShelfLayoutManagerTest, MAYBE_SetVisible) {
665 ShelfWidget* shelf = GetShelfWidget();
666 ShelfLayoutManager* manager = shelf->shelf_layout_manager();
667 // Force an initial layout.
668 manager->LayoutShelf();
669 EXPECT_EQ(SHELF_VISIBLE, manager->visibility_state());
671 gfx::Rect status_bounds(
672 shelf->status_area_widget()->GetWindowBoundsInScreen());
673 gfx::Rect shelf_bounds(
674 shelf->GetWindowBoundsInScreen());
675 int shelf_height = manager->GetIdealBounds().height();
676 gfx::Screen* screen = Shell::GetScreen();
677 gfx::Display display = screen->GetDisplayNearestWindow(
678 Shell::GetPrimaryRootWindow());
679 ASSERT_NE(-1, display.id());
680 // Bottom inset should be the max of widget heights.
681 EXPECT_EQ(shelf_height, display.GetWorkAreaInsets().bottom());
684 SetState(manager, SHELF_HIDDEN);
685 // Run the animation to completion.
686 StepWidgetLayerAnimatorToEnd(shelf);
687 StepWidgetLayerAnimatorToEnd(shelf->status_area_widget());
688 EXPECT_EQ(SHELF_HIDDEN, manager->visibility_state());
689 display = screen->GetDisplayNearestWindow(
690 Shell::GetPrimaryRootWindow());
692 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
694 // Make sure the bounds of the two widgets changed.
695 EXPECT_GE(shelf->GetNativeView()->bounds().y(),
696 screen->GetPrimaryDisplay().bounds().bottom());
697 EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(),
698 screen->GetPrimaryDisplay().bounds().bottom());
700 // And show it again.
701 SetState(manager, SHELF_VISIBLE);
702 // Run the animation to completion.
703 StepWidgetLayerAnimatorToEnd(shelf);
704 StepWidgetLayerAnimatorToEnd(shelf->status_area_widget());
705 EXPECT_EQ(SHELF_VISIBLE, manager->visibility_state());
706 display = screen->GetDisplayNearestWindow(
707 Shell::GetPrimaryRootWindow());
708 EXPECT_EQ(shelf_height, display.GetWorkAreaInsets().bottom());
710 // Make sure the bounds of the two widgets changed.
711 shelf_bounds = shelf->GetNativeView()->bounds();
712 EXPECT_LT(shelf_bounds.y(), screen->GetPrimaryDisplay().bounds().bottom());
713 status_bounds = shelf->status_area_widget()->GetNativeView()->bounds();
714 EXPECT_LT(status_bounds.y(),
715 screen->GetPrimaryDisplay().bounds().bottom());
718 // Makes sure shelf alignment is correct for lock screen.
719 TEST_F(ShelfLayoutManagerTest, SideAlignmentInteractionWithLockScreen) {
720 ShelfLayoutManager* manager = GetShelfWidget()->shelf_layout_manager();
721 manager->SetAlignment(SHELF_ALIGNMENT_LEFT);
722 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, manager->GetAlignment());
723 Shell::GetInstance()->session_state_delegate()->LockScreen();
724 EXPECT_EQ(SHELF_ALIGNMENT_BOTTOM, manager->GetAlignment());
725 Shell::GetInstance()->session_state_delegate()->UnlockScreen();
726 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, manager->GetAlignment());
729 // Makes sure LayoutShelf invoked while animating cleans things up.
730 TEST_F(ShelfLayoutManagerTest, LayoutShelfWhileAnimating) {
731 ShelfWidget* shelf = GetShelfWidget();
732 // Force an initial layout.
733 shelf->shelf_layout_manager()->LayoutShelf();
734 EXPECT_EQ(SHELF_VISIBLE, shelf->shelf_layout_manager()->visibility_state());
737 SetState(shelf->shelf_layout_manager(), SHELF_HIDDEN);
738 shelf->shelf_layout_manager()->LayoutShelf();
739 EXPECT_EQ(SHELF_HIDDEN, shelf->shelf_layout_manager()->visibility_state());
740 gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow(
741 Shell::GetPrimaryRootWindow());
742 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
744 // Make sure the bounds of the two widgets changed.
745 EXPECT_GE(shelf->GetNativeView()->bounds().y(),
746 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
747 EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(),
748 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom());
751 // Test that switching to a different visibility state does not restart the
752 // shelf show / hide animation if it is already running. (crbug.com/250918)
753 TEST_F(ShelfLayoutManagerTest, SetStateWhileAnimating) {
754 ShelfWidget* shelf = GetShelfWidget();
755 SetState(shelf->shelf_layout_manager(), SHELF_VISIBLE);
756 gfx::Rect initial_shelf_bounds = shelf->GetWindowBoundsInScreen();
757 gfx::Rect initial_status_bounds =
758 shelf->status_area_widget()->GetWindowBoundsInScreen();
760 ui::ScopedAnimationDurationScaleMode normal_animation_duration(
761 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
762 SetState(shelf->shelf_layout_manager(), SHELF_HIDDEN);
763 SetState(shelf->shelf_layout_manager(), SHELF_VISIBLE);
765 gfx::Rect current_shelf_bounds = shelf->GetWindowBoundsInScreen();
766 gfx::Rect current_status_bounds =
767 shelf->status_area_widget()->GetWindowBoundsInScreen();
769 const int small_change = initial_shelf_bounds.height() / 2;
771 std::abs(initial_shelf_bounds.height() - current_shelf_bounds.height()),
774 std::abs(initial_status_bounds.height() - current_status_bounds.height()),
778 // Makes sure the shelf is sized when the status area changes size.
779 TEST_F(ShelfLayoutManagerTest, ShelfUpdatedWhenStatusAreaChangesSize) {
780 Shelf* shelf = Shelf::ForPrimaryDisplay();
782 ShelfWidget* shelf_widget = GetShelfWidget();
783 ASSERT_TRUE(shelf_widget);
784 ASSERT_TRUE(shelf_widget->status_area_widget());
785 shelf_widget->status_area_widget()->SetBounds(
786 gfx::Rect(0, 0, 200, 200));
787 EXPECT_EQ(200, shelf_widget->GetContentsView()->width() -
788 test::ShelfTestAPI(shelf).shelf_view()->width());
793 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
794 #define MAYBE_AutoHide DISABLED_AutoHide
796 #define MAYBE_AutoHide AutoHide
799 // Various assertions around auto-hide.
800 TEST_F(ShelfLayoutManagerTest, MAYBE_AutoHide) {
801 aura::Window* root = Shell::GetPrimaryRootWindow();
802 aura::test::EventGenerator generator(root, root);
803 generator.MoveMouseTo(0, 0);
805 ShelfLayoutManager* shelf = GetShelfLayoutManager();
806 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
807 views::Widget* widget = new views::Widget;
808 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
809 params.bounds = gfx::Rect(0, 0, 200, 200);
810 params.context = CurrentContext();
811 // Widget is now owned by the parent window.
812 widget->Init(params);
815 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
816 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
818 // LayoutShelf() forces the animation to completion, at which point the
819 // shelf should go off the screen.
820 shelf->LayoutShelf();
821 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
822 GetShelfWidget()->GetWindowBoundsInScreen().y());
823 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
824 Shell::GetScreen()->GetDisplayNearestWindow(
825 root).work_area().bottom());
827 // Move the mouse to the bottom of the screen.
828 generator.MoveMouseTo(0, root->bounds().bottom() - 1);
830 // Shelf should be shown again (but it shouldn't have changed the work area).
831 SetState(shelf, SHELF_AUTO_HIDE);
832 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
833 shelf->LayoutShelf();
834 EXPECT_EQ(root->bounds().bottom() - shelf->GetIdealBounds().height(),
835 GetShelfWidget()->GetWindowBoundsInScreen().y());
836 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
837 Shell::GetScreen()->GetDisplayNearestWindow(
838 root).work_area().bottom());
840 // Move mouse back up.
841 generator.MoveMouseTo(0, 0);
842 SetState(shelf, SHELF_AUTO_HIDE);
843 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
844 shelf->LayoutShelf();
845 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
846 GetShelfWidget()->GetWindowBoundsInScreen().y());
848 // Drag mouse to bottom of screen.
849 generator.PressLeftButton();
850 generator.MoveMouseTo(0, root->bounds().bottom() - 1);
851 UpdateAutoHideStateNow();
852 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
854 generator.ReleaseLeftButton();
855 generator.MoveMouseTo(1, root->bounds().bottom() - 1);
856 UpdateAutoHideStateNow();
857 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
858 generator.PressLeftButton();
859 generator.MoveMouseTo(1, root->bounds().bottom() - 1);
860 UpdateAutoHideStateNow();
861 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
864 // Test the behavior of the shelf when it is auto hidden and it is on the
865 // boundary between the primary and the secondary display.
866 TEST_F(ShelfLayoutManagerTest, AutoHideShelfOnScreenBoundary) {
867 if (!SupportsMultipleDisplays())
870 UpdateDisplay("800x600,800x600");
871 DisplayLayout display_layout(DisplayLayout::RIGHT, 0);
872 Shell::GetInstance()->display_manager()->SetLayoutForCurrentDisplays(
874 // Put the primary monitor's shelf on the display boundary.
875 ShelfLayoutManager* shelf = GetShelfLayoutManager();
876 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
878 // Create a window because the shelf is always shown when no windows are
882 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
883 ASSERT_EQ(root_windows[0],
884 GetShelfWidget()->GetNativeWindow()->GetRootWindow());
886 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
887 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
889 int right_edge = root_windows[0]->GetBoundsInScreen().right() - 1;
890 int y = root_windows[0]->GetBoundsInScreen().y();
892 // Start off the mouse nowhere near the shelf; the shelf should be hidden.
893 aura::test::EventGenerator& generator(GetEventGenerator());
894 generator.MoveMouseTo(right_edge - 50, y);
895 UpdateAutoHideStateNow();
896 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
898 // Moving the mouse over the light bar (but not to the edge of the screen)
899 // should show the shelf.
900 generator.MoveMouseTo(right_edge - 1, y);
901 UpdateAutoHideStateNow();
902 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
903 EXPECT_EQ(right_edge - 1, Shell::GetScreen()->GetCursorScreenPoint().x());
905 // Moving the mouse off the light bar should hide the shelf.
906 generator.MoveMouseTo(right_edge - 50, y);
907 UpdateAutoHideStateNow();
908 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
910 // Moving the mouse to the right edge of the screen crossing the light bar
911 // should show the shelf despite the mouse cursor getting warped to the
912 // secondary display.
913 generator.MoveMouseTo(right_edge - 1, y);
914 generator.MoveMouseTo(right_edge, y);
915 UpdateAutoHideStateNow();
916 EXPECT_NE(right_edge - 1, Shell::GetScreen()->GetCursorScreenPoint().x());
917 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
920 generator.MoveMouseTo(right_edge - 50, y);
921 UpdateAutoHideStateNow();
922 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
924 // Moving the mouse to the right edge of the screen crossing the light bar and
925 // overshooting by a lot should keep the shelf hidden.
926 generator.MoveMouseTo(right_edge - 1, y);
927 generator.MoveMouseTo(right_edge + 50, y);
928 UpdateAutoHideStateNow();
929 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
931 // Moving the mouse to the right edge of the screen crossing the light bar and
932 // overshooting a bit should show the shelf.
933 generator.MoveMouseTo(right_edge - 1, y);
934 generator.MoveMouseTo(right_edge + 2, y);
935 UpdateAutoHideStateNow();
936 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
938 // Keeping the mouse close to the left edge of the secondary display after the
939 // shelf is shown should keep the shelf shown.
940 generator.MoveMouseTo(right_edge + 2, y + 1);
941 UpdateAutoHideStateNow();
942 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
944 // Moving the mouse far from the left edge of the secondary display should
946 generator.MoveMouseTo(right_edge + 50, y);
947 UpdateAutoHideStateNow();
948 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
950 // Moving to the left edge of the secondary display without first crossing
951 // the primary display's right aligned shelf first should not show the shelf.
952 generator.MoveMouseTo(right_edge + 2, y);
953 UpdateAutoHideStateNow();
954 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
957 // Assertions around the lock screen showing.
958 TEST_F(ShelfLayoutManagerTest, VisibleWhenLockScreenShowing) {
959 // Since ShelfLayoutManager queries for mouse location, move the mouse so
960 // it isn't over the shelf.
961 aura::test::EventGenerator generator(
962 Shell::GetPrimaryRootWindow(), gfx::Point());
963 generator.MoveMouseTo(0, 0);
965 ShelfLayoutManager* shelf = GetShelfLayoutManager();
966 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
967 views::Widget* widget = new views::Widget;
968 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
969 params.bounds = gfx::Rect(0, 0, 200, 200);
970 params.context = CurrentContext();
971 // Widget is now owned by the parent window.
972 widget->Init(params);
975 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
976 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
978 aura::Window* root = Shell::GetPrimaryRootWindow();
979 // LayoutShelf() forces the animation to completion, at which point the
980 // shelf should go off the screen.
981 shelf->LayoutShelf();
982 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize,
983 GetShelfWidget()->GetWindowBoundsInScreen().y());
985 aura::Window* lock_container = Shell::GetContainer(
986 Shell::GetPrimaryRootWindow(),
987 internal::kShellWindowId_LockScreenContainer);
989 views::Widget* lock_widget = new views::Widget;
990 views::Widget::InitParams lock_params(
991 views::Widget::InitParams::TYPE_WINDOW);
992 lock_params.bounds = gfx::Rect(0, 0, 200, 200);
993 params.context = CurrentContext();
994 lock_params.parent = lock_container;
995 // Widget is now owned by the parent window.
996 lock_widget->Init(lock_params);
997 lock_widget->Maximize();
1001 Shell::GetInstance()->session_state_delegate()->LockScreen();
1002 shelf->UpdateVisibilityState();
1003 // Showing a widget in the lock screen should force the shelf to be visibile.
1004 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1006 Shell::GetInstance()->session_state_delegate()->UnlockScreen();
1007 shelf->UpdateVisibilityState();
1008 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1011 // Assertions around SetAutoHideBehavior.
1012 TEST_F(ShelfLayoutManagerTest, SetAutoHideBehavior) {
1013 // Since ShelfLayoutManager queries for mouse location, move the mouse so
1014 // it isn't over the shelf.
1015 aura::test::EventGenerator generator(
1016 Shell::GetPrimaryRootWindow(), gfx::Point());
1017 generator.MoveMouseTo(0, 0);
1019 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1020 views::Widget* widget = new views::Widget;
1021 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1022 params.bounds = gfx::Rect(0, 0, 200, 200);
1023 params.context = CurrentContext();
1024 // Widget is now owned by the parent window.
1025 widget->Init(params);
1027 aura::Window* window = widget->GetNativeWindow();
1028 gfx::Rect display_bounds(
1029 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
1031 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1032 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1034 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1035 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1038 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1039 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
1040 window).work_area().bottom(),
1041 widget->GetWorkAreaBoundsInScreen().bottom());
1043 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1044 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1045 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
1046 window).work_area().bottom(),
1047 widget->GetWorkAreaBoundsInScreen().bottom());
1049 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1050 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1051 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
1052 window).work_area().bottom(),
1053 widget->GetWorkAreaBoundsInScreen().bottom());
1056 // Basic assertions around the dimming of the shelf.
1057 TEST_F(ShelfLayoutManagerTest, TestDimmingBehavior) {
1058 // Since ShelfLayoutManager queries for mouse location, move the mouse so
1059 // it isn't over the shelf.
1060 aura::test::EventGenerator generator(
1061 Shell::GetPrimaryRootWindow(), gfx::Point());
1062 generator.MoveMouseTo(0, 0);
1064 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1065 shelf->shelf_widget()->DisableDimmingAnimationsForTest();
1067 views::Widget* widget = new views::Widget;
1068 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1069 params.bounds = gfx::Rect(0, 0, 200, 200);
1070 params.context = CurrentContext();
1071 // Widget is now owned by the parent window.
1072 widget->Init(params);
1074 aura::Window* window = widget->GetNativeWindow();
1075 gfx::Rect display_bounds(
1076 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
1078 gfx::Point off_shelf = display_bounds.CenterPoint();
1079 gfx::Point on_shelf =
1080 shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
1082 // Test there is no dimming object active at this point.
1083 generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
1084 EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
1085 generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
1086 EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
1088 // After maximization, the shelf should be visible and the dimmer created.
1091 on_shelf = shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
1092 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1094 // Moving the mouse off the shelf should dim the bar.
1095 generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
1096 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1098 // Adding touch events outside the shelf should still keep the shelf in
1100 generator.PressTouch();
1101 generator.MoveTouch(off_shelf);
1102 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1103 // Move the touch into the shelf area should undim.
1104 generator.MoveTouch(on_shelf);
1105 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1106 generator.ReleaseTouch();
1107 // And a release dims again.
1108 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1110 // Moving the mouse on the shelf should undim the bar.
1111 generator.MoveMouseTo(on_shelf);
1112 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1114 // No matter what the touch events do, the shelf should stay undimmed.
1115 generator.PressTouch();
1116 generator.MoveTouch(off_shelf);
1117 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1118 generator.MoveTouch(on_shelf);
1119 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1120 generator.MoveTouch(off_shelf);
1121 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1122 generator.MoveTouch(on_shelf);
1123 generator.ReleaseTouch();
1125 // After restore, the dimming object should be deleted again.
1127 EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
1130 // Assertions around the dimming of the shelf in conjunction with menus.
1131 TEST_F(ShelfLayoutManagerTest, TestDimmingBehaviorWithMenus) {
1132 // Since ShelfLayoutManager queries for mouse location, move the mouse so
1133 // it isn't over the shelf.
1134 aura::test::EventGenerator generator(
1135 Shell::GetPrimaryRootWindow(), gfx::Point());
1136 generator.MoveMouseTo(0, 0);
1138 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1139 shelf->shelf_widget()->DisableDimmingAnimationsForTest();
1141 views::Widget* widget = new views::Widget;
1142 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1143 params.bounds = gfx::Rect(0, 0, 200, 200);
1144 params.context = CurrentContext();
1145 // Widget is now owned by the parent window.
1146 widget->Init(params);
1148 aura::Window* window = widget->GetNativeWindow();
1149 gfx::Rect display_bounds(
1150 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
1152 // After maximization, the shelf should be visible and the dimmer created.
1155 gfx::Point off_shelf = display_bounds.CenterPoint();
1156 gfx::Point on_shelf =
1157 shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
1159 // Moving the mouse on the shelf should undim the bar.
1160 generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
1161 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1163 // Simulate a menu opening.
1164 shelf->shelf_widget()->ForceUndimming(true);
1166 // Moving the mouse off the shelf should not dim the bar.
1167 generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
1168 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1170 // No matter what the touch events do, the shelf should stay undimmed.
1171 generator.PressTouch();
1172 generator.MoveTouch(off_shelf);
1173 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1174 generator.MoveTouch(on_shelf);
1175 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1176 generator.MoveTouch(off_shelf);
1177 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1178 generator.ReleaseTouch();
1179 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1181 // "Closing the menu" should now turn off the menu since no event is inside
1182 // the shelf any longer.
1183 shelf->shelf_widget()->ForceUndimming(false);
1184 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1186 // Moving the mouse again on the shelf which should undim the bar again.
1187 // This time we check that the bar stays undimmed when the mouse remains on
1188 // the bar and the "menu gets closed".
1189 generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
1190 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1191 shelf->shelf_widget()->ForceUndimming(true);
1192 generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
1193 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1194 generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
1195 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1196 shelf->shelf_widget()->ForceUndimming(true);
1197 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
1200 // Verifies the shelf is visible when status/shelf is focused.
1201 TEST_F(ShelfLayoutManagerTest, VisibleWhenStatusOrShelfFocused) {
1202 // Since ShelfLayoutManager queries for mouse location, move the mouse so
1203 // it isn't over the shelf.
1204 aura::test::EventGenerator generator(
1205 Shell::GetPrimaryRootWindow(), gfx::Point());
1206 generator.MoveMouseTo(0, 0);
1208 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1209 views::Widget* widget = new views::Widget;
1210 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1211 params.bounds = gfx::Rect(0, 0, 200, 200);
1212 params.context = CurrentContext();
1213 // Widget is now owned by the parent window.
1214 widget->Init(params);
1216 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1217 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1218 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1220 // Focus the shelf. Have to go through the focus cycler as normal focus
1221 // requests to it do nothing.
1222 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD);
1223 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1226 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1228 // Trying to activate the status should fail, since we only allow activating
1229 // it when the user is using the keyboard (i.e. through FocusCycler).
1230 GetShelfWidget()->status_area_widget()->Activate();
1231 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1233 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD);
1234 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1237 // Makes sure shelf will be visible when app list opens as shelf is in
1238 // SHELF_VISIBLE state,and toggling app list won't change shelf
1239 // visibility state.
1240 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfVisibleState) {
1241 Shell* shell = Shell::GetInstance();
1242 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1243 shelf->LayoutShelf();
1244 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1246 // Create a normal unmaximized windowm shelf should be visible.
1247 aura::Window* window = CreateTestWindow();
1248 window->SetBounds(gfx::Rect(0, 0, 100, 100));
1250 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1251 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1253 // Toggle app list to show, and the shelf stays visible.
1254 shell->ToggleAppList(NULL);
1255 EXPECT_TRUE(shell->GetAppListTargetVisibility());
1256 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1258 // Toggle app list to hide, and the shelf stays visible.
1259 shell->ToggleAppList(NULL);
1260 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1261 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1264 // Makes sure shelf will be shown with SHELF_AUTO_HIDE_SHOWN state
1265 // when app list opens as shelf is in SHELF_AUTO_HIDE state, and
1266 // toggling app list won't change shelf visibility state.
1267 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfAutoHideState) {
1268 Shell* shell = Shell::GetInstance();
1269 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1270 shelf->LayoutShelf();
1271 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1273 // Create a window and show it in maximized state.
1274 aura::Window* window = CreateTestWindow();
1275 window->SetBounds(gfx::Rect(0, 0, 100, 100));
1276 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1278 wm::ActivateWindow(window);
1280 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1281 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1283 // Toggle app list to show.
1284 shell->ToggleAppList(NULL);
1285 // The shelf's auto hide state won't be changed until the timer fires, so
1286 // calling shell->UpdateShelfVisibility() is kind of manually helping it to
1287 // update the state.
1288 shell->UpdateShelfVisibility();
1289 EXPECT_TRUE(shell->GetAppListTargetVisibility());
1290 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1291 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1293 // Toggle app list to hide.
1294 shell->ToggleAppList(NULL);
1295 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1296 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1299 // Makes sure shelf will be hidden when app list opens as shelf is in HIDDEN
1300 // state, and toggling app list won't change shelf visibility state.
1301 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfHiddenState) {
1302 Shell* shell = Shell::GetInstance();
1303 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1304 // For shelf to be visible, app list is not open in initial state.
1305 shelf->LayoutShelf();
1307 // Create a window and make it full screen.
1308 aura::Window* window = CreateTestWindow();
1309 window->SetBounds(gfx::Rect(0, 0, 100, 100));
1310 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
1312 wm::ActivateWindow(window);
1314 // App list and shelf is not shown.
1315 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1316 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
1318 // Toggle app list to show.
1319 shell->ToggleAppList(NULL);
1320 EXPECT_TRUE(shell->GetAppListTargetVisibility());
1321 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
1323 // Toggle app list to hide.
1324 shell->ToggleAppList(NULL);
1325 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1326 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
1329 // Tests that the shelf is only hidden for a fullscreen window at the front and
1330 // toggles visibility when another window is activated.
1331 TEST_F(ShelfLayoutManagerTest, FullscreenWindowInFrontHidesShelf) {
1332 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1334 // Create a window and make it full screen.
1335 aura::Window* window1 = CreateTestWindow();
1336 window1->SetBounds(gfx::Rect(0, 0, 100, 100));
1337 window1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
1340 aura::Window* window2 = CreateTestWindow();
1341 window2->SetBounds(gfx::Rect(0, 0, 100, 100));
1344 wm::GetWindowState(window1)->Activate();
1345 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
1347 wm::GetWindowState(window2)->Activate();
1348 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1350 wm::GetWindowState(window1)->Activate();
1351 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
1354 // Test the behavior of the shelf when a window on one display is fullscreen
1355 // but the other display has the active window.
1356 TEST_F(ShelfLayoutManagerTest, FullscreenWindowOnSecondDisplay) {
1357 if (!SupportsMultipleDisplays())
1360 UpdateDisplay("800x600,800x600");
1361 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
1362 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1363 Shell::RootWindowControllerList root_window_controllers =
1364 Shell::GetAllRootWindowControllers();
1366 // Create windows on either display.
1367 aura::Window* window1 = CreateTestWindow();
1368 window1->SetBoundsInScreen(
1369 gfx::Rect(0, 0, 100, 100),
1370 display_manager->GetDisplayAt(0));
1371 window1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
1374 aura::Window* window2 = CreateTestWindow();
1375 window2->SetBoundsInScreen(
1376 gfx::Rect(800, 0, 100, 100),
1377 display_manager->GetDisplayAt(1));
1380 EXPECT_EQ(root_windows[0], window1->GetRootWindow());
1381 EXPECT_EQ(root_windows[1], window2->GetRootWindow());
1383 wm::GetWindowState(window2)->Activate();
1384 EXPECT_EQ(SHELF_HIDDEN,
1385 root_window_controllers[0]->GetShelfLayoutManager()->visibility_state());
1386 EXPECT_EQ(SHELF_VISIBLE,
1387 root_window_controllers[1]->GetShelfLayoutManager()->visibility_state());
1392 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1393 #define MAYBE_SetAlignment DISABLED_SetAlignment
1395 #define MAYBE_SetAlignment SetAlignment
1398 // Tests SHELF_ALIGNMENT_(LEFT, RIGHT, TOP).
1399 TEST_F(ShelfLayoutManagerTest, MAYBE_SetAlignment) {
1400 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1401 // Force an initial layout.
1402 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1403 shelf->LayoutShelf();
1404 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1406 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
1407 gfx::Rect shelf_bounds(
1408 GetShelfWidget()->GetWindowBoundsInScreen());
1409 const gfx::Screen* screen = Shell::GetScreen();
1410 gfx::Display display =
1411 screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1412 ASSERT_NE(-1, display.id());
1413 EXPECT_EQ(shelf->GetIdealBounds().width(),
1414 display.GetWorkAreaInsets().left());
1416 shelf_bounds.width(),
1417 GetShelfWidget()->GetContentsView()->GetPreferredSize().width());
1418 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, GetSystemTray()->shelf_alignment());
1419 StatusAreaWidget* status_area_widget = GetShelfWidget()->status_area_widget();
1420 gfx::Rect status_bounds(status_area_widget->GetWindowBoundsInScreen());
1421 EXPECT_GE(status_bounds.width(),
1422 status_area_widget->GetContentsView()->GetPreferredSize().width());
1423 EXPECT_EQ(shelf->GetIdealBounds().width(),
1424 display.GetWorkAreaInsets().left());
1425 EXPECT_EQ(0, display.GetWorkAreaInsets().top());
1426 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
1427 EXPECT_EQ(0, display.GetWorkAreaInsets().right());
1428 EXPECT_EQ(display.bounds().x(), shelf_bounds.x());
1429 EXPECT_EQ(display.bounds().y(), shelf_bounds.y());
1430 EXPECT_EQ(display.bounds().height(), shelf_bounds.height());
1431 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1432 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1433 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
1434 display.GetWorkAreaInsets().left());
1435 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, display.work_area().x());
1437 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1438 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
1439 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1440 shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
1441 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1442 ASSERT_NE(-1, display.id());
1443 EXPECT_EQ(shelf->GetIdealBounds().width(),
1444 display.GetWorkAreaInsets().right());
1445 EXPECT_GE(shelf_bounds.width(),
1446 GetShelfWidget()->GetContentsView()->GetPreferredSize().width());
1447 EXPECT_EQ(SHELF_ALIGNMENT_RIGHT, GetSystemTray()->shelf_alignment());
1448 status_bounds = gfx::Rect(status_area_widget->GetWindowBoundsInScreen());
1449 EXPECT_GE(status_bounds.width(),
1450 status_area_widget->GetContentsView()->GetPreferredSize().width());
1451 EXPECT_EQ(shelf->GetIdealBounds().width(),
1452 display.GetWorkAreaInsets().right());
1453 EXPECT_EQ(0, display.GetWorkAreaInsets().top());
1454 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
1455 EXPECT_EQ(0, display.GetWorkAreaInsets().left());
1456 EXPECT_EQ(display.work_area().right(), shelf_bounds.x());
1457 EXPECT_EQ(display.bounds().y(), shelf_bounds.y());
1458 EXPECT_EQ(display.bounds().height(), shelf_bounds.height());
1459 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1460 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1461 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
1462 display.GetWorkAreaInsets().right());
1463 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
1464 display.bounds().right() - display.work_area().right());
1466 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1467 shelf->SetAlignment(SHELF_ALIGNMENT_TOP);
1468 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1469 shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
1470 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1471 ASSERT_NE(-1, display.id());
1472 EXPECT_EQ(shelf->GetIdealBounds().height(),
1473 display.GetWorkAreaInsets().top());
1474 EXPECT_GE(shelf_bounds.height(),
1475 GetShelfWidget()->GetContentsView()->GetPreferredSize().height());
1476 EXPECT_EQ(SHELF_ALIGNMENT_TOP, GetSystemTray()->shelf_alignment());
1477 status_bounds = gfx::Rect(status_area_widget->GetWindowBoundsInScreen());
1478 EXPECT_GE(status_bounds.height(),
1479 status_area_widget->GetContentsView()->GetPreferredSize().height());
1480 EXPECT_EQ(shelf->GetIdealBounds().height(),
1481 display.GetWorkAreaInsets().top());
1482 EXPECT_EQ(0, display.GetWorkAreaInsets().right());
1483 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom());
1484 EXPECT_EQ(0, display.GetWorkAreaInsets().left());
1485 EXPECT_EQ(display.work_area().y(), shelf_bounds.bottom());
1486 EXPECT_EQ(display.bounds().x(), shelf_bounds.x());
1487 EXPECT_EQ(display.bounds().width(), shelf_bounds.width());
1488 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1489 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow());
1490 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
1491 display.GetWorkAreaInsets().top());
1492 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize,
1493 display.work_area().y() - display.bounds().y());
1496 TEST_F(ShelfLayoutManagerTest, GestureEdgeSwipe) {
1497 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1498 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1499 views::Widget* widget = new views::Widget;
1500 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1501 params.bounds = gfx::Rect(0, 0, 200, 200);
1502 params.context = CurrentContext();
1503 widget->Init(params);
1507 aura::Window* window = widget->GetNativeWindow();
1508 shelf->LayoutShelf();
1510 gfx::Rect shelf_shown = GetShelfWidget()->GetWindowBoundsInScreen();
1511 gfx::Rect bounds_shelf = window->bounds();
1512 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1514 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1515 shelf->LayoutShelf();
1516 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1518 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1519 generator.GestureEdgeSwipe();
1521 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1522 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
1524 widget->SetFullscreen(true);
1525 wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(false);
1526 shelf->UpdateVisibilityState();
1528 gfx::Rect bounds_fullscreen = window->bounds();
1529 EXPECT_TRUE(widget->IsFullscreen());
1530 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1532 generator.GestureEdgeSwipe();
1533 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1534 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
1535 EXPECT_FALSE(widget->IsFullscreen());
1539 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1540 #define MAYBE_GestureDrag DISABLED_GestureDrag
1542 #define MAYBE_GestureDrag GestureDrag
1545 TEST_F(ShelfLayoutManagerTest, MAYBE_GestureDrag) {
1546 // Slop is an implementation detail of gesture recognition, and complicates
1547 // these tests. Ignore it.
1548 ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click(0);
1549 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1551 SCOPED_TRACE("BOTTOM");
1552 RunGestureDragTests(gfx::Vector2d(0, 120));
1556 SCOPED_TRACE("LEFT");
1557 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
1558 RunGestureDragTests(gfx::Vector2d(-120, 0));
1562 SCOPED_TRACE("RIGHT");
1563 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
1564 RunGestureDragTests(gfx::Vector2d(120, 0));
1568 TEST_F(ShelfLayoutManagerTest, WindowVisibilityDisablesAutoHide) {
1569 if (!SupportsMultipleDisplays())
1572 UpdateDisplay("800x600,800x600");
1573 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1574 shelf->LayoutShelf();
1575 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1577 // Create a visible window so auto-hide behavior is enforced
1578 views::Widget* dummy = CreateTestWidget();
1580 // Window visible => auto hide behaves normally.
1581 shelf->UpdateVisibilityState();
1582 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1584 // Window minimized => auto hide disabled.
1586 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1588 // Window closed => auto hide disabled.
1590 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1592 // Multiple window test
1593 views::Widget* window1 = CreateTestWidget();
1594 views::Widget* window2 = CreateTestWidget();
1596 // both visible => normal autohide
1597 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1599 // either minimzed => normal autohide
1600 window2->Minimize();
1601 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1603 window1->Minimize();
1604 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1606 // both minimized => disable auto hide
1607 window2->Minimize();
1608 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1610 // Test moving windows to/from other display.
1612 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1613 // Move to second display.
1614 window2->SetBounds(gfx::Rect(850, 50, 50, 50));
1615 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1616 // Move back to primary display.
1617 window2->SetBounds(gfx::Rect(50, 50, 50, 50));
1618 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1621 // Test that the shelf animates back to its normal position upon a user
1622 // completing a gesture drag.
1623 TEST_F(ShelfLayoutManagerTest, ShelfAnimatesWhenGestureComplete) {
1624 if (!SupportsHostWindowResize())
1627 // Test the shelf animates back to its original visible bounds when it is
1628 // dragged when there are no visible windows.
1629 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1630 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1631 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1632 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1633 gfx::Rect visible_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
1635 // Enable animations so that we can make sure that they occur.
1636 ui::ScopedAnimationDurationScaleMode regular_animations(
1637 ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
1639 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1640 gfx::Rect shelf_bounds_in_screen =
1641 GetShelfWidget()->GetWindowBoundsInScreen();
1642 gfx::Point start(shelf_bounds_in_screen.CenterPoint());
1643 gfx::Point end(start.x(), shelf_bounds_in_screen.bottom());
1644 generator.GestureScrollSequence(start, end,
1645 base::TimeDelta::FromMilliseconds(10), 5);
1646 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1647 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1649 ShelfAnimationWaiter waiter(visible_bounds);
1650 // Wait till the animation completes and check that it occurred.
1651 waiter.WaitTillDoneAnimating();
1652 EXPECT_TRUE(waiter.WasValidAnimation());
1655 // Create a visible window so auto-hide behavior is enforced.
1658 // Get the bounds of the shelf when it is hidden.
1659 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1660 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1661 gfx::Rect auto_hidden_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
1664 // Enable the animations so that we can make sure they do occur.
1665 ui::ScopedAnimationDurationScaleMode regular_animations(
1666 ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
1669 GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint();
1670 gfx::Point end(start.x(), start.y() - 100);
1671 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1673 // Test that the shelf animates to the visible bounds after a swipe up on
1674 // the auto hidden shelf.
1675 generator.GestureScrollSequence(start, end,
1676 base::TimeDelta::FromMilliseconds(10), 1);
1677 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1678 ShelfAnimationWaiter waiter1(visible_bounds);
1679 waiter1.WaitTillDoneAnimating();
1680 EXPECT_TRUE(waiter1.WasValidAnimation());
1682 // Test that the shelf animates to the auto hidden bounds after a swipe up
1683 // on the visible shelf.
1684 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1685 generator.GestureScrollSequence(start, end,
1686 base::TimeDelta::FromMilliseconds(10), 1);
1687 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1688 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1689 ShelfAnimationWaiter waiter2(auto_hidden_bounds);
1690 waiter2.WaitTillDoneAnimating();
1691 EXPECT_TRUE(waiter2.WasValidAnimation());
1695 TEST_F(ShelfLayoutManagerTest, GestureRevealsTrayBubble) {
1696 if (!SupportsHostWindowResize())
1699 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1700 shelf->LayoutShelf();
1702 // Create a visible window so auto-hide behavior is enforced.
1705 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1706 SystemTray* tray = GetSystemTray();
1708 // First, make sure the shelf is visible.
1709 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1710 EXPECT_FALSE(tray->HasSystemBubble());
1712 // Now, drag up on the tray to show the bubble.
1713 gfx::Point start = GetShelfWidget()->status_area_widget()->
1714 GetWindowBoundsInScreen().CenterPoint();
1715 gfx::Point end(start.x(), start.y() - 100);
1716 generator.GestureScrollSequence(start, end,
1717 base::TimeDelta::FromMilliseconds(10), 1);
1718 EXPECT_TRUE(tray->HasSystemBubble());
1719 tray->CloseSystemBubble();
1720 RunAllPendingInMessageLoop();
1721 EXPECT_FALSE(tray->HasSystemBubble());
1723 // Drag again, but only a small amount, and slowly. The bubble should not be
1725 end.set_y(start.y() - 30);
1726 generator.GestureScrollSequence(start, end,
1727 base::TimeDelta::FromMilliseconds(500), 100);
1728 EXPECT_FALSE(tray->HasSystemBubble());
1730 // Now, hide the shelf.
1731 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1733 // Start a drag from the bezel, and drag up to show both the shelf and the
1735 start.set_y(start.y() + 100);
1736 end.set_y(start.y() - 400);
1737 generator.GestureScrollSequence(start, end,
1738 base::TimeDelta::FromMilliseconds(10), 1);
1739 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
1740 EXPECT_TRUE(tray->HasSystemBubble());
1743 TEST_F(ShelfLayoutManagerTest, ShelfFlickerOnTrayActivation) {
1744 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1746 // Create a visible window so auto-hide behavior is enforced.
1749 // Turn on auto-hide for the shelf.
1750 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1751 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1752 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
1754 // Show the status menu. That should make the shelf visible again.
1755 Shell::GetInstance()->accelerator_controller()->PerformAction(
1756 SHOW_SYSTEM_TRAY_BUBBLE, ui::Accelerator());
1757 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
1758 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
1759 EXPECT_TRUE(GetSystemTray()->HasSystemBubble());
1762 TEST_F(ShelfLayoutManagerTest, WorkAreaChangeWorkspace) {
1763 // Make sure the shelf is always visible.
1764 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1765 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1766 shelf->LayoutShelf();
1768 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
1769 params.bounds = gfx::Rect(0, 0, 200, 200);
1770 params.context = CurrentContext();
1771 views::Widget* widget_one = CreateTestWidgetWithParams(params);
1772 widget_one->Maximize();
1774 views::Widget* widget_two = CreateTestWidgetWithParams(params);
1775 widget_two->Maximize();
1776 widget_two->Activate();
1778 // Both windows are maximized. They should be of the same size.
1779 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
1780 widget_two->GetNativeWindow()->bounds().ToString());
1781 int area_when_shelf_shown =
1782 widget_one->GetNativeWindow()->bounds().size().GetArea();
1784 // Now hide the shelf.
1785 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1787 // Both windows should be resized according to the shelf status.
1788 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
1789 widget_two->GetNativeWindow()->bounds().ToString());
1790 // Resized to small.
1791 EXPECT_LT(area_when_shelf_shown,
1792 widget_one->GetNativeWindow()->bounds().size().GetArea());
1794 // Now show the shelf.
1795 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1797 // Again both windows should be of the same size.
1798 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(),
1799 widget_two->GetNativeWindow()->bounds().ToString());
1800 EXPECT_EQ(area_when_shelf_shown,
1801 widget_one->GetNativeWindow()->bounds().size().GetArea());
1804 // Confirm that the shelf is dimmed only when content is maximized and
1805 // shelf is not autohidden.
1806 TEST_F(ShelfLayoutManagerTest, Dimming) {
1807 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1808 scoped_ptr<aura::Window> w1(CreateTestWindow());
1810 wm::ActivateWindow(w1.get());
1812 // Normal window doesn't dim shelf.
1813 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
1814 ShelfWidget* shelf = GetShelfWidget();
1815 EXPECT_FALSE(shelf->GetDimsShelf());
1817 // Maximized window does.
1818 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1819 EXPECT_TRUE(shelf->GetDimsShelf());
1821 // Change back to normal stops dimming.
1822 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
1823 EXPECT_FALSE(shelf->GetDimsShelf());
1825 // Changing back to maximized dims again.
1826 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1827 EXPECT_TRUE(shelf->GetDimsShelf());
1829 // Changing shelf to autohide stops dimming.
1830 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1831 EXPECT_FALSE(shelf->GetDimsShelf());
1834 // Make sure that the shelf will not hide if the mouse is between a bubble and
1836 TEST_F(ShelfLayoutManagerTest, BubbleEnlargesShelfMouseHitArea) {
1837 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1838 StatusAreaWidget* status_area_widget =
1839 Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
1840 SystemTray* tray = GetSystemTray();
1842 // Create a visible window so auto-hide behavior is enforced.
1845 shelf->LayoutShelf();
1846 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1848 // Make two iterations - first without a message bubble which should make
1849 // the shelf disappear and then with a message bubble which should keep it
1851 for (int i = 0; i < 2; i++) {
1852 // Make sure the shelf is visible and position the mouse over it. Then
1854 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
1855 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1857 status_area_widget->GetWindowBoundsInScreen().CenterPoint();
1858 generator.MoveMouseTo(center.x(), center.y());
1859 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1860 EXPECT_TRUE(shelf->IsVisible());
1862 // In our first iteration we make sure there is no bubble.
1863 tray->CloseSystemBubble();
1864 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1866 // In our second iteration we show a bubble.
1867 TestItem *item = new TestItem;
1868 tray->AddTrayItem(item);
1869 tray->ShowNotificationView(item);
1870 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
1872 // Move the pointer over the edge of the shelf.
1873 generator.MoveMouseTo(
1874 center.x(), status_area_widget->GetWindowBoundsInScreen().y() - 8);
1875 shelf->UpdateVisibilityState();
1877 EXPECT_TRUE(shelf->IsVisible());
1878 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
1880 EXPECT_FALSE(shelf->IsVisible());
1881 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1886 TEST_F(ShelfLayoutManagerTest, ShelfBackgroundColor) {
1887 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
1889 scoped_ptr<aura::Window> w1(CreateTestWindow());
1891 wm::ActivateWindow(w1.get());
1892 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
1893 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1894 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType());
1896 scoped_ptr<aura::Window> w2(CreateTestWindow());
1898 wm::ActivateWindow(w2.get());
1899 // Overlaps with shelf.
1900 w2->SetBounds(GetShelfLayoutManager()->GetIdealBounds());
1902 // Still background is 'maximized'.
1903 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType());
1905 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
1906 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType());
1907 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
1908 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
1910 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1911 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType());
1913 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType());
1916 // Verify that the shelf doesn't have the opaque background if it's auto-hide
1918 TEST_F(ShelfLayoutManagerTest, ShelfBackgroundColorAutoHide) {
1919 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget ()->GetBackgroundType());
1921 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1922 scoped_ptr<aura::Window> w1(CreateTestWindow());
1924 wm::ActivateWindow(w1.get());
1925 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType());
1926 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1927 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType());
1930 #if defined(OS_CHROMEOS)
1931 #define MAYBE_StatusAreaHitBoxCoversEdge StatusAreaHitBoxCoversEdge
1933 #define MAYBE_StatusAreaHitBoxCoversEdge DISABLED_StatusAreaHitBoxCoversEdge
1936 // Verify the hit bounds of the status area extend to the edge of the shelf.
1937 TEST_F(ShelfLayoutManagerTest, MAYBE_StatusAreaHitBoxCoversEdge) {
1938 UpdateDisplay("400x400");
1939 ShelfLayoutManager* shelf = GetShelfLayoutManager();
1940 StatusAreaWidget* status_area_widget =
1941 Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
1942 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1943 generator.MoveMouseTo(399,399);
1945 // Test bottom right pixel for bottom alignment.
1946 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1947 generator.ClickLeftButton();
1948 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
1949 generator.ClickLeftButton();
1950 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1952 // Test bottom right pixel for right alignment.
1953 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
1954 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1955 generator.ClickLeftButton();
1956 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
1957 generator.ClickLeftButton();
1958 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1960 // Test bottom left pixel for left alignment.
1961 generator.MoveMouseTo(0, 399);
1962 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
1963 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1964 generator.ClickLeftButton();
1965 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown());
1966 generator.ClickLeftButton();
1967 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown());
1970 } // namespace internal