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. 4 5 #include "ash/shelf/shelf_layout_manager.h" 6 7 #include "ash/accelerators/accelerator_controller.h" 8 #include "ash/accelerators/accelerator_table.h" 9 #include "ash/ash_switches.h" 10 #include "ash/display/display_manager.h" 11 #include "ash/focus_cycler.h" 12 #include "ash/launcher/launcher.h" 13 #include "ash/root_window_controller.h" 14 #include "ash/screen_ash.h" 15 #include "ash/session_state_delegate.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/launcher_test_api.h" 26 #include "ash/wm/window_state.h" 27 #include "ash/wm/window_util.h" 28 #include "base/command_line.h" 29 #include "base/strings/utf_string_conversions.h" 30 #include "ui/aura/client/aura_constants.h" 31 #include "ui/aura/root_window.h" 32 #include "ui/aura/test/event_generator.h" 33 #include "ui/aura/window.h" 34 #include "ui/compositor/layer.h" 35 #include "ui/compositor/layer_animator.h" 36 #include "ui/compositor/scoped_animation_duration_scale_mode.h" 37 #include "ui/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" 44 45 #if defined(OS_WIN) 46 #include "base/win/windows_version.h" 47 #endif 48 49 namespace ash { 50 namespace internal { 51 52 namespace { 53 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)); 59 } 60 61 ShelfWidget* GetShelfWidget() { 62 return Shell::GetPrimaryRootWindowController()->shelf(); 63 } 64 65 ShelfLayoutManager* GetShelfLayoutManager() { 66 return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager(); 67 } 68 69 SystemTray* GetSystemTray() { 70 return Shell::GetPrimaryRootWindowController()->GetSystemTray(); 71 } 72 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 { 76 public: 77 explicit ShelfAnimationWaiter(const gfx::Rect& target_bounds) 78 : target_bounds_(target_bounds), 79 animation_steps_(0), 80 done_waiting_(false) { 81 GetShelfWidget()->AddObserver(this); 82 } 83 84 virtual ~ShelfAnimationWaiter() { 85 GetShelfWidget()->RemoveObserver(this); 86 } 87 88 // Wait till the shelf finishes animating to its expected bounds. 89 void WaitTillDoneAnimating() { 90 if (IsDoneAnimating()) 91 done_waiting_ = true; 92 else 93 base::MessageLoop::current()->Run(); 94 } 95 96 // Returns true if the animation has completed and it was valid. 97 bool WasValidAnimation() const { 98 return done_waiting_ && animation_steps_ > 0; 99 } 100 101 private: 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); 111 } 112 113 // views::WidgetObserver override. 114 virtual void OnWidgetBoundsChanged(views::Widget* widget, 115 const gfx::Rect& new_bounds) OVERRIDE { 116 if (done_waiting_) 117 return; 118 119 ++animation_steps_; 120 if (IsDoneAnimating()) { 121 done_waiting_ = true; 122 base::MessageLoop::current()->Quit(); 123 } 124 } 125 126 gfx::Rect target_bounds_; 127 int animation_steps_; 128 bool done_waiting_; 129 130 DISALLOW_COPY_AND_ASSIGN(ShelfAnimationWaiter); 131 }; 132 133 class ShelfDragCallback { 134 public: 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()); 140 } 141 142 virtual ~ShelfDragCallback() { 143 } 144 145 void ProcessScroll(ui::EventType type, const gfx::Vector2dF& delta) { 146 if (GetShelfLayoutManager()->visibility_state() == ash::SHELF_HIDDEN) 147 return; 148 149 if (type == ui::ET_GESTURE_SCROLL_BEGIN) { 150 scroll_ = gfx::Vector2dF(); 151 was_visible_on_drag_start_ = GetShelfLayoutManager()->IsVisible(); 152 return; 153 } 154 155 // The state of the shelf at the end of the gesture is tested separately. 156 if (type == ui::ET_GESTURE_SCROLL_END) 157 return; 158 159 if (type == ui::ET_GESTURE_SCROLL_UPDATE) 160 scroll_.Add(delta); 161 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()); 174 } 175 176 // if the shelf is being dimmed test dimmer bounds as well. 177 if (GetShelfWidget()->GetDimsShelf()) 178 EXPECT_EQ(GetShelfWidget()->GetWindowBoundsInScreen(), 179 GetShelfWidget()->GetDimmerBoundsForTest()); 180 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( 184 scroll_.y(), 185 scroll_.x()); 186 bool increasing_drag = 187 GetShelfLayoutManager()->SelectValueForShelfAlignment( 188 scroll_delta < 0, 189 scroll_delta > 0, 190 scroll_delta < 0, 191 scroll_delta > 0); 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), 207 abs(scroll_delta)); 208 } else { 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)); 213 } 214 } 215 } else { 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)); 221 } else { 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)); 225 } 226 } 227 } 228 229 private: 230 const gfx::Rect not_visible_bounds_; 231 const gfx::Rect visible_bounds_; 232 gfx::Vector2dF scroll_; 233 bool was_visible_on_drag_start_; 234 235 DISALLOW_COPY_AND_ASSIGN(ShelfDragCallback); 236 }; 237 238 class ShelfLayoutObserverTest : public ShelfLayoutManagerObserver { 239 public: 240 ShelfLayoutObserverTest() 241 : changed_auto_hide_state_(false) { 242 } 243 244 virtual ~ShelfLayoutObserverTest() {} 245 246 bool changed_auto_hide_state() const { return changed_auto_hide_state_; } 247 248 private: 249 virtual void OnAutoHideStateChanged( 250 ShelfAutoHideState new_state) OVERRIDE { 251 changed_auto_hide_state_ = true; 252 } 253 254 bool changed_auto_hide_state_; 255 256 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutObserverTest); 257 }; 258 259 // Trivial item implementation that tracks its views for testing. 260 class TestItem : public SystemTrayItem { 261 public: 262 TestItem() 263 : SystemTrayItem(GetSystemTray()), 264 tray_view_(NULL), 265 default_view_(NULL), 266 detailed_view_(NULL), 267 notification_view_(NULL) {} 268 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(UTF8ToUTF16("Tray"))); 274 return tray_view_; 275 } 276 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(UTF8ToUTF16("Default"))); 281 return default_view_; 282 } 283 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(new views::Label(UTF8ToUTF16("Detailed"))); 288 return detailed_view_; 289 } 290 291 virtual views::View* CreateNotificationView( 292 user::LoginStatus status) OVERRIDE { 293 notification_view_ = new views::View; 294 return notification_view_; 295 } 296 297 virtual void DestroyTrayView() OVERRIDE { 298 tray_view_ = NULL; 299 } 300 301 virtual void DestroyDefaultView() OVERRIDE { 302 default_view_ = NULL; 303 } 304 305 virtual void DestroyDetailedView() OVERRIDE { 306 detailed_view_ = NULL; 307 } 308 309 virtual void DestroyNotificationView() OVERRIDE { 310 notification_view_ = NULL; 311 } 312 313 virtual void UpdateAfterLoginStatusChange( 314 user::LoginStatus status) OVERRIDE {} 315 316 views::View* tray_view() const { return tray_view_; } 317 views::View* default_view() const { return default_view_; } 318 views::View* detailed_view() const { return detailed_view_; } 319 views::View* notification_view() const { return notification_view_; } 320 321 private: 322 views::View* tray_view_; 323 views::View* default_view_; 324 views::View* detailed_view_; 325 views::View* notification_view_; 326 327 DISALLOW_COPY_AND_ASSIGN(TestItem); 328 }; 329 330 } // namespace 331 332 class ShelfLayoutManagerTest : public ash::test::AshTestBase { 333 public: 334 ShelfLayoutManagerTest() {} 335 336 void SetState(ShelfLayoutManager* shelf, 337 ShelfVisibilityState state) { 338 shelf->SetState(state); 339 } 340 341 void UpdateAutoHideStateNow() { 342 GetShelfLayoutManager()->UpdateAutoHideStateNow(); 343 } 344 345 aura::Window* CreateTestWindow() { 346 aura::Window* window = new aura::Window(NULL); 347 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); 348 window->SetType(aura::client::WINDOW_TYPE_NORMAL); 349 window->Init(ui::LAYER_TEXTURED); 350 ParentWindowInPrimaryRootWindow(window); 351 return window; 352 } 353 354 views::Widget* CreateTestWidgetWithParams( 355 const views::Widget::InitParams& params) { 356 views::Widget* out = new views::Widget; 357 out->Init(params); 358 out->Show(); 359 return out; 360 } 361 362 // Create a simple widget attached to the current context (will 363 // delete on TearDown). 364 views::Widget* CreateTestWidget() { 365 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 366 params.bounds = gfx::Rect(0, 0, 200, 200); 367 params.context = CurrentContext(); 368 return CreateTestWidgetWithParams(params); 369 } 370 371 // Overridden from AshTestBase: 372 virtual void SetUp() OVERRIDE { 373 CommandLine::ForCurrentProcess()->AppendSwitch( 374 ash::switches::kAshEnableTrayDragging); 375 test::AshTestBase::SetUp(); 376 } 377 378 void RunGestureDragTests(gfx::Vector2d); 379 380 private: 381 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerTest); 382 }; 383 384 void ShelfLayoutManagerTest::RunGestureDragTests(gfx::Vector2d delta) { 385 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 386 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 387 views::Widget* widget = new views::Widget; 388 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 389 params.bounds = gfx::Rect(0, 0, 200, 200); 390 params.context = CurrentContext(); 391 widget->Init(params); 392 widget->Show(); 393 widget->Maximize(); 394 395 aura::Window* window = widget->GetNativeWindow(); 396 shelf->LayoutShelf(); 397 398 gfx::Rect shelf_shown = GetShelfWidget()->GetWindowBoundsInScreen(); 399 gfx::Rect bounds_shelf = window->bounds(); 400 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 401 402 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 403 shelf->LayoutShelf(); 404 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 405 406 gfx::Rect bounds_noshelf = window->bounds(); 407 gfx::Rect shelf_hidden = GetShelfWidget()->GetWindowBoundsInScreen(); 408 409 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 410 shelf->LayoutShelf(); 411 412 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 413 const int kNumScrollSteps = 4; 414 ShelfDragCallback handler(shelf_hidden, shelf_shown); 415 416 // Swipe up on the shelf. This should not change any state. 417 gfx::Point start = GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint(); 418 gfx::Point end = start + delta; 419 420 // Swipe down on the shelf to hide it. 421 generator.GestureScrollSequenceWithCallback(start, end, 422 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps, 423 base::Bind(&ShelfDragCallback::ProcessScroll, 424 base::Unretained(&handler))); 425 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 426 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 427 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 428 EXPECT_NE(bounds_shelf.ToString(), window->bounds().ToString()); 429 EXPECT_NE(shelf_shown.ToString(), 430 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 431 432 // Swipe up to show the shelf. 433 generator.GestureScrollSequenceWithCallback(end, start, 434 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps, 435 base::Bind(&ShelfDragCallback::ProcessScroll, 436 base::Unretained(&handler))); 437 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 438 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); 439 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString()); 440 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), 441 GetShelfWidget()->GetWindowBoundsInScreen()); 442 EXPECT_EQ(shelf_shown.ToString(), 443 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 444 445 // Swipe up again. The shelf should hide. 446 end = start - delta; 447 generator.GestureScrollSequenceWithCallback(start, end, 448 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps, 449 base::Bind(&ShelfDragCallback::ProcessScroll, 450 base::Unretained(&handler))); 451 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 452 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 453 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 454 EXPECT_EQ(shelf_hidden.ToString(), 455 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 456 457 // Swipe up yet again to show it. 458 end = start + delta; 459 generator.GestureScrollSequenceWithCallback(end, start, 460 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps, 461 base::Bind(&ShelfDragCallback::ProcessScroll, 462 base::Unretained(&handler))); 463 464 // Swipe down very little. It shouldn't change any state. 465 if (GetShelfLayoutManager()->IsHorizontalAlignment()) 466 end.set_y(start.y() + shelf_shown.height() * 3 / 10); 467 else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment()) 468 end.set_x(start.x() - shelf_shown.width() * 3 / 10); 469 else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment()) 470 end.set_x(start.x() + shelf_shown.width() * 3 / 10); 471 generator.GestureScrollSequence(start, end, 472 base::TimeDelta::FromMilliseconds(10), 5); 473 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 474 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); 475 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString()); 476 EXPECT_EQ(shelf_shown.ToString(), 477 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 478 479 // Swipe down again to hide. 480 end = start + delta; 481 generator.GestureScrollSequenceWithCallback(start, end, 482 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps, 483 base::Bind(&ShelfDragCallback::ProcessScroll, 484 base::Unretained(&handler))); 485 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 486 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 487 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 488 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect()); 489 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString()); 490 EXPECT_EQ(shelf_hidden.ToString(), 491 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 492 493 // Swipe up in extended hit region to show it. 494 gfx::Point extended_start = start; 495 if (GetShelfLayoutManager()->IsHorizontalAlignment()) 496 extended_start.set_y(GetShelfWidget()->GetWindowBoundsInScreen().y() -1); 497 else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment()) 498 extended_start.set_x( 499 GetShelfWidget()->GetWindowBoundsInScreen().right() + 1); 500 else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment()) 501 extended_start.set_x(GetShelfWidget()->GetWindowBoundsInScreen().x() - 1); 502 end = extended_start - delta; 503 generator.GestureScrollSequenceWithCallback(extended_start, end, 504 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps, 505 base::Bind(&ShelfDragCallback::ProcessScroll, 506 base::Unretained(&handler))); 507 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 508 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); 509 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString()); 510 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), 511 GetShelfWidget()->GetWindowBoundsInScreen()); 512 EXPECT_EQ(shelf_shown.ToString(), 513 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 514 515 // Swipe down again to hide. 516 end = start + delta; 517 generator.GestureScrollSequenceWithCallback(start, end, 518 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps, 519 base::Bind(&ShelfDragCallback::ProcessScroll, 520 base::Unretained(&handler))); 521 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 522 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 523 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 524 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect()); 525 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString()); 526 EXPECT_EQ(shelf_hidden.ToString(), 527 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 528 529 // Swipe up outside the hit area. This should not change anything. 530 gfx::Point outside_start = gfx::Point( 531 (GetShelfWidget()->GetWindowBoundsInScreen().x() + 532 GetShelfWidget()->GetWindowBoundsInScreen().right())/2, 533 GetShelfWidget()->GetWindowBoundsInScreen().y() - 50); 534 end = outside_start + delta; 535 generator.GestureScrollSequence(outside_start, 536 end, 537 base::TimeDelta::FromMilliseconds(10), 538 kNumScrollSteps); 539 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 540 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 541 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 542 EXPECT_EQ(shelf_hidden.ToString(), 543 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 544 545 // Swipe up from below the shelf where a bezel would be, this should show the 546 // shelf. 547 gfx::Point below_start = start; 548 if (GetShelfLayoutManager()->IsHorizontalAlignment()) 549 below_start.set_y(GetShelfWidget()->GetWindowBoundsInScreen().bottom() + 1); 550 else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment()) 551 below_start.set_x( 552 GetShelfWidget()->GetWindowBoundsInScreen().x() - 1); 553 else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment()) 554 below_start.set_x(GetShelfWidget()->GetWindowBoundsInScreen().right() + 1); 555 end = below_start - delta; 556 generator.GestureScrollSequence(below_start, 557 end, 558 base::TimeDelta::FromMilliseconds(10), 559 kNumScrollSteps); 560 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 561 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); 562 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString()); 563 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), 564 GetShelfWidget()->GetWindowBoundsInScreen()); 565 EXPECT_EQ(shelf_shown.ToString(), 566 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 567 568 // Swipe down again to hide. 569 end = start + delta; 570 generator.GestureScrollSequenceWithCallback(start, end, 571 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps, 572 base::Bind(&ShelfDragCallback::ProcessScroll, 573 base::Unretained(&handler))); 574 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 575 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 576 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 577 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect()); 578 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString()); 579 EXPECT_EQ(shelf_hidden.ToString(), 580 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 581 582 // Put |widget| into fullscreen. Set the shelf to be auto hidden when |widget| 583 // is fullscreen. (eg browser immersive fullscreen). 584 widget->SetFullscreen(true); 585 wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(false); 586 shelf->UpdateVisibilityState(); 587 588 gfx::Rect bounds_fullscreen = window->bounds(); 589 EXPECT_TRUE(widget->IsFullscreen()); 590 EXPECT_NE(bounds_noshelf.ToString(), bounds_fullscreen.ToString()); 591 592 // Swipe up. This should show the shelf. 593 end = below_start - delta; 594 generator.GestureScrollSequenceWithCallback(below_start, end, 595 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps, 596 base::Bind(&ShelfDragCallback::ProcessScroll, 597 base::Unretained(&handler))); 598 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 599 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 600 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); 601 EXPECT_EQ(shelf_shown.ToString(), 602 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 603 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString()); 604 605 // Swipe up again. This should hide the shelf. 606 generator.GestureScrollSequenceWithCallback(below_start, end, 607 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps, 608 base::Bind(&ShelfDragCallback::ProcessScroll, 609 base::Unretained(&handler))); 610 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 611 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 612 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 613 EXPECT_EQ(shelf_hidden.ToString(), 614 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 615 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString()); 616 617 // Set the shelf to be hidden when |widget| is fullscreen. (eg tab fullscreen 618 // with or without immersive browser fullscreen). 619 wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(true); 620 shelf->UpdateVisibilityState(); 621 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); 622 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 623 624 // Swipe-up. This should not change anything. 625 end = start - delta; 626 generator.GestureScrollSequenceWithCallback(below_start, end, 627 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps, 628 base::Bind(&ShelfDragCallback::ProcessScroll, 629 base::Unretained(&handler))); 630 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); 631 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 632 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString()); 633 634 // Close actually, otherwise further event may be affected since widget 635 // is fullscreen status. 636 widget->Close(); 637 RunAllPendingInMessageLoop(); 638 639 // The shelf should be shown because there are no more visible windows. 640 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 641 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 642 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 643 644 // Swipe-up to hide. This should have no effect because there are no visible 645 // windows. 646 end = below_start - delta; 647 generator.GestureScrollSequenceWithCallback(below_start, end, 648 base::TimeDelta::FromMilliseconds(10), kNumScrollSteps, 649 base::Bind(&ShelfDragCallback::ProcessScroll, 650 base::Unretained(&handler))); 651 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 652 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 653 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 654 } 655 656 // Need to be implemented. http://crbug.com/111279. 657 #if defined(OS_WIN) 658 #define MAYBE_SetVisible DISABLED_SetVisible 659 #else 660 #define MAYBE_SetVisible SetVisible 661 #endif 662 // Makes sure SetVisible updates work area and widget appropriately. 663 TEST_F(ShelfLayoutManagerTest, MAYBE_SetVisible) { 664 ShelfWidget* shelf = GetShelfWidget(); 665 ShelfLayoutManager* manager = shelf->shelf_layout_manager(); 666 // Force an initial layout. 667 manager->LayoutShelf(); 668 EXPECT_EQ(SHELF_VISIBLE, manager->visibility_state()); 669 670 gfx::Rect status_bounds( 671 shelf->status_area_widget()->GetWindowBoundsInScreen()); 672 gfx::Rect launcher_bounds( 673 shelf->GetWindowBoundsInScreen()); 674 int shelf_height = manager->GetIdealBounds().height(); 675 gfx::Screen* screen = Shell::GetScreen(); 676 gfx::Display display = screen->GetDisplayNearestWindow( 677 Shell::GetPrimaryRootWindow()); 678 ASSERT_NE(-1, display.id()); 679 // Bottom inset should be the max of widget heights. 680 EXPECT_EQ(shelf_height, display.GetWorkAreaInsets().bottom()); 681 682 // Hide the shelf. 683 SetState(manager, SHELF_HIDDEN); 684 // Run the animation to completion. 685 StepWidgetLayerAnimatorToEnd(shelf); 686 StepWidgetLayerAnimatorToEnd(shelf->status_area_widget()); 687 EXPECT_EQ(SHELF_HIDDEN, manager->visibility_state()); 688 display = screen->GetDisplayNearestWindow( 689 Shell::GetPrimaryRootWindow()); 690 691 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom()); 692 693 // Make sure the bounds of the two widgets changed. 694 EXPECT_GE(shelf->GetNativeView()->bounds().y(), 695 screen->GetPrimaryDisplay().bounds().bottom()); 696 EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(), 697 screen->GetPrimaryDisplay().bounds().bottom()); 698 699 // And show it again. 700 SetState(manager, SHELF_VISIBLE); 701 // Run the animation to completion. 702 StepWidgetLayerAnimatorToEnd(shelf); 703 StepWidgetLayerAnimatorToEnd(shelf->status_area_widget()); 704 EXPECT_EQ(SHELF_VISIBLE, manager->visibility_state()); 705 display = screen->GetDisplayNearestWindow( 706 Shell::GetPrimaryRootWindow()); 707 EXPECT_EQ(shelf_height, display.GetWorkAreaInsets().bottom()); 708 709 // Make sure the bounds of the two widgets changed. 710 launcher_bounds = shelf->GetNativeView()->bounds(); 711 EXPECT_LT(launcher_bounds.y(), 712 screen->GetPrimaryDisplay().bounds().bottom()); 713 status_bounds = shelf->status_area_widget()->GetNativeView()->bounds(); 714 EXPECT_LT(status_bounds.y(), 715 screen->GetPrimaryDisplay().bounds().bottom()); 716 } 717 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()); 727 } 728 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()); 735 736 // Hide the shelf. 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()); 743 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()); 749 } 750 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(); 759 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); 764 765 gfx::Rect current_shelf_bounds = shelf->GetWindowBoundsInScreen(); 766 gfx::Rect current_status_bounds = 767 shelf->status_area_widget()->GetWindowBoundsInScreen(); 768 769 const int small_change = initial_shelf_bounds.height() / 2; 770 EXPECT_LE( 771 std::abs(initial_shelf_bounds.height() - current_shelf_bounds.height()), 772 small_change); 773 EXPECT_LE( 774 std::abs(initial_status_bounds.height() - current_status_bounds.height()), 775 small_change); 776 } 777 778 // Makes sure the launcher is sized when the status area changes size. 779 TEST_F(ShelfLayoutManagerTest, LauncherUpdatedWhenStatusAreaChangesSize) { 780 Launcher* launcher = Launcher::ForPrimaryDisplay(); 781 ASSERT_TRUE(launcher); 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::LauncherTestAPI(launcher).shelf_view()->width()); 789 } 790 791 792 #if defined(OS_WIN) 793 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962 794 #define MAYBE_AutoHide DISABLED_AutoHide 795 #else 796 #define MAYBE_AutoHide AutoHide 797 #endif 798 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); 804 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); 813 widget->Maximize(); 814 widget->Show(); 815 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 816 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 817 818 // LayoutShelf() forces the animation to completion, at which point the 819 // launcher 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()); 826 827 // Move the mouse to the bottom of the screen. 828 generator.MoveMouseTo(0, root->bounds().bottom() - 1); 829 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()); 839 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()); 847 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()); 853 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()); 862 } 863 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()) 868 return; 869 870 UpdateDisplay("800x600,800x600"); 871 DisplayLayout display_layout(DisplayLayout::RIGHT, 0); 872 Shell::GetInstance()->display_manager()->SetLayoutForCurrentDisplays( 873 display_layout); 874 // Put the primary monitor's shelf on the display boundary. 875 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 876 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT); 877 878 // Create a window because the shelf is always shown when no windows are 879 // visible. 880 CreateTestWidget(); 881 882 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 883 ASSERT_EQ(root_windows[0], 884 GetShelfWidget()->GetNativeWindow()->GetRootWindow()); 885 886 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 887 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 888 889 int right_edge = root_windows[0]->GetBoundsInScreen().right() - 1; 890 int y = root_windows[0]->GetBoundsInScreen().y(); 891 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()); 897 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()); 904 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()); 909 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()); 918 919 // Hide the shelf. 920 generator.MoveMouseTo(right_edge - 50, y); 921 UpdateAutoHideStateNow(); 922 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 923 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()); 930 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()); 937 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()); 943 944 // Moving the mouse far from the left edge of the secondary display should 945 // hide the shelf. 946 generator.MoveMouseTo(right_edge + 50, y); 947 UpdateAutoHideStateNow(); 948 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 949 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()); 955 } 956 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); 964 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); 973 widget->Maximize(); 974 widget->Show(); 975 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 976 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 977 978 aura::Window* root = Shell::GetPrimaryRootWindow(); 979 // LayoutShelf() forces the animation to completion, at which point the 980 // launcher should go off the screen. 981 shelf->LayoutShelf(); 982 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, 983 GetShelfWidget()->GetWindowBoundsInScreen().y()); 984 985 aura::Window* lock_container = Shell::GetContainer( 986 Shell::GetPrimaryRootWindow(), 987 internal::kShellWindowId_LockScreenContainer); 988 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(); 998 lock_widget->Show(); 999 1000 // Lock the screen. 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()); 1005 1006 Shell::GetInstance()->session_state_delegate()->UnlockScreen(); 1007 shelf->UpdateVisibilityState(); 1008 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1009 } 1010 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); 1018 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); 1026 widget->Show(); 1027 aura::Window* window = widget->GetNativeWindow(); 1028 gfx::Rect display_bounds( 1029 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds()); 1030 1031 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1032 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1033 1034 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1035 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1036 1037 widget->Maximize(); 1038 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1039 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow( 1040 window).work_area().bottom(), 1041 widget->GetWorkAreaBoundsInScreen().bottom()); 1042 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()); 1048 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()); 1054 } 1055 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); 1063 1064 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1065 shelf->shelf_widget()->DisableDimmingAnimationsForTest(); 1066 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); 1073 widget->Show(); 1074 aura::Window* window = widget->GetNativeWindow(); 1075 gfx::Rect display_bounds( 1076 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds()); 1077 1078 gfx::Point off_shelf = display_bounds.CenterPoint(); 1079 gfx::Point on_shelf = 1080 shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint(); 1081 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()); 1087 1088 // After maximization, the shelf should be visible and the dimmer created. 1089 widget->Maximize(); 1090 1091 on_shelf = shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint(); 1092 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1093 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()); 1097 1098 // Adding touch events outside the shelf should still keep the shelf in 1099 // dimmed state. 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()); 1109 1110 // Moving the mouse on the shelf should undim the bar. 1111 generator.MoveMouseTo(on_shelf); 1112 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1113 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(); 1124 1125 // After restore, the dimming object should be deleted again. 1126 widget->Restore(); 1127 EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1128 } 1129 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); 1137 1138 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1139 shelf->shelf_widget()->DisableDimmingAnimationsForTest(); 1140 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); 1147 widget->Show(); 1148 aura::Window* window = widget->GetNativeWindow(); 1149 gfx::Rect display_bounds( 1150 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds()); 1151 1152 // After maximization, the shelf should be visible and the dimmer created. 1153 widget->Maximize(); 1154 1155 gfx::Point off_shelf = display_bounds.CenterPoint(); 1156 gfx::Point on_shelf = 1157 shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint(); 1158 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()); 1162 1163 // Simulate a menu opening. 1164 shelf->shelf_widget()->ForceUndimming(true); 1165 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()); 1169 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()); 1180 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()); 1185 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()); 1198 } 1199 1200 // Verifies the shelf is visible when status/launcher is focused. 1201 TEST_F(ShelfLayoutManagerTest, VisibleWhenStatusOrLauncherFocused) { 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); 1207 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); 1215 widget->Show(); 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()); 1219 1220 // Focus the launcher. 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()); 1224 1225 widget->Activate(); 1226 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1227 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()); 1232 1233 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD); 1234 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1235 } 1236 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); 1245 1246 // Create a normal unmaximized windowm shelf should be visible. 1247 aura::Window* window = CreateTestWindow(); 1248 window->SetBounds(gfx::Rect(0, 0, 100, 100)); 1249 window->Show(); 1250 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 1251 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1252 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()); 1257 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()); 1262 } 1263 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); 1272 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); 1277 window->Show(); 1278 wm::ActivateWindow(window); 1279 1280 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 1281 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1282 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()); 1292 1293 // Toggle app list to hide. 1294 shell->ToggleAppList(NULL); 1295 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 1296 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1297 } 1298 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(); 1306 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); 1311 window->Show(); 1312 wm::ActivateWindow(window); 1313 1314 // App list and shelf is not shown. 1315 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 1316 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); 1317 1318 // Toggle app list to show. 1319 shell->ToggleAppList(NULL); 1320 EXPECT_TRUE(shell->GetAppListTargetVisibility()); 1321 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); 1322 1323 // Toggle app list to hide. 1324 shell->ToggleAppList(NULL); 1325 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 1326 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); 1327 } 1328 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(); 1333 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); 1338 window1->Show(); 1339 1340 aura::Window* window2 = CreateTestWindow(); 1341 window2->SetBounds(gfx::Rect(0, 0, 100, 100)); 1342 window2->Show(); 1343 1344 wm::GetWindowState(window1)->Activate(); 1345 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); 1346 1347 wm::GetWindowState(window2)->Activate(); 1348 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1349 1350 wm::GetWindowState(window1)->Activate(); 1351 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); 1352 } 1353 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()) 1358 return; 1359 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(); 1365 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); 1372 window1->Show(); 1373 1374 aura::Window* window2 = CreateTestWindow(); 1375 window2->SetBoundsInScreen( 1376 gfx::Rect(800, 0, 100, 100), 1377 display_manager->GetDisplayAt(1)); 1378 window2->Show(); 1379 1380 EXPECT_EQ(root_windows[0], window1->GetRootWindow()); 1381 EXPECT_EQ(root_windows[1], window2->GetRootWindow()); 1382 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()); 1388 } 1389 1390 1391 #if defined(OS_WIN) 1392 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962 1393 #define MAYBE_SetAlignment DISABLED_SetAlignment 1394 #else 1395 #define MAYBE_SetAlignment SetAlignment 1396 #endif 1397 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()); 1405 1406 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT); 1407 gfx::Rect launcher_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()); 1415 EXPECT_GE( 1416 launcher_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(), launcher_bounds.x()); 1429 EXPECT_EQ(display.bounds().y(), launcher_bounds.y()); 1430 EXPECT_EQ(display.bounds().height(), launcher_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()); 1436 1437 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1438 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT); 1439 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); 1440 launcher_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(launcher_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(), launcher_bounds.x()); 1457 EXPECT_EQ(display.bounds().y(), launcher_bounds.y()); 1458 EXPECT_EQ(display.bounds().height(), launcher_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()); 1465 1466 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1467 shelf->SetAlignment(SHELF_ALIGNMENT_TOP); 1468 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); 1469 launcher_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(launcher_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(), launcher_bounds.bottom()); 1486 EXPECT_EQ(display.bounds().x(), launcher_bounds.x()); 1487 EXPECT_EQ(display.bounds().width(), launcher_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()); 1494 } 1495 1496 #if defined(OS_WIN) 1497 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962 1498 #define MAYBE_GestureDrag DISABLED_GestureDrag 1499 #else 1500 #define MAYBE_GestureDrag GestureDrag 1501 #endif 1502 1503 TEST_F(ShelfLayoutManagerTest, MAYBE_GestureDrag) { 1504 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1505 { 1506 SCOPED_TRACE("BOTTOM"); 1507 RunGestureDragTests(gfx::Vector2d(0, 120)); 1508 } 1509 1510 { 1511 SCOPED_TRACE("LEFT"); 1512 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT); 1513 RunGestureDragTests(gfx::Vector2d(-120, 0)); 1514 } 1515 1516 { 1517 SCOPED_TRACE("RIGHT"); 1518 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT); 1519 RunGestureDragTests(gfx::Vector2d(120, 0)); 1520 } 1521 } 1522 1523 TEST_F(ShelfLayoutManagerTest, WindowVisibilityDisablesAutoHide) { 1524 if (!SupportsMultipleDisplays()) 1525 return; 1526 1527 UpdateDisplay("800x600,800x600"); 1528 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1529 shelf->LayoutShelf(); 1530 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1531 1532 // Create a visible window so auto-hide behavior is enforced 1533 views::Widget* dummy = CreateTestWidget(); 1534 1535 // Window visible => auto hide behaves normally. 1536 shelf->UpdateVisibilityState(); 1537 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1538 1539 // Window minimized => auto hide disabled. 1540 dummy->Minimize(); 1541 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1542 1543 // Window closed => auto hide disabled. 1544 dummy->CloseNow(); 1545 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1546 1547 // Multiple window test 1548 views::Widget* window1 = CreateTestWidget(); 1549 views::Widget* window2 = CreateTestWidget(); 1550 1551 // both visible => normal autohide 1552 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1553 1554 // either minimzed => normal autohide 1555 window2->Minimize(); 1556 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1557 window2->Restore(); 1558 window1->Minimize(); 1559 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1560 1561 // both minimized => disable auto hide 1562 window2->Minimize(); 1563 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1564 1565 // Test moving windows to/from other display. 1566 window2->Restore(); 1567 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1568 // Move to second display. 1569 window2->SetBounds(gfx::Rect(850, 50, 50, 50)); 1570 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1571 // Move back to primary display. 1572 window2->SetBounds(gfx::Rect(50, 50, 50, 50)); 1573 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1574 } 1575 1576 // Test that the shelf animates back to its normal position upon a user 1577 // completing a gesture drag. 1578 TEST_F(ShelfLayoutManagerTest, ShelfAnimatesWhenGestureComplete) { 1579 if (!SupportsHostWindowResize()) 1580 return; 1581 1582 // Test the shelf animates back to its original visible bounds when it is 1583 // dragged when there are no visible windows. 1584 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1585 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1586 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1587 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1588 gfx::Rect visible_bounds = GetShelfWidget()->GetWindowBoundsInScreen(); 1589 { 1590 // Enable animations so that we can make sure that they occur. 1591 ui::ScopedAnimationDurationScaleMode regular_animations( 1592 ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION); 1593 1594 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 1595 gfx::Rect shelf_bounds_in_screen = 1596 GetShelfWidget()->GetWindowBoundsInScreen(); 1597 gfx::Point start(shelf_bounds_in_screen.CenterPoint()); 1598 gfx::Point end(start.x(), shelf_bounds_in_screen.bottom()); 1599 generator.GestureScrollSequence(start, end, 1600 base::TimeDelta::FromMilliseconds(10), 5); 1601 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1602 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1603 1604 ShelfAnimationWaiter waiter(visible_bounds); 1605 // Wait till the animation completes and check that it occurred. 1606 waiter.WaitTillDoneAnimating(); 1607 EXPECT_TRUE(waiter.WasValidAnimation()); 1608 } 1609 1610 // Create a visible window so auto-hide behavior is enforced. 1611 CreateTestWidget(); 1612 1613 // Get the bounds of the shelf when it is hidden. 1614 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1615 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1616 gfx::Rect auto_hidden_bounds = GetShelfWidget()->GetWindowBoundsInScreen(); 1617 1618 { 1619 // Enable the animations so that we can make sure they do occur. 1620 ui::ScopedAnimationDurationScaleMode regular_animations( 1621 ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION); 1622 1623 gfx::Point start = 1624 GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint(); 1625 gfx::Point end(start.x(), start.y() - 100); 1626 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 1627 1628 // Test that the shelf animates to the visible bounds after a swipe up on 1629 // the auto hidden shelf. 1630 generator.GestureScrollSequence(start, end, 1631 base::TimeDelta::FromMilliseconds(10), 1); 1632 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1633 ShelfAnimationWaiter waiter1(visible_bounds); 1634 waiter1.WaitTillDoneAnimating(); 1635 EXPECT_TRUE(waiter1.WasValidAnimation()); 1636 1637 // Test that the shelf animates to the auto hidden bounds after a swipe up 1638 // on the visible shelf. 1639 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1640 generator.GestureScrollSequence(start, end, 1641 base::TimeDelta::FromMilliseconds(10), 1); 1642 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1643 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1644 ShelfAnimationWaiter waiter2(auto_hidden_bounds); 1645 waiter2.WaitTillDoneAnimating(); 1646 EXPECT_TRUE(waiter2.WasValidAnimation()); 1647 } 1648 } 1649 1650 TEST_F(ShelfLayoutManagerTest, GestureRevealsTrayBubble) { 1651 if (!SupportsHostWindowResize()) 1652 return; 1653 1654 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1655 shelf->LayoutShelf(); 1656 1657 // Create a visible window so auto-hide behavior is enforced. 1658 CreateTestWidget(); 1659 1660 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 1661 SystemTray* tray = GetSystemTray(); 1662 1663 // First, make sure the shelf is visible. 1664 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1665 EXPECT_FALSE(tray->HasSystemBubble()); 1666 1667 // Now, drag up on the tray to show the bubble. 1668 gfx::Point start = GetShelfWidget()->status_area_widget()-> 1669 GetWindowBoundsInScreen().CenterPoint(); 1670 gfx::Point end(start.x(), start.y() - 100); 1671 generator.GestureScrollSequence(start, end, 1672 base::TimeDelta::FromMilliseconds(10), 1); 1673 EXPECT_TRUE(tray->HasSystemBubble()); 1674 tray->CloseSystemBubble(); 1675 RunAllPendingInMessageLoop(); 1676 EXPECT_FALSE(tray->HasSystemBubble()); 1677 1678 // Drag again, but only a small amount, and slowly. The bubble should not be 1679 // visible. 1680 end.set_y(start.y() - 30); 1681 generator.GestureScrollSequence(start, end, 1682 base::TimeDelta::FromMilliseconds(500), 100); 1683 EXPECT_FALSE(tray->HasSystemBubble()); 1684 1685 // Now, hide the shelf. 1686 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1687 1688 // Start a drag from the bezel, and drag up to show both the shelf and the 1689 // tray bubble. 1690 start.set_y(start.y() + 100); 1691 end.set_y(start.y() - 400); 1692 generator.GestureScrollSequence(start, end, 1693 base::TimeDelta::FromMilliseconds(10), 1); 1694 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1695 EXPECT_TRUE(tray->HasSystemBubble()); 1696 } 1697 1698 TEST_F(ShelfLayoutManagerTest, ShelfFlickerOnTrayActivation) { 1699 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1700 1701 // Create a visible window so auto-hide behavior is enforced. 1702 CreateTestWidget(); 1703 1704 // Turn on auto-hide for the shelf. 1705 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1706 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1707 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1708 1709 // Show the status menu. That should make the shelf visible again. 1710 Shell::GetInstance()->accelerator_controller()->PerformAction( 1711 SHOW_SYSTEM_TRAY_BUBBLE, ui::Accelerator()); 1712 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1713 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1714 EXPECT_TRUE(GetSystemTray()->HasSystemBubble()); 1715 } 1716 1717 TEST_F(ShelfLayoutManagerTest, WorkAreaChangeWorkspace) { 1718 // Make sure the shelf is always visible. 1719 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1720 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1721 shelf->LayoutShelf(); 1722 1723 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 1724 params.bounds = gfx::Rect(0, 0, 200, 200); 1725 params.context = CurrentContext(); 1726 views::Widget* widget_one = CreateTestWidgetWithParams(params); 1727 widget_one->Maximize(); 1728 1729 views::Widget* widget_two = CreateTestWidgetWithParams(params); 1730 widget_two->Maximize(); 1731 widget_two->Activate(); 1732 1733 // Both windows are maximized. They should be of the same size. 1734 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(), 1735 widget_two->GetNativeWindow()->bounds().ToString()); 1736 int area_when_shelf_shown = 1737 widget_one->GetNativeWindow()->bounds().size().GetArea(); 1738 1739 // Now hide the shelf. 1740 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1741 1742 // Both windows should be resized according to the shelf status. 1743 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(), 1744 widget_two->GetNativeWindow()->bounds().ToString()); 1745 // Resized to small. 1746 EXPECT_LT(area_when_shelf_shown, 1747 widget_one->GetNativeWindow()->bounds().size().GetArea()); 1748 1749 // Now show the shelf. 1750 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1751 1752 // Again both windows should be of the same size. 1753 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(), 1754 widget_two->GetNativeWindow()->bounds().ToString()); 1755 EXPECT_EQ(area_when_shelf_shown, 1756 widget_one->GetNativeWindow()->bounds().size().GetArea()); 1757 } 1758 1759 // Confirm that the shelf is dimmed only when content is maximized and 1760 // shelf is not autohidden. 1761 TEST_F(ShelfLayoutManagerTest, Dimming) { 1762 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1763 scoped_ptr<aura::Window> w1(CreateTestWindow()); 1764 w1->Show(); 1765 wm::ActivateWindow(w1.get()); 1766 1767 // Normal window doesn't dim shelf. 1768 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); 1769 ShelfWidget* shelf = GetShelfWidget(); 1770 EXPECT_FALSE(shelf->GetDimsShelf()); 1771 1772 // Maximized window does. 1773 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); 1774 EXPECT_TRUE(shelf->GetDimsShelf()); 1775 1776 // Change back to normal stops dimming. 1777 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); 1778 EXPECT_FALSE(shelf->GetDimsShelf()); 1779 1780 // Changing back to maximized dims again. 1781 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); 1782 EXPECT_TRUE(shelf->GetDimsShelf()); 1783 1784 // Changing shelf to autohide stops dimming. 1785 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1786 EXPECT_FALSE(shelf->GetDimsShelf()); 1787 } 1788 1789 // Make sure that the shelf will not hide if the mouse is between a bubble and 1790 // the shelf. 1791 TEST_F(ShelfLayoutManagerTest, BubbleEnlargesShelfMouseHitArea) { 1792 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1793 StatusAreaWidget* status_area_widget = 1794 Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget(); 1795 SystemTray* tray = GetSystemTray(); 1796 1797 // Create a visible window so auto-hide behavior is enforced. 1798 CreateTestWidget(); 1799 1800 shelf->LayoutShelf(); 1801 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 1802 1803 // Make two iterations - first without a message bubble which should make 1804 // the shelf disappear and then with a message bubble which should keep it 1805 // visible. 1806 for (int i = 0; i < 2; i++) { 1807 // Make sure the shelf is visible and position the mouse over it. Then 1808 // allow auto hide. 1809 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1810 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1811 gfx::Point center = 1812 status_area_widget->GetWindowBoundsInScreen().CenterPoint(); 1813 generator.MoveMouseTo(center.x(), center.y()); 1814 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1815 EXPECT_TRUE(shelf->IsVisible()); 1816 if (!i) { 1817 // In our first iteration we make sure there is no bubble. 1818 tray->CloseSystemBubble(); 1819 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1820 } else { 1821 // In our second iteration we show a bubble. 1822 TestItem *item = new TestItem; 1823 tray->AddTrayItem(item); 1824 tray->ShowNotificationView(item); 1825 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown()); 1826 } 1827 // Move the pointer over the edge of the shelf. 1828 generator.MoveMouseTo( 1829 center.x(), status_area_widget->GetWindowBoundsInScreen().y() - 8); 1830 shelf->UpdateVisibilityState(); 1831 if (i) { 1832 EXPECT_TRUE(shelf->IsVisible()); 1833 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown()); 1834 } else { 1835 EXPECT_FALSE(shelf->IsVisible()); 1836 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1837 } 1838 } 1839 } 1840 1841 TEST_F(ShelfLayoutManagerTest, ShelfBackgroundColor) { 1842 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType()); 1843 1844 scoped_ptr<aura::Window> w1(CreateTestWindow()); 1845 w1->Show(); 1846 wm::ActivateWindow(w1.get()); 1847 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType()); 1848 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); 1849 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType()); 1850 1851 scoped_ptr<aura::Window> w2(CreateTestWindow()); 1852 w2->Show(); 1853 wm::ActivateWindow(w2.get()); 1854 // Overlaps with shelf. 1855 w2->SetBounds(GetShelfLayoutManager()->GetIdealBounds()); 1856 1857 // Still background is 'maximized'. 1858 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType()); 1859 1860 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); 1861 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType()); 1862 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); 1863 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType()); 1864 1865 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); 1866 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType()); 1867 w1.reset(); 1868 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType()); 1869 } 1870 1871 // Verify that the shelf doesn't have the opaque background if it's auto-hide 1872 // status. 1873 TEST_F(ShelfLayoutManagerTest, ShelfBackgroundColorAutoHide) { 1874 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget ()->GetBackgroundType()); 1875 1876 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1877 scoped_ptr<aura::Window> w1(CreateTestWindow()); 1878 w1->Show(); 1879 wm::ActivateWindow(w1.get()); 1880 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType()); 1881 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); 1882 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType()); 1883 } 1884 1885 #if defined(OS_CHROMEOS) 1886 #define MAYBE_StatusAreaHitBoxCoversEdge StatusAreaHitBoxCoversEdge 1887 #else 1888 #define MAYBE_StatusAreaHitBoxCoversEdge DISABLED_StatusAreaHitBoxCoversEdge 1889 #endif 1890 1891 // Verify the hit bounds of the status area extend to the edge of the shelf. 1892 TEST_F(ShelfLayoutManagerTest, MAYBE_StatusAreaHitBoxCoversEdge) { 1893 UpdateDisplay("400x400"); 1894 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1895 StatusAreaWidget* status_area_widget = 1896 Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget(); 1897 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 1898 generator.MoveMouseTo(399,399); 1899 1900 // Test bottom right pixel for bottom alignment. 1901 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1902 generator.ClickLeftButton(); 1903 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown()); 1904 generator.ClickLeftButton(); 1905 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1906 1907 // Test bottom right pixel for right alignment. 1908 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT); 1909 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1910 generator.ClickLeftButton(); 1911 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown()); 1912 generator.ClickLeftButton(); 1913 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1914 1915 // Test bottom left pixel for left alignment. 1916 generator.MoveMouseTo(0, 399); 1917 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT); 1918 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1919 generator.ClickLeftButton(); 1920 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown()); 1921 generator.ClickLeftButton(); 1922 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1923 } 1924 1925 } // namespace internal 1926 } // namespace ash 1927