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/root_window_controller.h" 13 #include "ash/session/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/window.h" 31 #include "ui/aura/window_event_dispatcher.h" 32 #include "ui/compositor/layer.h" 33 #include "ui/compositor/layer_animator.h" 34 #include "ui/compositor/scoped_animation_duration_scale_mode.h" 35 #include "ui/events/gestures/gesture_configuration.h" 36 #include "ui/events/test/event_generator.h" 37 #include "ui/gfx/display.h" 38 #include "ui/gfx/screen.h" 39 #include "ui/views/controls/label.h" 40 #include "ui/views/layout/fill_layout.h" 41 #include "ui/views/view.h" 42 #include "ui/views/widget/widget.h" 43 44 #if defined(OS_WIN) 45 #include "base/win/windows_version.h" 46 #endif 47 48 namespace ash { 49 namespace { 50 51 void StepWidgetLayerAnimatorToEnd(views::Widget* widget) { 52 widget->GetNativeView()->layer()->GetAnimator()->Step( 53 base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1)); 54 } 55 56 ShelfWidget* GetShelfWidget() { 57 return Shell::GetPrimaryRootWindowController()->shelf(); 58 } 59 60 ShelfLayoutManager* GetShelfLayoutManager() { 61 return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager(); 62 } 63 64 SystemTray* GetSystemTray() { 65 return Shell::GetPrimaryRootWindowController()->GetSystemTray(); 66 } 67 68 // Class which waits till the shelf finishes animating to the target size and 69 // counts the number of animation steps. 70 class ShelfAnimationWaiter : views::WidgetObserver { 71 public: 72 explicit ShelfAnimationWaiter(const gfx::Rect& target_bounds) 73 : target_bounds_(target_bounds), 74 animation_steps_(0), 75 done_waiting_(false) { 76 GetShelfWidget()->AddObserver(this); 77 } 78 79 virtual ~ShelfAnimationWaiter() { 80 GetShelfWidget()->RemoveObserver(this); 81 } 82 83 // Wait till the shelf finishes animating to its expected bounds. 84 void WaitTillDoneAnimating() { 85 if (IsDoneAnimating()) 86 done_waiting_ = true; 87 else 88 base::MessageLoop::current()->Run(); 89 } 90 91 // Returns true if the animation has completed and it was valid. 92 bool WasValidAnimation() const { 93 return done_waiting_ && animation_steps_ > 0; 94 } 95 96 private: 97 // Returns true if shelf has finished animating to the target size. 98 bool IsDoneAnimating() const { 99 ShelfLayoutManager* layout_manager = GetShelfLayoutManager(); 100 gfx::Rect current_bounds = GetShelfWidget()->GetWindowBoundsInScreen(); 101 int size = layout_manager->PrimaryAxisValue(current_bounds.height(), 102 current_bounds.width()); 103 int desired_size = layout_manager->PrimaryAxisValue(target_bounds_.height(), 104 target_bounds_.width()); 105 return (size == desired_size); 106 } 107 108 // views::WidgetObserver override. 109 virtual void OnWidgetBoundsChanged(views::Widget* widget, 110 const gfx::Rect& new_bounds) OVERRIDE { 111 if (done_waiting_) 112 return; 113 114 ++animation_steps_; 115 if (IsDoneAnimating()) { 116 done_waiting_ = true; 117 base::MessageLoop::current()->Quit(); 118 } 119 } 120 121 gfx::Rect target_bounds_; 122 int animation_steps_; 123 bool done_waiting_; 124 125 DISALLOW_COPY_AND_ASSIGN(ShelfAnimationWaiter); 126 }; 127 128 class ShelfDragCallback { 129 public: 130 ShelfDragCallback(const gfx::Rect& not_visible, const gfx::Rect& visible) 131 : not_visible_bounds_(not_visible), 132 visible_bounds_(visible), 133 was_visible_on_drag_start_(false) { 134 EXPECT_EQ(not_visible_bounds_.bottom(), visible_bounds_.bottom()); 135 } 136 137 virtual ~ShelfDragCallback() { 138 } 139 140 void ProcessScroll(ui::EventType type, const gfx::Vector2dF& delta) { 141 if (GetShelfLayoutManager()->visibility_state() == ash::SHELF_HIDDEN) 142 return; 143 144 if (type == ui::ET_GESTURE_SCROLL_BEGIN) { 145 scroll_ = gfx::Vector2dF(); 146 was_visible_on_drag_start_ = GetShelfLayoutManager()->IsVisible(); 147 return; 148 } 149 150 // The state of the shelf at the end of the gesture is tested separately. 151 if (type == ui::ET_GESTURE_SCROLL_END) 152 return; 153 154 if (type == ui::ET_GESTURE_SCROLL_UPDATE) 155 scroll_.Add(delta); 156 157 gfx::Rect shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen(); 158 if (GetShelfLayoutManager()->IsHorizontalAlignment()) { 159 EXPECT_EQ(not_visible_bounds_.bottom(), shelf_bounds.bottom()); 160 EXPECT_EQ(visible_bounds_.bottom(), shelf_bounds.bottom()); 161 } else if (SHELF_ALIGNMENT_RIGHT == 162 GetShelfLayoutManager()->GetAlignment()){ 163 EXPECT_EQ(not_visible_bounds_.right(), shelf_bounds.right()); 164 EXPECT_EQ(visible_bounds_.right(), shelf_bounds.right()); 165 } else if (SHELF_ALIGNMENT_LEFT == 166 GetShelfLayoutManager()->GetAlignment()) { 167 EXPECT_EQ(not_visible_bounds_.x(), shelf_bounds.x()); 168 EXPECT_EQ(visible_bounds_.x(), shelf_bounds.x()); 169 } 170 171 // if the shelf is being dimmed test dimmer bounds as well. 172 if (GetShelfWidget()->GetDimsShelf()) 173 EXPECT_EQ(GetShelfWidget()->GetWindowBoundsInScreen(), 174 GetShelfWidget()->GetDimmerBoundsForTest()); 175 176 // The shelf should never be smaller than the hidden state. 177 EXPECT_GE(shelf_bounds.height(), not_visible_bounds_.height()); 178 float scroll_delta = GetShelfLayoutManager()->PrimaryAxisValue( 179 scroll_.y(), 180 scroll_.x()); 181 bool increasing_drag = 182 GetShelfLayoutManager()->SelectValueForShelfAlignment( 183 scroll_delta < 0, 184 scroll_delta > 0, 185 scroll_delta < 0, 186 scroll_delta > 0); 187 int shelf_size = GetShelfLayoutManager()->PrimaryAxisValue( 188 shelf_bounds.height(), 189 shelf_bounds.width()); 190 int visible_bounds_size = GetShelfLayoutManager()->PrimaryAxisValue( 191 visible_bounds_.height(), 192 visible_bounds_.width()); 193 int not_visible_bounds_size = GetShelfLayoutManager()->PrimaryAxisValue( 194 not_visible_bounds_.height(), 195 not_visible_bounds_.width()); 196 if (was_visible_on_drag_start_) { 197 if (increasing_drag) { 198 // If dragging inwards from the visible state, then the shelf should 199 // increase in size, but not more than the scroll delta. 200 EXPECT_LE(visible_bounds_size, shelf_size); 201 EXPECT_LE(std::abs(shelf_size - visible_bounds_size), 202 std::abs(scroll_delta)); 203 } else { 204 if (shelf_size > not_visible_bounds_size) { 205 // If dragging outwards from the visible state, then the shelf 206 // should decrease in size, until it reaches the minimum size. 207 EXPECT_EQ(shelf_size, visible_bounds_size - std::abs(scroll_delta)); 208 } 209 } 210 } else { 211 if (std::abs(scroll_delta) < 212 visible_bounds_size - not_visible_bounds_size) { 213 // Tests that the shelf sticks with the touch point during the drag 214 // until the shelf is completely visible. 215 EXPECT_EQ(shelf_size, not_visible_bounds_size + std::abs(scroll_delta)); 216 } else { 217 // Tests that after the shelf is completely visible, the shelf starts 218 // resisting the drag. 219 EXPECT_LT(shelf_size, not_visible_bounds_size + std::abs(scroll_delta)); 220 } 221 } 222 } 223 224 private: 225 const gfx::Rect not_visible_bounds_; 226 const gfx::Rect visible_bounds_; 227 gfx::Vector2dF scroll_; 228 bool was_visible_on_drag_start_; 229 230 DISALLOW_COPY_AND_ASSIGN(ShelfDragCallback); 231 }; 232 233 class ShelfLayoutObserverTest : public ShelfLayoutManagerObserver { 234 public: 235 ShelfLayoutObserverTest() 236 : changed_auto_hide_state_(false) { 237 } 238 239 virtual ~ShelfLayoutObserverTest() {} 240 241 bool changed_auto_hide_state() const { return changed_auto_hide_state_; } 242 243 private: 244 virtual void OnAutoHideStateChanged( 245 ShelfAutoHideState new_state) OVERRIDE { 246 changed_auto_hide_state_ = true; 247 } 248 249 bool changed_auto_hide_state_; 250 251 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutObserverTest); 252 }; 253 254 // Trivial item implementation that tracks its views for testing. 255 class TestItem : public SystemTrayItem { 256 public: 257 TestItem() 258 : SystemTrayItem(GetSystemTray()), 259 tray_view_(NULL), 260 default_view_(NULL), 261 detailed_view_(NULL), 262 notification_view_(NULL) {} 263 264 virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE { 265 tray_view_ = new views::View; 266 // Add a label so it has non-zero width. 267 tray_view_->SetLayoutManager(new views::FillLayout); 268 tray_view_->AddChildView(new views::Label(base::UTF8ToUTF16("Tray"))); 269 return tray_view_; 270 } 271 272 virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE { 273 default_view_ = new views::View; 274 default_view_->SetLayoutManager(new views::FillLayout); 275 default_view_->AddChildView(new views::Label(base::UTF8ToUTF16("Default"))); 276 return default_view_; 277 } 278 279 virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE { 280 detailed_view_ = new views::View; 281 detailed_view_->SetLayoutManager(new views::FillLayout); 282 detailed_view_->AddChildView( 283 new views::Label(base::UTF8ToUTF16("Detailed"))); 284 return detailed_view_; 285 } 286 287 virtual views::View* CreateNotificationView( 288 user::LoginStatus status) OVERRIDE { 289 notification_view_ = new views::View; 290 return notification_view_; 291 } 292 293 virtual void DestroyTrayView() OVERRIDE { 294 tray_view_ = NULL; 295 } 296 297 virtual void DestroyDefaultView() OVERRIDE { 298 default_view_ = NULL; 299 } 300 301 virtual void DestroyDetailedView() OVERRIDE { 302 detailed_view_ = NULL; 303 } 304 305 virtual void DestroyNotificationView() OVERRIDE { 306 notification_view_ = NULL; 307 } 308 309 virtual void UpdateAfterLoginStatusChange( 310 user::LoginStatus status) OVERRIDE {} 311 312 views::View* tray_view() const { return tray_view_; } 313 views::View* default_view() const { return default_view_; } 314 views::View* detailed_view() const { return detailed_view_; } 315 views::View* notification_view() const { return notification_view_; } 316 317 private: 318 views::View* tray_view_; 319 views::View* default_view_; 320 views::View* detailed_view_; 321 views::View* notification_view_; 322 323 DISALLOW_COPY_AND_ASSIGN(TestItem); 324 }; 325 326 } // namespace 327 328 class ShelfLayoutManagerTest : public ash::test::AshTestBase { 329 public: 330 ShelfLayoutManagerTest() {} 331 332 void SetState(ShelfLayoutManager* shelf, 333 ShelfVisibilityState state) { 334 shelf->SetState(state); 335 } 336 337 void UpdateAutoHideStateNow() { 338 GetShelfLayoutManager()->UpdateAutoHideStateNow(); 339 } 340 341 aura::Window* CreateTestWindow() { 342 aura::Window* window = new aura::Window(NULL); 343 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); 344 window->SetType(ui::wm::WINDOW_TYPE_NORMAL); 345 window->Init(aura::WINDOW_LAYER_TEXTURED); 346 ParentWindowInPrimaryRootWindow(window); 347 return window; 348 } 349 350 views::Widget* CreateTestWidgetWithParams( 351 const views::Widget::InitParams& params) { 352 views::Widget* out = new views::Widget; 353 out->Init(params); 354 out->Show(); 355 return out; 356 } 357 358 // Create a simple widget attached to the current context (will 359 // delete on TearDown). 360 views::Widget* CreateTestWidget() { 361 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 362 params.bounds = gfx::Rect(0, 0, 200, 200); 363 params.context = CurrentContext(); 364 return CreateTestWidgetWithParams(params); 365 } 366 367 // Overridden from AshTestBase: 368 virtual void SetUp() OVERRIDE { 369 CommandLine::ForCurrentProcess()->AppendSwitch( 370 ash::switches::kAshEnableTrayDragging); 371 test::AshTestBase::SetUp(); 372 } 373 374 void RunGestureDragTests(gfx::Vector2d); 375 376 private: 377 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerTest); 378 }; 379 380 void ShelfLayoutManagerTest::RunGestureDragTests(gfx::Vector2d delta) { 381 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 382 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 383 views::Widget* widget = new views::Widget; 384 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 385 params.bounds = gfx::Rect(0, 0, 200, 200); 386 params.context = CurrentContext(); 387 widget->Init(params); 388 widget->Show(); 389 widget->Maximize(); 390 391 // The time delta should be large enough to prevent accidental fling creation. 392 const base::TimeDelta kTimeDelta = base::TimeDelta::FromMilliseconds(100); 393 394 aura::Window* window = widget->GetNativeWindow(); 395 shelf->LayoutShelf(); 396 397 gfx::Rect shelf_shown = GetShelfWidget()->GetWindowBoundsInScreen(); 398 gfx::Rect bounds_shelf = window->bounds(); 399 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 400 401 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 402 shelf->LayoutShelf(); 403 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 404 405 gfx::Rect bounds_noshelf = window->bounds(); 406 gfx::Rect shelf_hidden = GetShelfWidget()->GetWindowBoundsInScreen(); 407 408 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 409 shelf->LayoutShelf(); 410 411 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 412 const int kNumScrollSteps = 4; 413 ShelfDragCallback handler(shelf_hidden, shelf_shown); 414 415 // Swipe up on the shelf. This should not change any state. 416 gfx::Point start = GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint(); 417 gfx::Point end = start + delta; 418 419 // Swipe down on the shelf to hide it. 420 generator.GestureScrollSequenceWithCallback( 421 start, 422 end, 423 kTimeDelta, 424 kNumScrollSteps, 425 base::Bind(&ShelfDragCallback::ProcessScroll, 426 base::Unretained(&handler))); 427 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 428 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 429 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 430 EXPECT_NE(bounds_shelf.ToString(), window->bounds().ToString()); 431 EXPECT_NE(shelf_shown.ToString(), 432 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 433 434 // Swipe up to show the shelf. 435 generator.GestureScrollSequenceWithCallback( 436 end, 437 start, 438 kTimeDelta, 439 kNumScrollSteps, 440 base::Bind(&ShelfDragCallback::ProcessScroll, 441 base::Unretained(&handler))); 442 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 443 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); 444 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString()); 445 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), 446 GetShelfWidget()->GetWindowBoundsInScreen()); 447 EXPECT_EQ(shelf_shown.ToString(), 448 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 449 450 // Swipe up again. The shelf should hide. 451 end = start - delta; 452 generator.GestureScrollSequenceWithCallback( 453 start, 454 end, 455 kTimeDelta, 456 kNumScrollSteps, 457 base::Bind(&ShelfDragCallback::ProcessScroll, 458 base::Unretained(&handler))); 459 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 460 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 461 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 462 EXPECT_EQ(shelf_hidden.ToString(), 463 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 464 465 // Swipe up yet again to show it. 466 end = start + delta; 467 generator.GestureScrollSequenceWithCallback( 468 end, 469 start, 470 kTimeDelta, 471 kNumScrollSteps, 472 base::Bind(&ShelfDragCallback::ProcessScroll, 473 base::Unretained(&handler))); 474 475 // Swipe down very little. It shouldn't change any state. 476 if (GetShelfLayoutManager()->IsHorizontalAlignment()) 477 end.set_y(start.y() + shelf_shown.height() * 3 / 10); 478 else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment()) 479 end.set_x(start.x() - shelf_shown.width() * 3 / 10); 480 else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment()) 481 end.set_x(start.x() + shelf_shown.width() * 3 / 10); 482 generator.GestureScrollSequence(start, end, kTimeDelta, 5); 483 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 484 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); 485 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString()); 486 EXPECT_EQ(shelf_shown.ToString(), 487 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 488 489 // Swipe down again to hide. 490 end = start + delta; 491 generator.GestureScrollSequenceWithCallback( 492 start, 493 end, 494 kTimeDelta, 495 kNumScrollSteps, 496 base::Bind(&ShelfDragCallback::ProcessScroll, 497 base::Unretained(&handler))); 498 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 499 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 500 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 501 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect()); 502 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString()); 503 EXPECT_EQ(shelf_hidden.ToString(), 504 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 505 506 // Swipe up in extended hit region to show it. 507 gfx::Point extended_start = start; 508 if (GetShelfLayoutManager()->IsHorizontalAlignment()) 509 extended_start.set_y(GetShelfWidget()->GetWindowBoundsInScreen().y() -1); 510 else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment()) 511 extended_start.set_x( 512 GetShelfWidget()->GetWindowBoundsInScreen().right() + 1); 513 else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment()) 514 extended_start.set_x(GetShelfWidget()->GetWindowBoundsInScreen().x() - 1); 515 end = extended_start - delta; 516 generator.GestureScrollSequenceWithCallback( 517 extended_start, 518 end, 519 kTimeDelta, 520 kNumScrollSteps, 521 base::Bind(&ShelfDragCallback::ProcessScroll, 522 base::Unretained(&handler))); 523 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 524 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); 525 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString()); 526 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), 527 GetShelfWidget()->GetWindowBoundsInScreen()); 528 EXPECT_EQ(shelf_shown.ToString(), 529 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 530 531 // Swipe down again to hide. 532 end = start + delta; 533 generator.GestureScrollSequenceWithCallback( 534 start, 535 end, 536 kTimeDelta, 537 kNumScrollSteps, 538 base::Bind(&ShelfDragCallback::ProcessScroll, 539 base::Unretained(&handler))); 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(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect()); 544 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString()); 545 EXPECT_EQ(shelf_hidden.ToString(), 546 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 547 548 // Swipe up outside the hit area. This should not change anything. 549 gfx::Point outside_start = gfx::Point( 550 (GetShelfWidget()->GetWindowBoundsInScreen().x() + 551 GetShelfWidget()->GetWindowBoundsInScreen().right())/2, 552 GetShelfWidget()->GetWindowBoundsInScreen().y() - 50); 553 end = outside_start + delta; 554 generator.GestureScrollSequence( 555 outside_start, end, kTimeDelta, kNumScrollSteps); 556 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 557 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 558 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 559 EXPECT_EQ(shelf_hidden.ToString(), 560 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 561 562 // Swipe up from below the shelf where a bezel would be, this should show the 563 // shelf. 564 gfx::Point below_start = start; 565 if (GetShelfLayoutManager()->IsHorizontalAlignment()) 566 below_start.set_y(GetShelfWidget()->GetWindowBoundsInScreen().bottom() + 1); 567 else if (SHELF_ALIGNMENT_LEFT == GetShelfLayoutManager()->GetAlignment()) 568 below_start.set_x( 569 GetShelfWidget()->GetWindowBoundsInScreen().x() - 1); 570 else if (SHELF_ALIGNMENT_RIGHT == GetShelfLayoutManager()->GetAlignment()) 571 below_start.set_x(GetShelfWidget()->GetWindowBoundsInScreen().right() + 1); 572 end = below_start - delta; 573 generator.GestureScrollSequence( 574 below_start, end, kTimeDelta, kNumScrollSteps); 575 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 576 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); 577 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString()); 578 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), 579 GetShelfWidget()->GetWindowBoundsInScreen()); 580 EXPECT_EQ(shelf_shown.ToString(), 581 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 582 583 // Swipe down again to hide. 584 end = start + delta; 585 generator.GestureScrollSequenceWithCallback( 586 start, 587 end, 588 kTimeDelta, 589 kNumScrollSteps, 590 base::Bind(&ShelfDragCallback::ProcessScroll, 591 base::Unretained(&handler))); 592 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 593 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 594 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 595 EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect()); 596 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString()); 597 EXPECT_EQ(shelf_hidden.ToString(), 598 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 599 600 // Put |widget| into fullscreen. Set the shelf to be auto hidden when |widget| 601 // is fullscreen. (eg browser immersive fullscreen). 602 widget->SetFullscreen(true); 603 wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(false); 604 shelf->UpdateVisibilityState(); 605 606 gfx::Rect bounds_fullscreen = window->bounds(); 607 EXPECT_TRUE(widget->IsFullscreen()); 608 EXPECT_NE(bounds_noshelf.ToString(), bounds_fullscreen.ToString()); 609 610 // Swipe up. This should show the shelf. 611 end = below_start - delta; 612 generator.GestureScrollSequenceWithCallback( 613 below_start, 614 end, 615 kTimeDelta, 616 kNumScrollSteps, 617 base::Bind(&ShelfDragCallback::ProcessScroll, 618 base::Unretained(&handler))); 619 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 620 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 621 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); 622 EXPECT_EQ(shelf_shown.ToString(), 623 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 624 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString()); 625 626 // Swipe up again. This should hide the shelf. 627 generator.GestureScrollSequenceWithCallback( 628 below_start, 629 end, 630 kTimeDelta, 631 kNumScrollSteps, 632 base::Bind(&ShelfDragCallback::ProcessScroll, 633 base::Unretained(&handler))); 634 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 635 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 636 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 637 EXPECT_EQ(shelf_hidden.ToString(), 638 GetShelfWidget()->GetWindowBoundsInScreen().ToString()); 639 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString()); 640 641 // Set the shelf to be hidden when |widget| is fullscreen. (eg tab fullscreen 642 // with or without immersive browser fullscreen). 643 wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(true); 644 shelf->UpdateVisibilityState(); 645 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); 646 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 647 648 // Swipe-up. This should not change anything. 649 end = start - delta; 650 generator.GestureScrollSequenceWithCallback( 651 below_start, 652 end, 653 kTimeDelta, 654 kNumScrollSteps, 655 base::Bind(&ShelfDragCallback::ProcessScroll, 656 base::Unretained(&handler))); 657 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); 658 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 659 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString()); 660 661 // Close actually, otherwise further event may be affected since widget 662 // is fullscreen status. 663 widget->Close(); 664 RunAllPendingInMessageLoop(); 665 666 // The shelf should be shown because there are no more visible windows. 667 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 668 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 669 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 670 671 // Swipe-up to hide. This should have no effect because there are no visible 672 // windows. 673 end = below_start - delta; 674 generator.GestureScrollSequenceWithCallback( 675 below_start, 676 end, 677 kTimeDelta, 678 kNumScrollSteps, 679 base::Bind(&ShelfDragCallback::ProcessScroll, 680 base::Unretained(&handler))); 681 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 682 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 683 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); 684 } 685 686 // Need to be implemented. http://crbug.com/111279. 687 #if defined(OS_WIN) 688 #define MAYBE_SetVisible DISABLED_SetVisible 689 #else 690 #define MAYBE_SetVisible SetVisible 691 #endif 692 // Makes sure SetVisible updates work area and widget appropriately. 693 TEST_F(ShelfLayoutManagerTest, MAYBE_SetVisible) { 694 ShelfWidget* shelf = GetShelfWidget(); 695 ShelfLayoutManager* manager = shelf->shelf_layout_manager(); 696 // Force an initial layout. 697 manager->LayoutShelf(); 698 EXPECT_EQ(SHELF_VISIBLE, manager->visibility_state()); 699 700 gfx::Rect status_bounds( 701 shelf->status_area_widget()->GetWindowBoundsInScreen()); 702 gfx::Rect shelf_bounds( 703 shelf->GetWindowBoundsInScreen()); 704 int shelf_height = manager->GetIdealBounds().height(); 705 gfx::Screen* screen = Shell::GetScreen(); 706 gfx::Display display = screen->GetDisplayNearestWindow( 707 Shell::GetPrimaryRootWindow()); 708 ASSERT_NE(-1, display.id()); 709 // Bottom inset should be the max of widget heights. 710 EXPECT_EQ(shelf_height, display.GetWorkAreaInsets().bottom()); 711 712 // Hide the shelf. 713 SetState(manager, SHELF_HIDDEN); 714 // Run the animation to completion. 715 StepWidgetLayerAnimatorToEnd(shelf); 716 StepWidgetLayerAnimatorToEnd(shelf->status_area_widget()); 717 EXPECT_EQ(SHELF_HIDDEN, manager->visibility_state()); 718 display = screen->GetDisplayNearestWindow( 719 Shell::GetPrimaryRootWindow()); 720 721 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom()); 722 723 // Make sure the bounds of the two widgets changed. 724 EXPECT_GE(shelf->GetNativeView()->bounds().y(), 725 screen->GetPrimaryDisplay().bounds().bottom()); 726 EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(), 727 screen->GetPrimaryDisplay().bounds().bottom()); 728 729 // And show it again. 730 SetState(manager, SHELF_VISIBLE); 731 // Run the animation to completion. 732 StepWidgetLayerAnimatorToEnd(shelf); 733 StepWidgetLayerAnimatorToEnd(shelf->status_area_widget()); 734 EXPECT_EQ(SHELF_VISIBLE, manager->visibility_state()); 735 display = screen->GetDisplayNearestWindow( 736 Shell::GetPrimaryRootWindow()); 737 EXPECT_EQ(shelf_height, display.GetWorkAreaInsets().bottom()); 738 739 // Make sure the bounds of the two widgets changed. 740 shelf_bounds = shelf->GetNativeView()->bounds(); 741 EXPECT_LT(shelf_bounds.y(), screen->GetPrimaryDisplay().bounds().bottom()); 742 status_bounds = shelf->status_area_widget()->GetNativeView()->bounds(); 743 EXPECT_LT(status_bounds.y(), 744 screen->GetPrimaryDisplay().bounds().bottom()); 745 } 746 747 // Makes sure shelf alignment is correct for lock screen. 748 TEST_F(ShelfLayoutManagerTest, SideAlignmentInteractionWithLockScreen) { 749 ShelfLayoutManager* manager = GetShelfWidget()->shelf_layout_manager(); 750 manager->SetAlignment(SHELF_ALIGNMENT_LEFT); 751 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, manager->GetAlignment()); 752 Shell::GetInstance()->session_state_delegate()->LockScreen(); 753 EXPECT_EQ(SHELF_ALIGNMENT_BOTTOM, manager->GetAlignment()); 754 Shell::GetInstance()->session_state_delegate()->UnlockScreen(); 755 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, manager->GetAlignment()); 756 } 757 758 // Makes sure LayoutShelf invoked while animating cleans things up. 759 TEST_F(ShelfLayoutManagerTest, LayoutShelfWhileAnimating) { 760 ShelfWidget* shelf = GetShelfWidget(); 761 // Force an initial layout. 762 shelf->shelf_layout_manager()->LayoutShelf(); 763 EXPECT_EQ(SHELF_VISIBLE, shelf->shelf_layout_manager()->visibility_state()); 764 765 // Hide the shelf. 766 SetState(shelf->shelf_layout_manager(), SHELF_HIDDEN); 767 shelf->shelf_layout_manager()->LayoutShelf(); 768 EXPECT_EQ(SHELF_HIDDEN, shelf->shelf_layout_manager()->visibility_state()); 769 gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow( 770 Shell::GetPrimaryRootWindow()); 771 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom()); 772 773 // Make sure the bounds of the two widgets changed. 774 EXPECT_GE(shelf->GetNativeView()->bounds().y(), 775 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom()); 776 EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(), 777 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom()); 778 } 779 780 // Test that switching to a different visibility state does not restart the 781 // shelf show / hide animation if it is already running. (crbug.com/250918) 782 TEST_F(ShelfLayoutManagerTest, SetStateWhileAnimating) { 783 ShelfWidget* shelf = GetShelfWidget(); 784 SetState(shelf->shelf_layout_manager(), SHELF_VISIBLE); 785 gfx::Rect initial_shelf_bounds = shelf->GetWindowBoundsInScreen(); 786 gfx::Rect initial_status_bounds = 787 shelf->status_area_widget()->GetWindowBoundsInScreen(); 788 789 ui::ScopedAnimationDurationScaleMode normal_animation_duration( 790 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION); 791 SetState(shelf->shelf_layout_manager(), SHELF_HIDDEN); 792 SetState(shelf->shelf_layout_manager(), SHELF_VISIBLE); 793 794 gfx::Rect current_shelf_bounds = shelf->GetWindowBoundsInScreen(); 795 gfx::Rect current_status_bounds = 796 shelf->status_area_widget()->GetWindowBoundsInScreen(); 797 798 const int small_change = initial_shelf_bounds.height() / 2; 799 EXPECT_LE( 800 std::abs(initial_shelf_bounds.height() - current_shelf_bounds.height()), 801 small_change); 802 EXPECT_LE( 803 std::abs(initial_status_bounds.height() - current_status_bounds.height()), 804 small_change); 805 } 806 807 // Makes sure the shelf is sized when the status area changes size. 808 TEST_F(ShelfLayoutManagerTest, ShelfUpdatedWhenStatusAreaChangesSize) { 809 Shelf* shelf = Shelf::ForPrimaryDisplay(); 810 ASSERT_TRUE(shelf); 811 ShelfWidget* shelf_widget = GetShelfWidget(); 812 ASSERT_TRUE(shelf_widget); 813 ASSERT_TRUE(shelf_widget->status_area_widget()); 814 shelf_widget->status_area_widget()->SetBounds( 815 gfx::Rect(0, 0, 200, 200)); 816 EXPECT_EQ(200, shelf_widget->GetContentsView()->width() - 817 test::ShelfTestAPI(shelf).shelf_view()->width()); 818 } 819 820 821 #if defined(OS_WIN) 822 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962 823 #define MAYBE_AutoHide DISABLED_AutoHide 824 #else 825 #define MAYBE_AutoHide AutoHide 826 #endif 827 828 // Various assertions around auto-hide. 829 TEST_F(ShelfLayoutManagerTest, MAYBE_AutoHide) { 830 aura::Window* root = Shell::GetPrimaryRootWindow(); 831 ui::test::EventGenerator generator(root, root); 832 generator.MoveMouseTo(0, 0); 833 834 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 835 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 836 views::Widget* widget = new views::Widget; 837 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 838 params.bounds = gfx::Rect(0, 0, 200, 200); 839 params.context = CurrentContext(); 840 // Widget is now owned by the parent window. 841 widget->Init(params); 842 widget->Maximize(); 843 widget->Show(); 844 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 845 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 846 847 // LayoutShelf() forces the animation to completion, at which point the 848 // shelf should go off the screen. 849 shelf->LayoutShelf(); 850 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, 851 GetShelfWidget()->GetWindowBoundsInScreen().y()); 852 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, 853 Shell::GetScreen()->GetDisplayNearestWindow( 854 root).work_area().bottom()); 855 856 // Move the mouse to the bottom of the screen. 857 generator.MoveMouseTo(0, root->bounds().bottom() - 1); 858 859 // Shelf should be shown again (but it shouldn't have changed the work area). 860 SetState(shelf, SHELF_AUTO_HIDE); 861 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 862 shelf->LayoutShelf(); 863 EXPECT_EQ(root->bounds().bottom() - shelf->GetIdealBounds().height(), 864 GetShelfWidget()->GetWindowBoundsInScreen().y()); 865 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, 866 Shell::GetScreen()->GetDisplayNearestWindow( 867 root).work_area().bottom()); 868 869 // Move mouse back up. 870 generator.MoveMouseTo(0, 0); 871 SetState(shelf, SHELF_AUTO_HIDE); 872 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 873 shelf->LayoutShelf(); 874 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, 875 GetShelfWidget()->GetWindowBoundsInScreen().y()); 876 877 // Drag mouse to bottom of screen. 878 generator.PressLeftButton(); 879 generator.MoveMouseTo(0, root->bounds().bottom() - 1); 880 UpdateAutoHideStateNow(); 881 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 882 883 generator.ReleaseLeftButton(); 884 generator.MoveMouseTo(1, root->bounds().bottom() - 1); 885 UpdateAutoHideStateNow(); 886 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 887 generator.PressLeftButton(); 888 generator.MoveMouseTo(1, root->bounds().bottom() - 1); 889 UpdateAutoHideStateNow(); 890 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 891 } 892 893 // Test the behavior of the shelf when it is auto hidden and it is on the 894 // boundary between the primary and the secondary display. 895 TEST_F(ShelfLayoutManagerTest, AutoHideShelfOnScreenBoundary) { 896 if (!SupportsMultipleDisplays()) 897 return; 898 899 UpdateDisplay("800x600,800x600"); 900 DisplayLayout display_layout(DisplayLayout::RIGHT, 0); 901 Shell::GetInstance()->display_manager()->SetLayoutForCurrentDisplays( 902 display_layout); 903 // Put the primary monitor's shelf on the display boundary. 904 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 905 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT); 906 907 // Create a window because the shelf is always shown when no windows are 908 // visible. 909 CreateTestWidget(); 910 911 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 912 ASSERT_EQ(root_windows[0], 913 GetShelfWidget()->GetNativeWindow()->GetRootWindow()); 914 915 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 916 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 917 918 int right_edge = root_windows[0]->GetBoundsInScreen().right() - 1; 919 int y = root_windows[0]->GetBoundsInScreen().y(); 920 921 // Start off the mouse nowhere near the shelf; the shelf should be hidden. 922 ui::test::EventGenerator& generator(GetEventGenerator()); 923 generator.MoveMouseTo(right_edge - 50, y); 924 UpdateAutoHideStateNow(); 925 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 926 927 // Moving the mouse over the light bar (but not to the edge of the screen) 928 // should show the shelf. 929 generator.MoveMouseTo(right_edge - 1, y); 930 UpdateAutoHideStateNow(); 931 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 932 EXPECT_EQ(right_edge - 1, Shell::GetScreen()->GetCursorScreenPoint().x()); 933 934 // Moving the mouse off the light bar should hide the shelf. 935 generator.MoveMouseTo(right_edge - 50, y); 936 UpdateAutoHideStateNow(); 937 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 938 939 // Moving the mouse to the right edge of the screen crossing the light bar 940 // should show the shelf despite the mouse cursor getting warped to the 941 // secondary display. 942 generator.MoveMouseTo(right_edge - 1, y); 943 generator.MoveMouseTo(right_edge, y); 944 UpdateAutoHideStateNow(); 945 EXPECT_NE(right_edge - 1, Shell::GetScreen()->GetCursorScreenPoint().x()); 946 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 947 948 // Hide the shelf. 949 generator.MoveMouseTo(right_edge - 50, y); 950 UpdateAutoHideStateNow(); 951 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 952 953 // Moving the mouse to the right edge of the screen crossing the light bar and 954 // overshooting by a lot should keep the shelf hidden. 955 generator.MoveMouseTo(right_edge - 1, y); 956 generator.MoveMouseTo(right_edge + 50, y); 957 UpdateAutoHideStateNow(); 958 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 959 960 // Moving the mouse to the right edge of the screen crossing the light bar and 961 // overshooting a bit should show the shelf. 962 generator.MoveMouseTo(right_edge - 1, y); 963 generator.MoveMouseTo(right_edge + 2, y); 964 UpdateAutoHideStateNow(); 965 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 966 967 // Keeping the mouse close to the left edge of the secondary display after the 968 // shelf is shown should keep the shelf shown. 969 generator.MoveMouseTo(right_edge + 2, y + 1); 970 UpdateAutoHideStateNow(); 971 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 972 973 // Moving the mouse far from the left edge of the secondary display should 974 // hide the shelf. 975 generator.MoveMouseTo(right_edge + 50, y); 976 UpdateAutoHideStateNow(); 977 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 978 979 // Moving to the left edge of the secondary display without first crossing 980 // the primary display's right aligned shelf first should not show the shelf. 981 generator.MoveMouseTo(right_edge + 2, y); 982 UpdateAutoHideStateNow(); 983 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 984 } 985 986 // Assertions around the lock screen showing. 987 TEST_F(ShelfLayoutManagerTest, VisibleWhenLockScreenShowing) { 988 // Since ShelfLayoutManager queries for mouse location, move the mouse so 989 // it isn't over the shelf. 990 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), 991 gfx::Point()); 992 generator.MoveMouseTo(0, 0); 993 994 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 995 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 996 views::Widget* widget = new views::Widget; 997 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 998 params.bounds = gfx::Rect(0, 0, 200, 200); 999 params.context = CurrentContext(); 1000 // Widget is now owned by the parent window. 1001 widget->Init(params); 1002 widget->Maximize(); 1003 widget->Show(); 1004 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1005 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1006 1007 aura::Window* root = Shell::GetPrimaryRootWindow(); 1008 // LayoutShelf() forces the animation to completion, at which point the 1009 // shelf should go off the screen. 1010 shelf->LayoutShelf(); 1011 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, 1012 GetShelfWidget()->GetWindowBoundsInScreen().y()); 1013 1014 aura::Window* lock_container = Shell::GetContainer( 1015 Shell::GetPrimaryRootWindow(), kShellWindowId_LockScreenContainer); 1016 1017 views::Widget* lock_widget = new views::Widget; 1018 views::Widget::InitParams lock_params( 1019 views::Widget::InitParams::TYPE_WINDOW); 1020 lock_params.bounds = gfx::Rect(0, 0, 200, 200); 1021 params.context = CurrentContext(); 1022 lock_params.parent = lock_container; 1023 // Widget is now owned by the parent window. 1024 lock_widget->Init(lock_params); 1025 lock_widget->Maximize(); 1026 lock_widget->Show(); 1027 1028 // Lock the screen. 1029 Shell::GetInstance()->session_state_delegate()->LockScreen(); 1030 shelf->UpdateVisibilityState(); 1031 // Showing a widget in the lock screen should force the shelf to be visibile. 1032 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1033 1034 Shell::GetInstance()->session_state_delegate()->UnlockScreen(); 1035 shelf->UpdateVisibilityState(); 1036 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1037 } 1038 1039 // Assertions around SetAutoHideBehavior. 1040 TEST_F(ShelfLayoutManagerTest, SetAutoHideBehavior) { 1041 // Since ShelfLayoutManager queries for mouse location, move the mouse so 1042 // it isn't over the shelf. 1043 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), 1044 gfx::Point()); 1045 generator.MoveMouseTo(0, 0); 1046 1047 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1048 views::Widget* widget = new views::Widget; 1049 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 1050 params.bounds = gfx::Rect(0, 0, 200, 200); 1051 params.context = CurrentContext(); 1052 // Widget is now owned by the parent window. 1053 widget->Init(params); 1054 widget->Show(); 1055 aura::Window* window = widget->GetNativeWindow(); 1056 gfx::Rect display_bounds( 1057 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds()); 1058 1059 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1060 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1061 1062 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1063 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1064 1065 widget->Maximize(); 1066 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1067 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow( 1068 window).work_area().bottom(), 1069 widget->GetWorkAreaBoundsInScreen().bottom()); 1070 1071 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1072 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1073 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow( 1074 window).work_area().bottom(), 1075 widget->GetWorkAreaBoundsInScreen().bottom()); 1076 1077 ui::ScopedAnimationDurationScaleMode animation_duration( 1078 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION); 1079 1080 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1081 ShelfWidget* shelf_widget = GetShelfWidget(); 1082 EXPECT_TRUE(shelf_widget->status_area_widget()->IsVisible()); 1083 StepWidgetLayerAnimatorToEnd(shelf_widget); 1084 StepWidgetLayerAnimatorToEnd(shelf_widget->status_area_widget()); 1085 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1086 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow( 1087 window).work_area().bottom(), 1088 widget->GetWorkAreaBoundsInScreen().bottom()); 1089 } 1090 1091 // Basic assertions around the dimming of the shelf. 1092 TEST_F(ShelfLayoutManagerTest, TestDimmingBehavior) { 1093 // Since ShelfLayoutManager queries for mouse location, move the mouse so 1094 // it isn't over the shelf. 1095 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), 1096 gfx::Point()); 1097 generator.MoveMouseTo(0, 0); 1098 1099 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1100 shelf->shelf_widget()->DisableDimmingAnimationsForTest(); 1101 1102 views::Widget* widget = new views::Widget; 1103 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 1104 params.bounds = gfx::Rect(0, 0, 200, 200); 1105 params.context = CurrentContext(); 1106 // Widget is now owned by the parent window. 1107 widget->Init(params); 1108 widget->Show(); 1109 aura::Window* window = widget->GetNativeWindow(); 1110 gfx::Rect display_bounds( 1111 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds()); 1112 1113 gfx::Point off_shelf = display_bounds.CenterPoint(); 1114 gfx::Point on_shelf = 1115 shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint(); 1116 1117 // Test there is no dimming object active at this point. 1118 generator.MoveMouseTo(on_shelf.x(), on_shelf.y()); 1119 EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1120 generator.MoveMouseTo(off_shelf.x(), off_shelf.y()); 1121 EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1122 1123 // After maximization, the shelf should be visible and the dimmer created. 1124 widget->Maximize(); 1125 1126 on_shelf = shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint(); 1127 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1128 1129 // Moving the mouse off the shelf should dim the bar. 1130 generator.MoveMouseTo(off_shelf.x(), off_shelf.y()); 1131 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1132 1133 // Adding touch events outside the shelf should still keep the shelf in 1134 // dimmed state. 1135 generator.PressTouch(); 1136 generator.MoveTouch(off_shelf); 1137 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1138 // Move the touch into the shelf area should undim. 1139 generator.MoveTouch(on_shelf); 1140 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1141 generator.ReleaseTouch(); 1142 // And a release dims again. 1143 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1144 1145 // Moving the mouse on the shelf should undim the bar. 1146 generator.MoveMouseTo(on_shelf); 1147 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1148 1149 // No matter what the touch events do, the shelf should stay undimmed. 1150 generator.PressTouch(); 1151 generator.MoveTouch(off_shelf); 1152 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1153 generator.MoveTouch(on_shelf); 1154 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1155 generator.MoveTouch(off_shelf); 1156 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1157 generator.MoveTouch(on_shelf); 1158 generator.ReleaseTouch(); 1159 1160 // After restore, the dimming object should be deleted again. 1161 widget->Restore(); 1162 EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1163 } 1164 1165 // Assertions around the dimming of the shelf in conjunction with menus. 1166 TEST_F(ShelfLayoutManagerTest, TestDimmingBehaviorWithMenus) { 1167 // Since ShelfLayoutManager queries for mouse location, move the mouse so 1168 // it isn't over the shelf. 1169 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), 1170 gfx::Point()); 1171 generator.MoveMouseTo(0, 0); 1172 1173 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1174 shelf->shelf_widget()->DisableDimmingAnimationsForTest(); 1175 1176 views::Widget* widget = new views::Widget; 1177 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 1178 params.bounds = gfx::Rect(0, 0, 200, 200); 1179 params.context = CurrentContext(); 1180 // Widget is now owned by the parent window. 1181 widget->Init(params); 1182 widget->Show(); 1183 aura::Window* window = widget->GetNativeWindow(); 1184 gfx::Rect display_bounds( 1185 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds()); 1186 1187 // After maximization, the shelf should be visible and the dimmer created. 1188 widget->Maximize(); 1189 1190 gfx::Point off_shelf = display_bounds.CenterPoint(); 1191 gfx::Point on_shelf = 1192 shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint(); 1193 1194 // Moving the mouse on the shelf should undim the bar. 1195 generator.MoveMouseTo(on_shelf.x(), on_shelf.y()); 1196 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1197 1198 // Simulate a menu opening. 1199 shelf->shelf_widget()->ForceUndimming(true); 1200 1201 // Moving the mouse off the shelf should not dim the bar. 1202 generator.MoveMouseTo(off_shelf.x(), off_shelf.y()); 1203 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1204 1205 // No matter what the touch events do, the shelf should stay undimmed. 1206 generator.PressTouch(); 1207 generator.MoveTouch(off_shelf); 1208 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1209 generator.MoveTouch(on_shelf); 1210 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1211 generator.MoveTouch(off_shelf); 1212 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1213 generator.ReleaseTouch(); 1214 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1215 1216 // "Closing the menu" should now turn off the menu since no event is inside 1217 // the shelf any longer. 1218 shelf->shelf_widget()->ForceUndimming(false); 1219 EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1220 1221 // Moving the mouse again on the shelf which should undim the bar again. 1222 // This time we check that the bar stays undimmed when the mouse remains on 1223 // the bar and the "menu gets closed". 1224 generator.MoveMouseTo(on_shelf.x(), on_shelf.y()); 1225 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1226 shelf->shelf_widget()->ForceUndimming(true); 1227 generator.MoveMouseTo(off_shelf.x(), off_shelf.y()); 1228 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1229 generator.MoveMouseTo(on_shelf.x(), on_shelf.y()); 1230 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1231 shelf->shelf_widget()->ForceUndimming(true); 1232 EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest()); 1233 } 1234 1235 // Verifies the shelf is visible when status/shelf is focused. 1236 TEST_F(ShelfLayoutManagerTest, VisibleWhenStatusOrShelfFocused) { 1237 // Since ShelfLayoutManager queries for mouse location, move the mouse so 1238 // it isn't over the shelf. 1239 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), 1240 gfx::Point()); 1241 generator.MoveMouseTo(0, 0); 1242 1243 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1244 views::Widget* widget = new views::Widget; 1245 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 1246 params.bounds = gfx::Rect(0, 0, 200, 200); 1247 params.context = CurrentContext(); 1248 // Widget is now owned by the parent window. 1249 widget->Init(params); 1250 widget->Show(); 1251 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1252 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1253 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1254 1255 // Focus the shelf. Have to go through the focus cycler as normal focus 1256 // requests to it do nothing. 1257 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD); 1258 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1259 1260 widget->Activate(); 1261 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1262 1263 // Trying to activate the status should fail, since we only allow activating 1264 // it when the user is using the keyboard (i.e. through FocusCycler). 1265 GetShelfWidget()->status_area_widget()->Activate(); 1266 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1267 1268 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD); 1269 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1270 } 1271 1272 // Makes sure shelf will be visible when app list opens as shelf is in 1273 // SHELF_VISIBLE state,and toggling app list won't change shelf 1274 // visibility state. 1275 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfVisibleState) { 1276 Shell* shell = Shell::GetInstance(); 1277 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1278 shelf->LayoutShelf(); 1279 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1280 1281 // Create a normal unmaximized windowm shelf should be visible. 1282 aura::Window* window = CreateTestWindow(); 1283 window->SetBounds(gfx::Rect(0, 0, 100, 100)); 1284 window->Show(); 1285 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 1286 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1287 1288 // Show app list and the shelf stays visible. 1289 shell->ShowAppList(NULL); 1290 EXPECT_TRUE(shell->GetAppListTargetVisibility()); 1291 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1292 1293 // Hide app list and the shelf stays visible. 1294 shell->DismissAppList(); 1295 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 1296 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1297 } 1298 1299 // Makes sure shelf will be shown with SHELF_AUTO_HIDE_SHOWN state 1300 // when app list opens as shelf is in SHELF_AUTO_HIDE state, and 1301 // toggling app list won't change shelf visibility state. 1302 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfAutoHideState) { 1303 Shell* shell = Shell::GetInstance(); 1304 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1305 shelf->LayoutShelf(); 1306 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1307 1308 // Create a window and show it in maximized state. 1309 aura::Window* window = CreateTestWindow(); 1310 window->SetBounds(gfx::Rect(0, 0, 100, 100)); 1311 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); 1312 window->Show(); 1313 wm::ActivateWindow(window); 1314 1315 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 1316 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1317 1318 // Show app list. 1319 shell->ShowAppList(NULL); 1320 // The shelf's auto hide state won't be changed until the timer fires, so 1321 // calling shell->UpdateShelfVisibility() is kind of manually helping it to 1322 // update the state. 1323 shell->UpdateShelfVisibility(); 1324 EXPECT_TRUE(shell->GetAppListTargetVisibility()); 1325 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1326 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1327 1328 // Hide app list. 1329 shell->DismissAppList(); 1330 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 1331 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1332 } 1333 1334 // Makes sure shelf will be hidden when app list opens as shelf is in HIDDEN 1335 // state, and toggling app list won't change shelf visibility state. 1336 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfHiddenState) { 1337 Shell* shell = Shell::GetInstance(); 1338 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1339 // For shelf to be visible, app list is not open in initial state. 1340 shelf->LayoutShelf(); 1341 1342 // Create a window and make it full screen. 1343 aura::Window* window = CreateTestWindow(); 1344 window->SetBounds(gfx::Rect(0, 0, 100, 100)); 1345 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN); 1346 window->Show(); 1347 wm::ActivateWindow(window); 1348 1349 // App list and shelf is not shown. 1350 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 1351 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); 1352 1353 // Show app list. 1354 shell->ShowAppList(NULL); 1355 EXPECT_TRUE(shell->GetAppListTargetVisibility()); 1356 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); 1357 1358 // Hide app list. 1359 shell->DismissAppList(); 1360 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 1361 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); 1362 } 1363 1364 // Tests that the shelf is only hidden for a fullscreen window at the front and 1365 // toggles visibility when another window is activated. 1366 TEST_F(ShelfLayoutManagerTest, FullscreenWindowInFrontHidesShelf) { 1367 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1368 1369 // Create a window and make it full screen. 1370 aura::Window* window1 = CreateTestWindow(); 1371 window1->SetBounds(gfx::Rect(0, 0, 100, 100)); 1372 window1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN); 1373 window1->Show(); 1374 1375 aura::Window* window2 = CreateTestWindow(); 1376 window2->SetBounds(gfx::Rect(0, 0, 100, 100)); 1377 window2->Show(); 1378 1379 wm::GetWindowState(window1)->Activate(); 1380 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); 1381 1382 wm::GetWindowState(window2)->Activate(); 1383 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1384 1385 wm::GetWindowState(window1)->Activate(); 1386 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); 1387 } 1388 1389 // Test the behavior of the shelf when a window on one display is fullscreen 1390 // but the other display has the active window. 1391 TEST_F(ShelfLayoutManagerTest, FullscreenWindowOnSecondDisplay) { 1392 if (!SupportsMultipleDisplays()) 1393 return; 1394 1395 UpdateDisplay("800x600,800x600"); 1396 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 1397 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 1398 Shell::RootWindowControllerList root_window_controllers = 1399 Shell::GetAllRootWindowControllers(); 1400 1401 // Create windows on either display. 1402 aura::Window* window1 = CreateTestWindow(); 1403 window1->SetBoundsInScreen( 1404 gfx::Rect(0, 0, 100, 100), 1405 display_manager->GetDisplayAt(0)); 1406 window1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN); 1407 window1->Show(); 1408 1409 aura::Window* window2 = CreateTestWindow(); 1410 window2->SetBoundsInScreen( 1411 gfx::Rect(800, 0, 100, 100), 1412 display_manager->GetDisplayAt(1)); 1413 window2->Show(); 1414 1415 EXPECT_EQ(root_windows[0], window1->GetRootWindow()); 1416 EXPECT_EQ(root_windows[1], window2->GetRootWindow()); 1417 1418 wm::GetWindowState(window2)->Activate(); 1419 EXPECT_EQ(SHELF_HIDDEN, 1420 root_window_controllers[0]->GetShelfLayoutManager()->visibility_state()); 1421 EXPECT_EQ(SHELF_VISIBLE, 1422 root_window_controllers[1]->GetShelfLayoutManager()->visibility_state()); 1423 } 1424 1425 1426 #if defined(OS_WIN) 1427 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962 1428 #define MAYBE_SetAlignment DISABLED_SetAlignment 1429 #else 1430 #define MAYBE_SetAlignment SetAlignment 1431 #endif 1432 1433 // Tests SHELF_ALIGNMENT_(LEFT, RIGHT, TOP). 1434 TEST_F(ShelfLayoutManagerTest, MAYBE_SetAlignment) { 1435 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1436 // Force an initial layout. 1437 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1438 shelf->LayoutShelf(); 1439 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1440 1441 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT); 1442 gfx::Rect shelf_bounds( 1443 GetShelfWidget()->GetWindowBoundsInScreen()); 1444 const gfx::Screen* screen = Shell::GetScreen(); 1445 gfx::Display display = 1446 screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); 1447 ASSERT_NE(-1, display.id()); 1448 EXPECT_EQ(shelf->GetIdealBounds().width(), 1449 display.GetWorkAreaInsets().left()); 1450 EXPECT_GE( 1451 shelf_bounds.width(), 1452 GetShelfWidget()->GetContentsView()->GetPreferredSize().width()); 1453 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, GetSystemTray()->shelf_alignment()); 1454 StatusAreaWidget* status_area_widget = GetShelfWidget()->status_area_widget(); 1455 gfx::Rect status_bounds(status_area_widget->GetWindowBoundsInScreen()); 1456 EXPECT_GE(status_bounds.width(), 1457 status_area_widget->GetContentsView()->GetPreferredSize().width()); 1458 EXPECT_EQ(shelf->GetIdealBounds().width(), 1459 display.GetWorkAreaInsets().left()); 1460 EXPECT_EQ(0, display.GetWorkAreaInsets().top()); 1461 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom()); 1462 EXPECT_EQ(0, display.GetWorkAreaInsets().right()); 1463 EXPECT_EQ(display.bounds().x(), shelf_bounds.x()); 1464 EXPECT_EQ(display.bounds().y(), shelf_bounds.y()); 1465 EXPECT_EQ(display.bounds().height(), shelf_bounds.height()); 1466 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1467 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); 1468 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, 1469 display.GetWorkAreaInsets().left()); 1470 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, display.work_area().x()); 1471 1472 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1473 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT); 1474 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); 1475 shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen(); 1476 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); 1477 ASSERT_NE(-1, display.id()); 1478 EXPECT_EQ(shelf->GetIdealBounds().width(), 1479 display.GetWorkAreaInsets().right()); 1480 EXPECT_GE(shelf_bounds.width(), 1481 GetShelfWidget()->GetContentsView()->GetPreferredSize().width()); 1482 EXPECT_EQ(SHELF_ALIGNMENT_RIGHT, GetSystemTray()->shelf_alignment()); 1483 status_bounds = gfx::Rect(status_area_widget->GetWindowBoundsInScreen()); 1484 EXPECT_GE(status_bounds.width(), 1485 status_area_widget->GetContentsView()->GetPreferredSize().width()); 1486 EXPECT_EQ(shelf->GetIdealBounds().width(), 1487 display.GetWorkAreaInsets().right()); 1488 EXPECT_EQ(0, display.GetWorkAreaInsets().top()); 1489 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom()); 1490 EXPECT_EQ(0, display.GetWorkAreaInsets().left()); 1491 EXPECT_EQ(display.work_area().right(), shelf_bounds.x()); 1492 EXPECT_EQ(display.bounds().y(), shelf_bounds.y()); 1493 EXPECT_EQ(display.bounds().height(), shelf_bounds.height()); 1494 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1495 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); 1496 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, 1497 display.GetWorkAreaInsets().right()); 1498 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, 1499 display.bounds().right() - display.work_area().right()); 1500 1501 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1502 shelf->SetAlignment(SHELF_ALIGNMENT_TOP); 1503 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); 1504 shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen(); 1505 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); 1506 ASSERT_NE(-1, display.id()); 1507 EXPECT_EQ(shelf->GetIdealBounds().height(), 1508 display.GetWorkAreaInsets().top()); 1509 EXPECT_GE(shelf_bounds.height(), 1510 GetShelfWidget()->GetContentsView()->GetPreferredSize().height()); 1511 EXPECT_EQ(SHELF_ALIGNMENT_TOP, GetSystemTray()->shelf_alignment()); 1512 status_bounds = gfx::Rect(status_area_widget->GetWindowBoundsInScreen()); 1513 EXPECT_GE(status_bounds.height(), 1514 status_area_widget->GetContentsView()->GetPreferredSize().height()); 1515 EXPECT_EQ(shelf->GetIdealBounds().height(), 1516 display.GetWorkAreaInsets().top()); 1517 EXPECT_EQ(0, display.GetWorkAreaInsets().right()); 1518 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom()); 1519 EXPECT_EQ(0, display.GetWorkAreaInsets().left()); 1520 EXPECT_EQ(display.work_area().y(), shelf_bounds.bottom()); 1521 EXPECT_EQ(display.bounds().x(), shelf_bounds.x()); 1522 EXPECT_EQ(display.bounds().width(), shelf_bounds.width()); 1523 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1524 display = screen->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); 1525 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, 1526 display.GetWorkAreaInsets().top()); 1527 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, 1528 display.work_area().y() - display.bounds().y()); 1529 } 1530 1531 TEST_F(ShelfLayoutManagerTest, GestureEdgeSwipe) { 1532 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1533 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1534 views::Widget* widget = new views::Widget; 1535 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 1536 params.bounds = gfx::Rect(0, 0, 200, 200); 1537 params.context = CurrentContext(); 1538 widget->Init(params); 1539 widget->Show(); 1540 widget->Maximize(); 1541 1542 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 1543 1544 aura::Window* window = widget->GetNativeWindow(); 1545 shelf->LayoutShelf(); 1546 1547 gfx::Rect shelf_shown = GetShelfWidget()->GetWindowBoundsInScreen(); 1548 gfx::Rect bounds_shelf = window->bounds(); 1549 1550 // Edge swipe when SHELF_VISIBLE should not change visibility state. 1551 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1552 generator.GestureEdgeSwipe(); 1553 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1554 1555 // Edge swipe when AUTO_HIDE_HIDDEN should change to AUTO_HIDE_SHOWN. 1556 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1557 shelf->LayoutShelf(); 1558 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1559 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1560 generator.GestureEdgeSwipe(); 1561 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1562 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1563 1564 widget->SetFullscreen(true); 1565 wm::GetWindowState(window)->set_hide_shelf_when_fullscreen(false); 1566 shelf->UpdateVisibilityState(); 1567 1568 // Edge swipe in fullscreen + AUTO_HIDE_HIDDEN should show the shelf and 1569 // remain fullscreen. 1570 EXPECT_TRUE(widget->IsFullscreen()); 1571 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1572 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1573 generator.GestureEdgeSwipe(); 1574 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1575 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1576 EXPECT_TRUE(widget->IsFullscreen()); 1577 } 1578 1579 #if defined(OS_WIN) 1580 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962 1581 #define MAYBE_GestureDrag DISABLED_GestureDrag 1582 #else 1583 #define MAYBE_GestureDrag GestureDrag 1584 #endif 1585 1586 TEST_F(ShelfLayoutManagerTest, MAYBE_GestureDrag) { 1587 // Slop is an implementation detail of gesture recognition, and complicates 1588 // these tests. Ignore it. 1589 ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click(0); 1590 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1591 { 1592 SCOPED_TRACE("BOTTOM"); 1593 RunGestureDragTests(gfx::Vector2d(0, 120)); 1594 } 1595 1596 { 1597 SCOPED_TRACE("LEFT"); 1598 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT); 1599 RunGestureDragTests(gfx::Vector2d(-120, 0)); 1600 } 1601 1602 { 1603 SCOPED_TRACE("RIGHT"); 1604 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT); 1605 RunGestureDragTests(gfx::Vector2d(120, 0)); 1606 } 1607 } 1608 1609 TEST_F(ShelfLayoutManagerTest, WindowVisibilityDisablesAutoHide) { 1610 if (!SupportsMultipleDisplays()) 1611 return; 1612 1613 UpdateDisplay("800x600,800x600"); 1614 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1615 shelf->LayoutShelf(); 1616 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1617 1618 // Create a visible window so auto-hide behavior is enforced 1619 views::Widget* dummy = CreateTestWidget(); 1620 1621 // Window visible => auto hide behaves normally. 1622 shelf->UpdateVisibilityState(); 1623 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1624 1625 // Window minimized => auto hide disabled. 1626 dummy->Minimize(); 1627 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1628 1629 // Window closed => auto hide disabled. 1630 dummy->CloseNow(); 1631 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1632 1633 // Multiple window test 1634 views::Widget* window1 = CreateTestWidget(); 1635 views::Widget* window2 = CreateTestWidget(); 1636 1637 // both visible => normal autohide 1638 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1639 1640 // either minimzed => normal autohide 1641 window2->Minimize(); 1642 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1643 window2->Restore(); 1644 window1->Minimize(); 1645 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1646 1647 // both minimized => disable auto hide 1648 window2->Minimize(); 1649 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1650 1651 // Test moving windows to/from other display. 1652 window2->Restore(); 1653 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1654 // Move to second display. 1655 window2->SetBounds(gfx::Rect(850, 50, 50, 50)); 1656 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1657 // Move back to primary display. 1658 window2->SetBounds(gfx::Rect(50, 50, 50, 50)); 1659 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1660 } 1661 1662 // Test that the shelf animates back to its normal position upon a user 1663 // completing a gesture drag. 1664 TEST_F(ShelfLayoutManagerTest, ShelfAnimatesWhenGestureComplete) { 1665 if (!SupportsHostWindowResize()) 1666 return; 1667 1668 // Test the shelf animates back to its original visible bounds when it is 1669 // dragged when there are no visible windows. 1670 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1671 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1672 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1673 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1674 gfx::Rect visible_bounds = GetShelfWidget()->GetWindowBoundsInScreen(); 1675 { 1676 // Enable animations so that we can make sure that they occur. 1677 ui::ScopedAnimationDurationScaleMode regular_animations( 1678 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); 1679 1680 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 1681 gfx::Rect shelf_bounds_in_screen = 1682 GetShelfWidget()->GetWindowBoundsInScreen(); 1683 gfx::Point start(shelf_bounds_in_screen.CenterPoint()); 1684 gfx::Point end(start.x(), shelf_bounds_in_screen.bottom()); 1685 generator.GestureScrollSequence(start, end, 1686 base::TimeDelta::FromMilliseconds(10), 5); 1687 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1688 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1689 1690 ShelfAnimationWaiter waiter(visible_bounds); 1691 // Wait till the animation completes and check that it occurred. 1692 waiter.WaitTillDoneAnimating(); 1693 EXPECT_TRUE(waiter.WasValidAnimation()); 1694 } 1695 1696 // Create a visible window so auto-hide behavior is enforced. 1697 CreateTestWidget(); 1698 1699 // Get the bounds of the shelf when it is hidden. 1700 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1701 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1702 gfx::Rect auto_hidden_bounds = GetShelfWidget()->GetWindowBoundsInScreen(); 1703 1704 { 1705 // Enable the animations so that we can make sure they do occur. 1706 ui::ScopedAnimationDurationScaleMode regular_animations( 1707 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); 1708 1709 gfx::Point start = 1710 GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint(); 1711 gfx::Point end(start.x(), start.y() - 100); 1712 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 1713 1714 // Test that the shelf animates to the visible bounds after a swipe up on 1715 // the auto hidden shelf. 1716 generator.GestureScrollSequence(start, end, 1717 base::TimeDelta::FromMilliseconds(10), 1); 1718 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1719 ShelfAnimationWaiter waiter1(visible_bounds); 1720 waiter1.WaitTillDoneAnimating(); 1721 EXPECT_TRUE(waiter1.WasValidAnimation()); 1722 1723 // Test that the shelf animates to the auto hidden bounds after a swipe up 1724 // on the visible shelf. 1725 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1726 generator.GestureScrollSequence(start, end, 1727 base::TimeDelta::FromMilliseconds(10), 1); 1728 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1729 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1730 ShelfAnimationWaiter waiter2(auto_hidden_bounds); 1731 waiter2.WaitTillDoneAnimating(); 1732 EXPECT_TRUE(waiter2.WasValidAnimation()); 1733 } 1734 } 1735 1736 TEST_F(ShelfLayoutManagerTest, GestureRevealsTrayBubble) { 1737 if (!SupportsHostWindowResize()) 1738 return; 1739 1740 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1741 shelf->LayoutShelf(); 1742 1743 // Create a visible window so auto-hide behavior is enforced. 1744 CreateTestWidget(); 1745 1746 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 1747 SystemTray* tray = GetSystemTray(); 1748 1749 // First, make sure the shelf is visible. 1750 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1751 EXPECT_FALSE(tray->HasSystemBubble()); 1752 1753 // Now, drag up on the tray to show the bubble. 1754 gfx::Point start = GetShelfWidget()->status_area_widget()-> 1755 GetWindowBoundsInScreen().CenterPoint(); 1756 gfx::Point end(start.x(), start.y() - 100); 1757 generator.GestureScrollSequence(start, end, 1758 base::TimeDelta::FromMilliseconds(10), 1); 1759 EXPECT_TRUE(tray->HasSystemBubble()); 1760 tray->CloseSystemBubble(); 1761 RunAllPendingInMessageLoop(); 1762 EXPECT_FALSE(tray->HasSystemBubble()); 1763 1764 // Drag again, but only a small amount, and slowly. The bubble should not be 1765 // visible. 1766 end.set_y(start.y() - 30); 1767 generator.GestureScrollSequence(start, end, 1768 base::TimeDelta::FromMilliseconds(500), 100); 1769 EXPECT_FALSE(tray->HasSystemBubble()); 1770 1771 // Now, hide the shelf. 1772 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1773 1774 // Start a drag from the bezel, and drag up to show both the shelf and the 1775 // tray bubble. 1776 start.set_y(start.y() + 100); 1777 end.set_y(start.y() - 400); 1778 generator.GestureScrollSequence(start, end, 1779 base::TimeDelta::FromMilliseconds(10), 1); 1780 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); 1781 EXPECT_TRUE(tray->HasSystemBubble()); 1782 } 1783 1784 TEST_F(ShelfLayoutManagerTest, ShelfFlickerOnTrayActivation) { 1785 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1786 1787 // Create a visible window so auto-hide behavior is enforced. 1788 CreateTestWidget(); 1789 1790 // Turn on auto-hide for the shelf. 1791 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1792 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1793 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); 1794 1795 // Show the status menu. That should make the shelf visible again. 1796 Shell::GetInstance()->accelerator_controller()->PerformAction( 1797 SHOW_SYSTEM_TRAY_BUBBLE, ui::Accelerator()); 1798 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); 1799 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); 1800 EXPECT_TRUE(GetSystemTray()->HasSystemBubble()); 1801 } 1802 1803 TEST_F(ShelfLayoutManagerTest, WorkAreaChangeWorkspace) { 1804 // Make sure the shelf is always visible. 1805 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1806 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1807 shelf->LayoutShelf(); 1808 1809 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 1810 params.bounds = gfx::Rect(0, 0, 200, 200); 1811 params.context = CurrentContext(); 1812 views::Widget* widget_one = CreateTestWidgetWithParams(params); 1813 widget_one->Maximize(); 1814 1815 views::Widget* widget_two = CreateTestWidgetWithParams(params); 1816 widget_two->Maximize(); 1817 widget_two->Activate(); 1818 1819 // Both windows are maximized. They should be of the same size. 1820 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(), 1821 widget_two->GetNativeWindow()->bounds().ToString()); 1822 int area_when_shelf_shown = 1823 widget_one->GetNativeWindow()->bounds().size().GetArea(); 1824 1825 // Now hide the shelf. 1826 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1827 1828 // Both windows should be resized according to the shelf status. 1829 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(), 1830 widget_two->GetNativeWindow()->bounds().ToString()); 1831 // Resized to small. 1832 EXPECT_LT(area_when_shelf_shown, 1833 widget_one->GetNativeWindow()->bounds().size().GetArea()); 1834 1835 // Now show the shelf. 1836 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1837 1838 // Again both windows should be of the same size. 1839 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(), 1840 widget_two->GetNativeWindow()->bounds().ToString()); 1841 EXPECT_EQ(area_when_shelf_shown, 1842 widget_one->GetNativeWindow()->bounds().size().GetArea()); 1843 } 1844 1845 // Confirm that the shelf is dimmed only when content is maximized and 1846 // shelf is not autohidden. 1847 TEST_F(ShelfLayoutManagerTest, Dimming) { 1848 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1849 scoped_ptr<aura::Window> w1(CreateTestWindow()); 1850 w1->Show(); 1851 wm::ActivateWindow(w1.get()); 1852 1853 // Normal window doesn't dim shelf. 1854 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); 1855 ShelfWidget* shelf = GetShelfWidget(); 1856 EXPECT_FALSE(shelf->GetDimsShelf()); 1857 1858 // Maximized window does. 1859 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); 1860 EXPECT_TRUE(shelf->GetDimsShelf()); 1861 1862 // Change back to normal stops dimming. 1863 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); 1864 EXPECT_FALSE(shelf->GetDimsShelf()); 1865 1866 // Changing back to maximized dims again. 1867 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); 1868 EXPECT_TRUE(shelf->GetDimsShelf()); 1869 1870 // Changing shelf to autohide stops dimming. 1871 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1872 EXPECT_FALSE(shelf->GetDimsShelf()); 1873 } 1874 1875 // Make sure that the shelf will not hide if the mouse is between a bubble and 1876 // the shelf. 1877 TEST_F(ShelfLayoutManagerTest, BubbleEnlargesShelfMouseHitArea) { 1878 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1879 StatusAreaWidget* status_area_widget = 1880 Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget(); 1881 SystemTray* tray = GetSystemTray(); 1882 1883 // Create a visible window so auto-hide behavior is enforced. 1884 CreateTestWidget(); 1885 1886 shelf->LayoutShelf(); 1887 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 1888 1889 // Make two iterations - first without a message bubble which should make 1890 // the shelf disappear and then with a message bubble which should keep it 1891 // visible. 1892 for (int i = 0; i < 2; i++) { 1893 // Make sure the shelf is visible and position the mouse over it. Then 1894 // allow auto hide. 1895 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 1896 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1897 gfx::Point center = 1898 status_area_widget->GetWindowBoundsInScreen().CenterPoint(); 1899 generator.MoveMouseTo(center.x(), center.y()); 1900 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1901 EXPECT_TRUE(shelf->IsVisible()); 1902 if (!i) { 1903 // In our first iteration we make sure there is no bubble. 1904 tray->CloseSystemBubble(); 1905 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1906 } else { 1907 // In our second iteration we show a bubble. 1908 TestItem *item = new TestItem; 1909 tray->AddTrayItem(item); 1910 tray->ShowNotificationView(item); 1911 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown()); 1912 } 1913 // Move the pointer over the edge of the shelf. 1914 generator.MoveMouseTo( 1915 center.x(), status_area_widget->GetWindowBoundsInScreen().y() - 8); 1916 shelf->UpdateVisibilityState(); 1917 if (i) { 1918 EXPECT_TRUE(shelf->IsVisible()); 1919 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown()); 1920 } else { 1921 EXPECT_FALSE(shelf->IsVisible()); 1922 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1923 } 1924 } 1925 } 1926 1927 TEST_F(ShelfLayoutManagerTest, ShelfBackgroundColor) { 1928 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType()); 1929 1930 scoped_ptr<aura::Window> w1(CreateTestWindow()); 1931 w1->Show(); 1932 wm::ActivateWindow(w1.get()); 1933 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType()); 1934 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); 1935 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType()); 1936 1937 scoped_ptr<aura::Window> w2(CreateTestWindow()); 1938 w2->Show(); 1939 wm::ActivateWindow(w2.get()); 1940 // Overlaps with shelf. 1941 w2->SetBounds(GetShelfLayoutManager()->GetIdealBounds()); 1942 1943 // Still background is 'maximized'. 1944 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType()); 1945 1946 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); 1947 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType()); 1948 w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); 1949 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType()); 1950 1951 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); 1952 EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, GetShelfWidget()->GetBackgroundType()); 1953 w1.reset(); 1954 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget()->GetBackgroundType()); 1955 } 1956 1957 // Verify that the shelf doesn't have the opaque background if it's auto-hide 1958 // status. 1959 TEST_F(ShelfLayoutManagerTest, ShelfBackgroundColorAutoHide) { 1960 EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, GetShelfWidget ()->GetBackgroundType()); 1961 1962 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1963 scoped_ptr<aura::Window> w1(CreateTestWindow()); 1964 w1->Show(); 1965 wm::ActivateWindow(w1.get()); 1966 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType()); 1967 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); 1968 EXPECT_EQ(SHELF_BACKGROUND_OVERLAP, GetShelfWidget()->GetBackgroundType()); 1969 } 1970 1971 #if defined(OS_CHROMEOS) 1972 #define MAYBE_StatusAreaHitBoxCoversEdge StatusAreaHitBoxCoversEdge 1973 #else 1974 #define MAYBE_StatusAreaHitBoxCoversEdge DISABLED_StatusAreaHitBoxCoversEdge 1975 #endif 1976 1977 // Verify the hit bounds of the status area extend to the edge of the shelf. 1978 TEST_F(ShelfLayoutManagerTest, MAYBE_StatusAreaHitBoxCoversEdge) { 1979 UpdateDisplay("400x400"); 1980 ShelfLayoutManager* shelf = GetShelfLayoutManager(); 1981 StatusAreaWidget* status_area_widget = 1982 Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget(); 1983 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 1984 generator.MoveMouseTo(399,399); 1985 1986 // Test bottom right pixel for bottom alignment. 1987 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1988 generator.ClickLeftButton(); 1989 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown()); 1990 generator.ClickLeftButton(); 1991 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1992 1993 // Test bottom right pixel for right alignment. 1994 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT); 1995 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 1996 generator.ClickLeftButton(); 1997 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown()); 1998 generator.ClickLeftButton(); 1999 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 2000 2001 // Test bottom left pixel for left alignment. 2002 generator.MoveMouseTo(0, 399); 2003 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT); 2004 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 2005 generator.ClickLeftButton(); 2006 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown()); 2007 generator.ClickLeftButton(); 2008 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); 2009 } 2010 2011 // Tests that when the auto-hide behaviour is changed during an animation the 2012 // target bounds are updated to reflect the new state. 2013 TEST_F(ShelfLayoutManagerTest, 2014 ShelfAutoHideToggleDuringAnimationUpdatesBounds) { 2015 ShelfLayoutManager* shelf_manager = GetShelfLayoutManager(); 2016 aura::Window* status_window = GetShelfWidget()->status_area_widget()-> 2017 GetNativeView(); 2018 gfx::Rect initial_bounds = status_window->bounds(); 2019 2020 ui::ScopedAnimationDurationScaleMode regular_animations( 2021 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION); 2022 shelf_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN); 2023 gfx::Rect hide_target_bounds = status_window->GetTargetBounds(); 2024 EXPECT_GT(hide_target_bounds.y(), initial_bounds.y()); 2025 2026 shelf_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 2027 gfx::Rect reshow_target_bounds = status_window->GetTargetBounds(); 2028 EXPECT_EQ(initial_bounds, reshow_target_bounds); 2029 } 2030 2031 } // namespace ash 2032