| OLD | NEW |
| (Empty) |
| 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/wm/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/shell.h" | |
| 16 #include "ash/shell_delegate.h" | |
| 17 #include "ash/shell_window_ids.h" | |
| 18 #include "ash/system/status_area_widget.h" | |
| 19 #include "ash/system/tray/system_tray.h" | |
| 20 #include "ash/system/tray/system_tray_item.h" | |
| 21 #include "ash/test/ash_test_base.h" | |
| 22 #include "ash/wm/window_util.h" | |
| 23 #include "base/command_line.h" | |
| 24 #include "base/utf_string_conversions.h" | |
| 25 #include "ui/aura/client/aura_constants.h" | |
| 26 #include "ui/aura/root_window.h" | |
| 27 #include "ui/aura/test/event_generator.h" | |
| 28 #include "ui/aura/window.h" | |
| 29 #include "ui/base/animation/animation_container_element.h" | |
| 30 #include "ui/compositor/layer.h" | |
| 31 #include "ui/compositor/layer_animator.h" | |
| 32 #include "ui/gfx/display.h" | |
| 33 #include "ui/gfx/screen.h" | |
| 34 #include "ui/views/controls/label.h" | |
| 35 #include "ui/views/layout/fill_layout.h" | |
| 36 #include "ui/views/view.h" | |
| 37 #include "ui/views/widget/widget.h" | |
| 38 | |
| 39 #if defined(OS_WIN) | |
| 40 #include "base/win/windows_version.h" | |
| 41 #endif | |
| 42 | |
| 43 namespace ash { | |
| 44 namespace internal { | |
| 45 | |
| 46 namespace { | |
| 47 | |
| 48 void StepWidgetLayerAnimatorToEnd(views::Widget* widget) { | |
| 49 ui::AnimationContainerElement* element = | |
| 50 static_cast<ui::AnimationContainerElement*>( | |
| 51 widget->GetNativeView()->layer()->GetAnimator()); | |
| 52 element->Step(base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1)); | |
| 53 } | |
| 54 | |
| 55 ShelfLayoutManager* GetShelfLayoutManager() { | |
| 56 return Shell::GetPrimaryRootWindowController()->shelf(); | |
| 57 } | |
| 58 | |
| 59 SystemTray* GetSystemTray() { | |
| 60 return Shell::GetPrimaryRootWindowController()->GetSystemTray(); | |
| 61 } | |
| 62 | |
| 63 class ShelfLayoutObserverTest : public ShelfLayoutManager::Observer { | |
| 64 public: | |
| 65 ShelfLayoutObserverTest() | |
| 66 : changed_auto_hide_state_(false) { | |
| 67 } | |
| 68 | |
| 69 virtual ~ShelfLayoutObserverTest() {} | |
| 70 | |
| 71 bool changed_auto_hide_state() const { return changed_auto_hide_state_; } | |
| 72 | |
| 73 private: | |
| 74 virtual void OnAutoHideStateChanged( | |
| 75 ShelfAutoHideState new_state) OVERRIDE { | |
| 76 changed_auto_hide_state_ = true; | |
| 77 } | |
| 78 | |
| 79 bool changed_auto_hide_state_; | |
| 80 | |
| 81 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutObserverTest); | |
| 82 }; | |
| 83 | |
| 84 // Trivial item implementation that tracks its views for testing. | |
| 85 class TestItem : public SystemTrayItem { | |
| 86 public: | |
| 87 TestItem() | |
| 88 : SystemTrayItem(GetSystemTray()), | |
| 89 tray_view_(NULL), | |
| 90 default_view_(NULL), | |
| 91 detailed_view_(NULL), | |
| 92 notification_view_(NULL) {} | |
| 93 | |
| 94 virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE { | |
| 95 tray_view_ = new views::View; | |
| 96 // Add a label so it has non-zero width. | |
| 97 tray_view_->SetLayoutManager(new views::FillLayout); | |
| 98 tray_view_->AddChildView(new views::Label(UTF8ToUTF16("Tray"))); | |
| 99 return tray_view_; | |
| 100 } | |
| 101 | |
| 102 virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE { | |
| 103 default_view_ = new views::View; | |
| 104 default_view_->SetLayoutManager(new views::FillLayout); | |
| 105 default_view_->AddChildView(new views::Label(UTF8ToUTF16("Default"))); | |
| 106 return default_view_; | |
| 107 } | |
| 108 | |
| 109 virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE { | |
| 110 detailed_view_ = new views::View; | |
| 111 detailed_view_->SetLayoutManager(new views::FillLayout); | |
| 112 detailed_view_->AddChildView(new views::Label(UTF8ToUTF16("Detailed"))); | |
| 113 return detailed_view_; | |
| 114 } | |
| 115 | |
| 116 virtual views::View* CreateNotificationView( | |
| 117 user::LoginStatus status) OVERRIDE { | |
| 118 notification_view_ = new views::View; | |
| 119 return notification_view_; | |
| 120 } | |
| 121 | |
| 122 virtual void DestroyTrayView() OVERRIDE { | |
| 123 tray_view_ = NULL; | |
| 124 } | |
| 125 | |
| 126 virtual void DestroyDefaultView() OVERRIDE { | |
| 127 default_view_ = NULL; | |
| 128 } | |
| 129 | |
| 130 virtual void DestroyDetailedView() OVERRIDE { | |
| 131 detailed_view_ = NULL; | |
| 132 } | |
| 133 | |
| 134 virtual void DestroyNotificationView() OVERRIDE { | |
| 135 notification_view_ = NULL; | |
| 136 } | |
| 137 | |
| 138 virtual void UpdateAfterLoginStatusChange( | |
| 139 user::LoginStatus status) OVERRIDE {} | |
| 140 | |
| 141 views::View* tray_view() const { return tray_view_; } | |
| 142 views::View* default_view() const { return default_view_; } | |
| 143 views::View* detailed_view() const { return detailed_view_; } | |
| 144 views::View* notification_view() const { return notification_view_; } | |
| 145 | |
| 146 private: | |
| 147 views::View* tray_view_; | |
| 148 views::View* default_view_; | |
| 149 views::View* detailed_view_; | |
| 150 views::View* notification_view_; | |
| 151 | |
| 152 DISALLOW_COPY_AND_ASSIGN(TestItem); | |
| 153 }; | |
| 154 | |
| 155 } // namespace | |
| 156 | |
| 157 class ShelfLayoutManagerTest : public ash::test::AshTestBase { | |
| 158 public: | |
| 159 ShelfLayoutManagerTest() {} | |
| 160 | |
| 161 void SetState(ShelfLayoutManager* shelf, | |
| 162 ShelfVisibilityState state) { | |
| 163 shelf->SetState(state); | |
| 164 } | |
| 165 | |
| 166 void UpdateAutoHideStateNow() { | |
| 167 GetShelfLayoutManager()->UpdateAutoHideStateNow(); | |
| 168 } | |
| 169 | |
| 170 aura::Window* CreateTestWindow() { | |
| 171 aura::Window* window = new aura::Window(NULL); | |
| 172 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); | |
| 173 window->SetType(aura::client::WINDOW_TYPE_NORMAL); | |
| 174 window->Init(ui::LAYER_TEXTURED); | |
| 175 SetDefaultParentByPrimaryRootWindow(window); | |
| 176 return window; | |
| 177 } | |
| 178 | |
| 179 views::Widget* CreateTestWidgetWithParams( | |
| 180 const views::Widget::InitParams& params) { | |
| 181 views::Widget* out = new views::Widget; | |
| 182 out->Init(params); | |
| 183 out->Show(); | |
| 184 return out; | |
| 185 } | |
| 186 | |
| 187 // Create a simple widget attached to the current context (will | |
| 188 // delete on TearDown). | |
| 189 views::Widget* CreateTestWidget() { | |
| 190 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
| 191 params.bounds = gfx::Rect(0, 0, 200, 200); | |
| 192 params.context = CurrentContext(); | |
| 193 return CreateTestWidgetWithParams(params); | |
| 194 } | |
| 195 | |
| 196 // Overridden from AshTestBase: | |
| 197 virtual void SetUp() OVERRIDE { | |
| 198 CommandLine::ForCurrentProcess()->AppendSwitch( | |
| 199 ash::switches::kAshEnableTrayDragging); | |
| 200 test::AshTestBase::SetUp(); | |
| 201 } | |
| 202 private: | |
| 203 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerTest); | |
| 204 }; | |
| 205 | |
| 206 // Fails on Mac only. Need to be implemented. http://crbug.com/111279. | |
| 207 #if defined(OS_MACOSX) || defined(OS_WIN) | |
| 208 #define MAYBE_SetVisible DISABLED_SetVisible | |
| 209 #else | |
| 210 #define MAYBE_SetVisible SetVisible | |
| 211 #endif | |
| 212 // Makes sure SetVisible updates work area and widget appropriately. | |
| 213 TEST_F(ShelfLayoutManagerTest, MAYBE_SetVisible) { | |
| 214 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 215 // Force an initial layout. | |
| 216 shelf->LayoutShelf(); | |
| 217 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 218 | |
| 219 gfx::Rect status_bounds( | |
| 220 shelf->status_area_widget()->GetWindowBoundsInScreen()); | |
| 221 gfx::Rect launcher_bounds( | |
| 222 shelf->launcher_widget()->GetWindowBoundsInScreen()); | |
| 223 int shelf_height = shelf->GetIdealBounds().height(); | |
| 224 | |
| 225 const gfx::Display& display = Shell::GetInstance()->display_manager()-> | |
| 226 GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
| 227 ASSERT_NE(-1, display.id()); | |
| 228 // Bottom inset should be the max of widget heights. | |
| 229 EXPECT_EQ(shelf_height, | |
| 230 display.bounds().bottom() - display.work_area().bottom()); | |
| 231 | |
| 232 // Hide the shelf. | |
| 233 SetState(shelf, SHELF_HIDDEN); | |
| 234 // Run the animation to completion. | |
| 235 StepWidgetLayerAnimatorToEnd(shelf->launcher_widget()); | |
| 236 StepWidgetLayerAnimatorToEnd(shelf->status_area_widget()); | |
| 237 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); | |
| 238 EXPECT_EQ(0, | |
| 239 display.bounds().bottom() - display.work_area().bottom()); | |
| 240 | |
| 241 // Make sure the bounds of the two widgets changed. | |
| 242 EXPECT_GE(shelf->launcher_widget()->GetNativeView()->bounds().y(), | |
| 243 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom()); | |
| 244 EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(), | |
| 245 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom()); | |
| 246 | |
| 247 // And show it again. | |
| 248 SetState(shelf, SHELF_VISIBLE); | |
| 249 // Run the animation to completion. | |
| 250 StepWidgetLayerAnimatorToEnd(shelf->launcher_widget()); | |
| 251 StepWidgetLayerAnimatorToEnd(shelf->status_area_widget()); | |
| 252 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 253 EXPECT_EQ(shelf_height, | |
| 254 display.bounds().bottom() - display.work_area().bottom()); | |
| 255 | |
| 256 // Make sure the bounds of the two widgets changed. | |
| 257 launcher_bounds = shelf->launcher_widget()->GetNativeView()->bounds(); | |
| 258 int bottom = | |
| 259 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom() - shelf_height; | |
| 260 EXPECT_EQ(launcher_bounds.y(), | |
| 261 bottom + (shelf->GetIdealBounds().height() - | |
| 262 launcher_bounds.height()) / 2); | |
| 263 status_bounds = shelf->status_area_widget()->GetNativeView()->bounds(); | |
| 264 EXPECT_EQ(status_bounds.y(), | |
| 265 bottom + shelf_height - status_bounds.height()); | |
| 266 } | |
| 267 | |
| 268 // Makes sure LayoutShelf invoked while animating cleans things up. | |
| 269 TEST_F(ShelfLayoutManagerTest, LayoutShelfWhileAnimating) { | |
| 270 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 271 // Force an initial layout. | |
| 272 shelf->LayoutShelf(); | |
| 273 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 274 | |
| 275 const gfx::Display& display = Shell::GetInstance()->display_manager()-> | |
| 276 GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
| 277 | |
| 278 // Hide the shelf. | |
| 279 SetState(shelf, SHELF_HIDDEN); | |
| 280 shelf->LayoutShelf(); | |
| 281 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); | |
| 282 EXPECT_EQ(0, display.bounds().bottom() - display.work_area().bottom()); | |
| 283 | |
| 284 // Make sure the bounds of the two widgets changed. | |
| 285 EXPECT_GE(shelf->launcher_widget()->GetNativeView()->bounds().y(), | |
| 286 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom()); | |
| 287 EXPECT_GE(shelf->status_area_widget()->GetNativeView()->bounds().y(), | |
| 288 Shell::GetScreen()->GetPrimaryDisplay().bounds().bottom()); | |
| 289 } | |
| 290 | |
| 291 // Makes sure the launcher is initially sized correctly. | |
| 292 TEST_F(ShelfLayoutManagerTest, LauncherInitiallySized) { | |
| 293 Launcher* launcher = Launcher::ForPrimaryDisplay(); | |
| 294 ASSERT_TRUE(launcher); | |
| 295 ShelfLayoutManager* shelf_layout_manager = GetShelfLayoutManager(); | |
| 296 ASSERT_TRUE(shelf_layout_manager); | |
| 297 ASSERT_TRUE(shelf_layout_manager->status_area_widget()); | |
| 298 int status_width = shelf_layout_manager->status_area_widget()-> | |
| 299 GetWindowBoundsInScreen().width(); | |
| 300 // Test only makes sense if the status is > 0, which is better be. | |
| 301 EXPECT_GT(status_width, 0); | |
| 302 EXPECT_EQ(status_width, launcher->status_size().width()); | |
| 303 } | |
| 304 | |
| 305 // Makes sure the launcher is sized when the status area changes size. | |
| 306 TEST_F(ShelfLayoutManagerTest, LauncherUpdatedWhenStatusAreaChangesSize) { | |
| 307 Launcher* launcher = Launcher::ForPrimaryDisplay(); | |
| 308 ASSERT_TRUE(launcher); | |
| 309 ShelfLayoutManager* shelf_layout_manager = GetShelfLayoutManager(); | |
| 310 ASSERT_TRUE(shelf_layout_manager); | |
| 311 ASSERT_TRUE(shelf_layout_manager->status_area_widget()); | |
| 312 shelf_layout_manager->status_area_widget()->SetBounds( | |
| 313 gfx::Rect(0, 0, 200, 200)); | |
| 314 EXPECT_EQ(200, launcher->status_size().width()); | |
| 315 } | |
| 316 | |
| 317 // Verifies when the shell is deleted with a full screen window we don't | |
| 318 // crash. This test is here as originally the crash was in ShelfLayoutManager. | |
| 319 TEST_F(ShelfLayoutManagerTest, DontReferenceLauncherAfterDeletion) { | |
| 320 views::Widget* widget = new views::Widget; | |
| 321 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
| 322 params.bounds = gfx::Rect(0, 0, 200, 200); | |
| 323 params.context = CurrentContext(); | |
| 324 // Widget is now owned by the parent window. | |
| 325 widget->Init(params); | |
| 326 widget->SetFullscreen(true); | |
| 327 } | |
| 328 | |
| 329 #if defined(OS_WIN) | |
| 330 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962 | |
| 331 #define MAYBE_AutoHide DISABLED_AutoHide | |
| 332 #else | |
| 333 #define MAYBE_AutoHide AutoHide | |
| 334 #endif | |
| 335 | |
| 336 // Various assertions around auto-hide. | |
| 337 TEST_F(ShelfLayoutManagerTest, MAYBE_AutoHide) { | |
| 338 aura::RootWindow* root = Shell::GetPrimaryRootWindow(); | |
| 339 aura::test::EventGenerator generator(root, root); | |
| 340 generator.MoveMouseTo(0, 0); | |
| 341 | |
| 342 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 343 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 344 views::Widget* widget = new views::Widget; | |
| 345 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
| 346 params.bounds = gfx::Rect(0, 0, 200, 200); | |
| 347 params.context = CurrentContext(); | |
| 348 // Widget is now owned by the parent window. | |
| 349 widget->Init(params); | |
| 350 widget->Maximize(); | |
| 351 widget->Show(); | |
| 352 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 353 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 354 | |
| 355 // LayoutShelf() forces the animation to completion, at which point the | |
| 356 // launcher should go off the screen. | |
| 357 shelf->LayoutShelf(); | |
| 358 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, | |
| 359 shelf->launcher_widget()->GetWindowBoundsInScreen().y()); | |
| 360 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, | |
| 361 Shell::GetScreen()->GetDisplayNearestWindow( | |
| 362 root).work_area().bottom()); | |
| 363 | |
| 364 // Move the mouse to the bottom of the screen. | |
| 365 generator.MoveMouseTo(0, root->bounds().bottom() - 1); | |
| 366 | |
| 367 // Shelf should be shown again (but it shouldn't have changed the work area). | |
| 368 SetState(shelf, SHELF_AUTO_HIDE); | |
| 369 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
| 370 shelf->LayoutShelf(); | |
| 371 EXPECT_EQ(root->bounds().bottom() - shelf->GetIdealBounds().height(), | |
| 372 shelf->launcher_widget()->GetWindowBoundsInScreen().y()); | |
| 373 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, | |
| 374 Shell::GetScreen()->GetDisplayNearestWindow( | |
| 375 root).work_area().bottom()); | |
| 376 | |
| 377 // Move mouse back up. | |
| 378 generator.MoveMouseTo(0, 0); | |
| 379 SetState(shelf, SHELF_AUTO_HIDE); | |
| 380 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 381 shelf->LayoutShelf(); | |
| 382 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, | |
| 383 shelf->launcher_widget()->GetWindowBoundsInScreen().y()); | |
| 384 | |
| 385 // Drag mouse to bottom of screen. | |
| 386 generator.PressLeftButton(); | |
| 387 generator.MoveMouseTo(0, root->bounds().bottom() - 1); | |
| 388 UpdateAutoHideStateNow(); | |
| 389 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 390 | |
| 391 generator.ReleaseLeftButton(); | |
| 392 generator.MoveMouseTo(1, root->bounds().bottom() - 1); | |
| 393 UpdateAutoHideStateNow(); | |
| 394 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
| 395 generator.PressLeftButton(); | |
| 396 generator.MoveMouseTo(1, root->bounds().bottom() - 1); | |
| 397 UpdateAutoHideStateNow(); | |
| 398 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
| 399 } | |
| 400 | |
| 401 // Assertions around the lock screen showing. | |
| 402 TEST_F(ShelfLayoutManagerTest, VisibleWhenLockScreenShowing) { | |
| 403 // Since ShelfLayoutManager queries for mouse location, move the mouse so | |
| 404 // it isn't over the shelf. | |
| 405 aura::test::EventGenerator generator( | |
| 406 Shell::GetPrimaryRootWindow(), gfx::Point()); | |
| 407 generator.MoveMouseTo(0, 0); | |
| 408 | |
| 409 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 410 shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 411 views::Widget* widget = new views::Widget; | |
| 412 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
| 413 params.bounds = gfx::Rect(0, 0, 200, 200); | |
| 414 params.context = CurrentContext(); | |
| 415 // Widget is now owned by the parent window. | |
| 416 widget->Init(params); | |
| 417 widget->Maximize(); | |
| 418 widget->Show(); | |
| 419 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 420 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 421 | |
| 422 aura::RootWindow* root = Shell::GetPrimaryRootWindow(); | |
| 423 // LayoutShelf() forces the animation to completion, at which point the | |
| 424 // launcher should go off the screen. | |
| 425 shelf->LayoutShelf(); | |
| 426 EXPECT_EQ(root->bounds().bottom() - ShelfLayoutManager::kAutoHideSize, | |
| 427 shelf->launcher_widget()->GetWindowBoundsInScreen().y()); | |
| 428 | |
| 429 aura::Window* lock_container = Shell::GetContainer( | |
| 430 Shell::GetPrimaryRootWindow(), | |
| 431 internal::kShellWindowId_LockScreenContainer); | |
| 432 | |
| 433 views::Widget* lock_widget = new views::Widget; | |
| 434 views::Widget::InitParams lock_params( | |
| 435 views::Widget::InitParams::TYPE_WINDOW); | |
| 436 lock_params.bounds = gfx::Rect(0, 0, 200, 200); | |
| 437 params.context = CurrentContext(); | |
| 438 lock_params.parent = lock_container; | |
| 439 // Widget is now owned by the parent window. | |
| 440 lock_widget->Init(lock_params); | |
| 441 lock_widget->Maximize(); | |
| 442 lock_widget->Show(); | |
| 443 | |
| 444 // Lock the screen. | |
| 445 Shell::GetInstance()->delegate()->LockScreen(); | |
| 446 shelf->UpdateVisibilityState(); | |
| 447 // Showing a widget in the lock screen should force the shelf to be visibile. | |
| 448 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 449 | |
| 450 Shell::GetInstance()->delegate()->UnlockScreen(); | |
| 451 shelf->UpdateVisibilityState(); | |
| 452 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 453 } | |
| 454 | |
| 455 // Assertions around SetAutoHideBehavior. | |
| 456 TEST_F(ShelfLayoutManagerTest, SetAutoHideBehavior) { | |
| 457 // Since ShelfLayoutManager queries for mouse location, move the mouse so | |
| 458 // it isn't over the shelf. | |
| 459 aura::test::EventGenerator generator( | |
| 460 Shell::GetPrimaryRootWindow(), gfx::Point()); | |
| 461 generator.MoveMouseTo(0, 0); | |
| 462 | |
| 463 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 464 views::Widget* widget = new views::Widget; | |
| 465 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
| 466 params.bounds = gfx::Rect(0, 0, 200, 200); | |
| 467 params.context = CurrentContext(); | |
| 468 // Widget is now owned by the parent window. | |
| 469 widget->Init(params); | |
| 470 widget->Show(); | |
| 471 aura::Window* window = widget->GetNativeWindow(); | |
| 472 gfx::Rect display_bounds( | |
| 473 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds()); | |
| 474 | |
| 475 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 476 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 477 | |
| 478 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
| 479 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 480 | |
| 481 widget->Maximize(); | |
| 482 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 483 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow( | |
| 484 window).work_area().bottom(), | |
| 485 widget->GetWorkAreaBoundsInScreen().bottom()); | |
| 486 | |
| 487 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 488 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 489 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow( | |
| 490 window).work_area().bottom(), | |
| 491 widget->GetWorkAreaBoundsInScreen().bottom()); | |
| 492 | |
| 493 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
| 494 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 495 EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow( | |
| 496 window).work_area().bottom(), | |
| 497 widget->GetWorkAreaBoundsInScreen().bottom()); | |
| 498 } | |
| 499 | |
| 500 // Verifies the shelf is visible when status/launcher is focused. | |
| 501 TEST_F(ShelfLayoutManagerTest, VisibleWhenStatusOrLauncherFocused) { | |
| 502 // Since ShelfLayoutManager queries for mouse location, move the mouse so | |
| 503 // it isn't over the shelf. | |
| 504 aura::test::EventGenerator generator( | |
| 505 Shell::GetPrimaryRootWindow(), gfx::Point()); | |
| 506 generator.MoveMouseTo(0, 0); | |
| 507 | |
| 508 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 509 views::Widget* widget = new views::Widget; | |
| 510 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
| 511 params.bounds = gfx::Rect(0, 0, 200, 200); | |
| 512 params.context = CurrentContext(); | |
| 513 // Widget is now owned by the parent window. | |
| 514 widget->Init(params); | |
| 515 widget->Show(); | |
| 516 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 517 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 518 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 519 | |
| 520 // Focus the launcher. Have to go through the focus cycler as normal focus | |
| 521 // requests to it do nothing. | |
| 522 shelf->launcher()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD); | |
| 523 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
| 524 | |
| 525 widget->Activate(); | |
| 526 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 527 | |
| 528 // Trying to activate the status should fail, since we only allow activating | |
| 529 // it when the user is using the keyboard (i.e. through FocusCycler). | |
| 530 shelf->status_area_widget()->Activate(); | |
| 531 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 532 | |
| 533 shelf->launcher()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD); | |
| 534 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
| 535 } | |
| 536 | |
| 537 // Makes sure shelf will be visible when app list opens as shelf is in | |
| 538 // SHELF_VISIBLE state,and toggling app list won't change shelf | |
| 539 // visibility state. | |
| 540 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfVisibleState) { | |
| 541 Shell* shell = Shell::GetInstance(); | |
| 542 internal::RootWindowController* controller = | |
| 543 Shell::GetPrimaryRootWindowController(); | |
| 544 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 545 shelf->LayoutShelf(); | |
| 546 controller->SetShelfAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
| 547 | |
| 548 // Create a normal unmaximized windowm shelf should be visible. | |
| 549 aura::Window* window = CreateTestWindow(); | |
| 550 window->SetBounds(gfx::Rect(0, 0, 100, 100)); | |
| 551 window->Show(); | |
| 552 EXPECT_FALSE(shell->GetAppListTargetVisibility()); | |
| 553 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 554 | |
| 555 // Toggle app list to show, and the shelf stays visible. | |
| 556 shell->ToggleAppList(NULL); | |
| 557 EXPECT_TRUE(shell->GetAppListTargetVisibility()); | |
| 558 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 559 | |
| 560 // Toggle app list to hide, and the shelf stays visible. | |
| 561 shell->ToggleAppList(NULL); | |
| 562 EXPECT_FALSE(shell->GetAppListTargetVisibility()); | |
| 563 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 564 } | |
| 565 | |
| 566 // Makes sure shelf will be shown with SHELF_AUTO_HIDE_SHOWN state | |
| 567 // when app list opens as shelf is in SHELF_AUTO_HIDE state, and | |
| 568 // toggling app list won't change shelf visibility state. | |
| 569 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfAutoHideState) { | |
| 570 Shell* shell = Shell::GetInstance(); | |
| 571 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 572 internal::RootWindowController* controller = | |
| 573 Shell::GetPrimaryRootWindowController(); | |
| 574 shelf->LayoutShelf(); | |
| 575 controller->SetShelfAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 576 | |
| 577 // Create a window and show it in maximized state. | |
| 578 aura::Window* window = CreateTestWindow(); | |
| 579 window->SetBounds(gfx::Rect(0, 0, 100, 100)); | |
| 580 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); | |
| 581 window->Show(); | |
| 582 wm::ActivateWindow(window); | |
| 583 | |
| 584 EXPECT_FALSE(shell->GetAppListTargetVisibility()); | |
| 585 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 586 | |
| 587 // Toggle app list to show. | |
| 588 shell->ToggleAppList(NULL); | |
| 589 // The shelf's auto hide state won't be changed until the timer fires, so | |
| 590 // calling shell->UpdateShelfVisibility() is kind of manually helping it to | |
| 591 // update the state. | |
| 592 shell->UpdateShelfVisibility(); | |
| 593 EXPECT_TRUE(shell->GetAppListTargetVisibility()); | |
| 594 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 595 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
| 596 | |
| 597 // Toggle app list to hide. | |
| 598 shell->ToggleAppList(NULL); | |
| 599 EXPECT_FALSE(shell->GetAppListTargetVisibility()); | |
| 600 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 601 } | |
| 602 | |
| 603 // Makes sure shelf will be hidden when app list opens as shelf is in HIDDEN | |
| 604 // state, and toggling app list won't change shelf visibility state. | |
| 605 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfHiddenState) { | |
| 606 Shell* shell = Shell::GetInstance(); | |
| 607 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 608 // For shelf to be visible, app list is not open in initial state. | |
| 609 shelf->LayoutShelf(); | |
| 610 | |
| 611 // Create a window and make it full screen. | |
| 612 aura::Window* window = CreateTestWindow(); | |
| 613 window->SetBounds(gfx::Rect(0, 0, 100, 100)); | |
| 614 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN); | |
| 615 window->Show(); | |
| 616 wm::ActivateWindow(window); | |
| 617 | |
| 618 // App list and shelf is not shown. | |
| 619 EXPECT_FALSE(shell->GetAppListTargetVisibility()); | |
| 620 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); | |
| 621 | |
| 622 // Toggle app list to show. | |
| 623 shell->ToggleAppList(NULL); | |
| 624 EXPECT_TRUE(shell->GetAppListTargetVisibility()); | |
| 625 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); | |
| 626 | |
| 627 // Toggle app list to hide. | |
| 628 shell->ToggleAppList(NULL); | |
| 629 EXPECT_FALSE(shell->GetAppListTargetVisibility()); | |
| 630 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); | |
| 631 } | |
| 632 | |
| 633 #if defined(OS_WIN) | |
| 634 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962 | |
| 635 #define MAYBE_SetAlignment DISABLED_SetAlignment | |
| 636 #else | |
| 637 #define MAYBE_SetAlignment SetAlignment | |
| 638 #endif | |
| 639 | |
| 640 // Tests SHELF_ALIGNMENT_(LEFT, RIGHT, TOP). | |
| 641 TEST_F(ShelfLayoutManagerTest, MAYBE_SetAlignment) { | |
| 642 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 643 // Force an initial layout. | |
| 644 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
| 645 shelf->LayoutShelf(); | |
| 646 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 647 | |
| 648 shelf->SetAlignment(SHELF_ALIGNMENT_LEFT); | |
| 649 gfx::Rect launcher_bounds( | |
| 650 shelf->launcher_widget()->GetWindowBoundsInScreen()); | |
| 651 const internal::DisplayManager* manager = | |
| 652 Shell::GetInstance()->display_manager(); | |
| 653 gfx::Display display = | |
| 654 manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
| 655 ASSERT_NE(-1, display.id()); | |
| 656 EXPECT_EQ(shelf->GetIdealBounds().width(), | |
| 657 display.GetWorkAreaInsets().left()); | |
| 658 EXPECT_GE( | |
| 659 launcher_bounds.width(), | |
| 660 shelf->launcher_widget()->GetContentsView()->GetPreferredSize().width()); | |
| 661 EXPECT_EQ(SHELF_ALIGNMENT_LEFT, GetSystemTray()->shelf_alignment()); | |
| 662 StatusAreaWidget* status_area_widget = shelf->status_area_widget(); | |
| 663 gfx::Rect status_bounds(status_area_widget->GetWindowBoundsInScreen()); | |
| 664 EXPECT_GE(status_bounds.width(), | |
| 665 status_area_widget->GetContentsView()->GetPreferredSize().width()); | |
| 666 EXPECT_EQ(shelf->GetIdealBounds().width(), | |
| 667 display.GetWorkAreaInsets().left()); | |
| 668 EXPECT_EQ(0, display.GetWorkAreaInsets().top()); | |
| 669 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom()); | |
| 670 EXPECT_EQ(0, display.GetWorkAreaInsets().right()); | |
| 671 EXPECT_EQ(display.bounds().x(), launcher_bounds.x()); | |
| 672 EXPECT_EQ(display.bounds().y(), launcher_bounds.y()); | |
| 673 EXPECT_EQ(display.bounds().height(), launcher_bounds.height()); | |
| 674 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 675 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
| 676 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, | |
| 677 display.GetWorkAreaInsets().left()); | |
| 678 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, display.work_area().x()); | |
| 679 | |
| 680 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
| 681 shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT); | |
| 682 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
| 683 launcher_bounds = shelf->launcher_widget()->GetWindowBoundsInScreen(); | |
| 684 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
| 685 ASSERT_NE(-1, display.id()); | |
| 686 EXPECT_EQ(shelf->GetIdealBounds().width(), | |
| 687 display.GetWorkAreaInsets().right()); | |
| 688 EXPECT_GE(launcher_bounds.width(), | |
| 689 shelf->launcher_widget()->GetContentsView()->GetPreferredSize().width()); | |
| 690 EXPECT_EQ(SHELF_ALIGNMENT_RIGHT, GetSystemTray()->shelf_alignment()); | |
| 691 status_bounds = gfx::Rect(status_area_widget->GetWindowBoundsInScreen()); | |
| 692 EXPECT_GE(status_bounds.width(), | |
| 693 status_area_widget->GetContentsView()->GetPreferredSize().width()); | |
| 694 EXPECT_EQ(shelf->GetIdealBounds().width(), | |
| 695 display.GetWorkAreaInsets().right()); | |
| 696 EXPECT_EQ(0, display.GetWorkAreaInsets().top()); | |
| 697 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom()); | |
| 698 EXPECT_EQ(0, display.GetWorkAreaInsets().left()); | |
| 699 EXPECT_EQ(display.work_area().right(), launcher_bounds.x()); | |
| 700 EXPECT_EQ(display.bounds().y(), launcher_bounds.y()); | |
| 701 EXPECT_EQ(display.bounds().height(), launcher_bounds.height()); | |
| 702 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 703 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
| 704 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, | |
| 705 display.GetWorkAreaInsets().right()); | |
| 706 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, | |
| 707 display.bounds().right() - display.work_area().right()); | |
| 708 | |
| 709 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
| 710 shelf->SetAlignment(SHELF_ALIGNMENT_TOP); | |
| 711 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
| 712 launcher_bounds = shelf->launcher_widget()->GetWindowBoundsInScreen(); | |
| 713 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
| 714 ASSERT_NE(-1, display.id()); | |
| 715 EXPECT_EQ(shelf->GetIdealBounds().height(), | |
| 716 display.GetWorkAreaInsets().top()); | |
| 717 EXPECT_GE(launcher_bounds.height(), | |
| 718 shelf->launcher_widget()->GetContentsView()->GetPreferredSize().height()); | |
| 719 EXPECT_EQ(SHELF_ALIGNMENT_TOP, GetSystemTray()->shelf_alignment()); | |
| 720 status_bounds = gfx::Rect(status_area_widget->GetWindowBoundsInScreen()); | |
| 721 EXPECT_GE(status_bounds.height(), | |
| 722 status_area_widget->GetContentsView()->GetPreferredSize().height()); | |
| 723 EXPECT_EQ(shelf->GetIdealBounds().height(), | |
| 724 display.GetWorkAreaInsets().top()); | |
| 725 EXPECT_EQ(0, display.GetWorkAreaInsets().right()); | |
| 726 EXPECT_EQ(0, display.GetWorkAreaInsets().bottom()); | |
| 727 EXPECT_EQ(0, display.GetWorkAreaInsets().left()); | |
| 728 EXPECT_EQ(display.work_area().y(), launcher_bounds.bottom()); | |
| 729 EXPECT_EQ(display.bounds().x(), launcher_bounds.x()); | |
| 730 EXPECT_EQ(display.bounds().width(), launcher_bounds.width()); | |
| 731 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 732 display = manager->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow()); | |
| 733 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, | |
| 734 display.GetWorkAreaInsets().top()); | |
| 735 EXPECT_EQ(ShelfLayoutManager::kAutoHideSize, | |
| 736 display.work_area().y() - display.bounds().y()); | |
| 737 } | |
| 738 | |
| 739 #if defined(OS_WIN) | |
| 740 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962 | |
| 741 #define MAYBE_GestureDrag DISABLED_GestureDrag | |
| 742 #else | |
| 743 #define MAYBE_GestureDrag GestureDrag | |
| 744 #endif | |
| 745 | |
| 746 TEST_F(ShelfLayoutManagerTest, MAYBE_GestureDrag) { | |
| 747 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 748 internal::RootWindowController* controller = | |
| 749 Shell::GetPrimaryRootWindowController(); | |
| 750 controller->SetShelfAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
| 751 shelf->LayoutShelf(); | |
| 752 | |
| 753 views::Widget* widget = new views::Widget; | |
| 754 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
| 755 params.bounds = gfx::Rect(0, 0, 200, 200); | |
| 756 params.context = CurrentContext(); | |
| 757 widget->Init(params); | |
| 758 widget->Show(); | |
| 759 widget->Maximize(); | |
| 760 | |
| 761 aura::Window* window = widget->GetNativeWindow(); | |
| 762 | |
| 763 gfx::Rect shelf_shown = shelf->launcher_widget()->GetWindowBoundsInScreen(); | |
| 764 gfx::Rect bounds_shelf = window->bounds(); | |
| 765 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 766 | |
| 767 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); | |
| 768 | |
| 769 // Swipe up on the shelf. This should not change any state. | |
| 770 gfx::Point start = | |
| 771 shelf->launcher_widget()->GetWindowBoundsInScreen().CenterPoint(); | |
| 772 gfx::Point end(start.x(), start.y() + 100); | |
| 773 | |
| 774 // Swipe down on the shelf to hide it. | |
| 775 end.set_y(start.y() + 100); | |
| 776 generator.GestureScrollSequence(start, end, | |
| 777 base::TimeDelta::FromMilliseconds(10), 1); | |
| 778 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 779 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 780 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); | |
| 781 EXPECT_NE(bounds_shelf.ToString(), window->bounds().ToString()); | |
| 782 EXPECT_NE(shelf_shown.ToString(), | |
| 783 shelf->launcher_widget()->GetWindowBoundsInScreen().ToString()); | |
| 784 | |
| 785 gfx::Rect bounds_noshelf = window->bounds(); | |
| 786 gfx::Rect shelf_hidden = shelf->launcher_widget()->GetWindowBoundsInScreen(); | |
| 787 | |
| 788 // Swipe up to show the shelf. | |
| 789 generator.GestureScrollSequence(end, start, | |
| 790 base::TimeDelta::FromMilliseconds(10), 1); | |
| 791 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 792 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); | |
| 793 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString()); | |
| 794 EXPECT_EQ(shelf_shown.ToString(), | |
| 795 shelf->launcher_widget()->GetWindowBoundsInScreen().ToString()); | |
| 796 | |
| 797 // Swipe up again. The shelf should hide. | |
| 798 end.set_y(start.y() - 100); | |
| 799 generator.GestureScrollSequence(start, end, | |
| 800 base::TimeDelta::FromMilliseconds(10), 1); | |
| 801 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 802 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 803 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); | |
| 804 EXPECT_EQ(shelf_hidden.ToString(), | |
| 805 shelf->launcher_widget()->GetWindowBoundsInScreen().ToString()); | |
| 806 | |
| 807 // Swipe up yet again to show it. | |
| 808 end.set_y(start.y() + 100); | |
| 809 generator.GestureScrollSequence(end, start, | |
| 810 base::TimeDelta::FromMilliseconds(10), 1); | |
| 811 | |
| 812 // Swipe down very little. It shouldn't change any state. | |
| 813 end.set_y(start.y() + shelf_shown.height() * 3 / 10); | |
| 814 generator.GestureScrollSequence(start, end, | |
| 815 base::TimeDelta::FromMilliseconds(100), 1); | |
| 816 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 817 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); | |
| 818 EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString()); | |
| 819 EXPECT_EQ(shelf_shown.ToString(), | |
| 820 shelf->launcher_widget()->GetWindowBoundsInScreen().ToString()); | |
| 821 | |
| 822 // Swipe down again to hide. | |
| 823 end.set_y(start.y() + 100); | |
| 824 generator.GestureScrollSequence(start, end, | |
| 825 base::TimeDelta::FromMilliseconds(10), 1); | |
| 826 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 827 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 828 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); | |
| 829 EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString()); | |
| 830 EXPECT_EQ(shelf_hidden.ToString(), | |
| 831 shelf->launcher_widget()->GetWindowBoundsInScreen().ToString()); | |
| 832 | |
| 833 // Swipe up yet again to show it. | |
| 834 end.set_y(start.y() + 100); | |
| 835 generator.GestureScrollSequence(end, start, | |
| 836 base::TimeDelta::FromMilliseconds(10), 1); | |
| 837 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 838 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); | |
| 839 | |
| 840 // Tap on the shelf itself. This should not change anything. | |
| 841 generator.GestureTapAt(start); | |
| 842 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 843 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); | |
| 844 | |
| 845 // Now, tap on the desktop region (above the shelf). This should hide the | |
| 846 // shelf. | |
| 847 gfx::Point tap = start + gfx::Vector2d(0, -90); | |
| 848 generator.GestureTapAt(tap); | |
| 849 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 850 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 851 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); | |
| 852 | |
| 853 // Make the window fullscreen. | |
| 854 widget->SetFullscreen(true); | |
| 855 gfx::Rect bounds_fullscreen = window->bounds(); | |
| 856 EXPECT_TRUE(widget->IsFullscreen()); | |
| 857 EXPECT_NE(bounds_noshelf.ToString(), bounds_fullscreen.ToString()); | |
| 858 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); | |
| 859 | |
| 860 // Swipe-up. This should not change anything. | |
| 861 generator.GestureScrollSequence(end, start, | |
| 862 base::TimeDelta::FromMilliseconds(10), 1); | |
| 863 EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state()); | |
| 864 EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); | |
| 865 EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString()); | |
| 866 } | |
| 867 | |
| 868 TEST_F(ShelfLayoutManagerTest, WindowVisibilityDisablesAutoHide) { | |
| 869 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 870 shelf->LayoutShelf(); | |
| 871 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 872 | |
| 873 // Create a visible window so auto-hide behavior is enforced | |
| 874 views::Widget* dummy = CreateTestWidget(); | |
| 875 | |
| 876 // Window visible => auto hide behaves normally. | |
| 877 shelf->UpdateVisibilityState(); | |
| 878 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 879 | |
| 880 // Window minimized => auto hide disabled. | |
| 881 dummy->Minimize(); | |
| 882 shelf->UpdateVisibilityState(); | |
| 883 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
| 884 | |
| 885 // Window closed => auto hide disabled. | |
| 886 dummy->CloseNow(); | |
| 887 shelf->UpdateVisibilityState(); | |
| 888 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
| 889 | |
| 890 // Multiple window test | |
| 891 views::Widget* window1 = CreateTestWidget(); | |
| 892 views::Widget* window2 = CreateTestWidget(); | |
| 893 | |
| 894 // both visible => normal autohide | |
| 895 shelf->UpdateVisibilityState(); | |
| 896 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 897 | |
| 898 // either minimzed => normal autohide | |
| 899 window2->Minimize(); | |
| 900 shelf->UpdateVisibilityState(); | |
| 901 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 902 window2->Restore(); | |
| 903 window1->Minimize(); | |
| 904 shelf->UpdateVisibilityState(); | |
| 905 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 906 | |
| 907 // both minimzed => disable auto hide | |
| 908 window2->Minimize(); | |
| 909 shelf->UpdateVisibilityState(); | |
| 910 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
| 911 } | |
| 912 | |
| 913 #if defined(OS_WIN) | |
| 914 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962 | |
| 915 #define MAYBE_GestureRevealsTrayBubble DISABLED_GestureRevealsTrayBubble | |
| 916 #else | |
| 917 #define MAYBE_GestureRevealsTrayBubble GestureRevealsTrayBubble | |
| 918 #endif | |
| 919 | |
| 920 TEST_F(ShelfLayoutManagerTest, MAYBE_GestureRevealsTrayBubble) { | |
| 921 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 922 shelf->LayoutShelf(); | |
| 923 | |
| 924 // Create a visible window so auto-hide behavior is enforced. | |
| 925 CreateTestWidget(); | |
| 926 | |
| 927 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); | |
| 928 SystemTray* tray = GetSystemTray(); | |
| 929 | |
| 930 // First, make sure the shelf is visible. | |
| 931 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
| 932 EXPECT_FALSE(tray->HasSystemBubble()); | |
| 933 | |
| 934 // Now, drag up on the tray to show the bubble. | |
| 935 gfx::Point start = | |
| 936 shelf->status_area_widget()->GetWindowBoundsInScreen().CenterPoint(); | |
| 937 gfx::Point end(start.x(), start.y() - 100); | |
| 938 generator.GestureScrollSequence(start, end, | |
| 939 base::TimeDelta::FromMilliseconds(10), 1); | |
| 940 EXPECT_TRUE(tray->HasSystemBubble()); | |
| 941 tray->CloseBubbleForTest(); | |
| 942 RunAllPendingInMessageLoop(); | |
| 943 EXPECT_FALSE(tray->HasSystemBubble()); | |
| 944 | |
| 945 // Drag again, but only a small amount, and slowly. The bubble should not be | |
| 946 // visible. | |
| 947 end.set_y(start.y() - 30); | |
| 948 generator.GestureScrollSequence(start, end, | |
| 949 base::TimeDelta::FromMilliseconds(500), 100); | |
| 950 EXPECT_FALSE(tray->HasSystemBubble()); | |
| 951 | |
| 952 // Now, hide the shelf. | |
| 953 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 954 | |
| 955 // Start a drag from the bezel, and drag up to show both the shelf and the | |
| 956 // tray bubble. | |
| 957 start.set_y(start.y() + 100); | |
| 958 end.set_y(start.y() - 400); | |
| 959 generator.GestureScrollSequence(start, end, | |
| 960 base::TimeDelta::FromMilliseconds(10), 1); | |
| 961 EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state()); | |
| 962 EXPECT_TRUE(tray->HasSystemBubble()); | |
| 963 } | |
| 964 | |
| 965 TEST_F(ShelfLayoutManagerTest, ShelfFlickerOnTrayActivation) { | |
| 966 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 967 | |
| 968 // Create a visible window so auto-hide behavior is enforced. | |
| 969 CreateTestWidget(); | |
| 970 | |
| 971 // Turn on auto-hide for the shelf. | |
| 972 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 973 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 974 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
| 975 | |
| 976 // Show the status menu. That should make the shelf visible again. | |
| 977 Shell::GetInstance()->accelerator_controller()->PerformAction( | |
| 978 SHOW_SYSTEM_TRAY_BUBBLE, ui::Accelerator()); | |
| 979 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 980 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
| 981 EXPECT_TRUE(GetSystemTray()->HasSystemBubble()); | |
| 982 | |
| 983 // Now activate the tray (using the keyboard, instead of using the mouse to | |
| 984 // make sure the mouse does not alter the auto-hide state in the shelf). | |
| 985 // This should not trigger any auto-hide state change in the shelf. | |
| 986 ShelfLayoutObserverTest observer; | |
| 987 shelf->AddObserver(&observer); | |
| 988 | |
| 989 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); | |
| 990 generator.PressKey(ui::VKEY_SPACE, 0); | |
| 991 generator.ReleaseKey(ui::VKEY_SPACE, 0); | |
| 992 EXPECT_TRUE(GetSystemTray()->HasSystemBubble()); | |
| 993 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state()); | |
| 994 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state()); | |
| 995 EXPECT_FALSE(observer.changed_auto_hide_state()); | |
| 996 | |
| 997 shelf->RemoveObserver(&observer); | |
| 998 } | |
| 999 | |
| 1000 TEST_F(ShelfLayoutManagerTest, WorkAreaChangeWorkspace) { | |
| 1001 // Make sure the shelf is always visible. | |
| 1002 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 1003 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
| 1004 shelf->LayoutShelf(); | |
| 1005 | |
| 1006 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
| 1007 params.bounds = gfx::Rect(0, 0, 200, 200); | |
| 1008 params.context = CurrentContext(); | |
| 1009 views::Widget* widget_one = CreateTestWidgetWithParams(params); | |
| 1010 widget_one->Maximize(); | |
| 1011 | |
| 1012 views::Widget* widget_two = CreateTestWidgetWithParams(params); | |
| 1013 widget_two->Maximize(); | |
| 1014 widget_two->Activate(); | |
| 1015 | |
| 1016 // Both windows are maximized. They should be of the same size. | |
| 1017 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(), | |
| 1018 widget_two->GetNativeWindow()->bounds().ToString()); | |
| 1019 | |
| 1020 // Now hide the shelf. | |
| 1021 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 1022 | |
| 1023 // The active maximized window will get resized to the new work area. However, | |
| 1024 // the inactive window should not get resized. | |
| 1025 EXPECT_NE(widget_one->GetNativeWindow()->bounds().ToString(), | |
| 1026 widget_two->GetNativeWindow()->bounds().ToString()); | |
| 1027 | |
| 1028 // Activate the first window. Now, both windows should be of the same size | |
| 1029 // again. | |
| 1030 widget_one->Activate(); | |
| 1031 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(), | |
| 1032 widget_two->GetNativeWindow()->bounds().ToString()); | |
| 1033 | |
| 1034 // Now show the shelf. | |
| 1035 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
| 1036 | |
| 1037 // The active maximized window will get resized to the new work area. However, | |
| 1038 // the inactive window should not get resized. | |
| 1039 EXPECT_NE(widget_one->GetNativeWindow()->bounds().ToString(), | |
| 1040 widget_two->GetNativeWindow()->bounds().ToString()); | |
| 1041 | |
| 1042 // Activate the first window. Now, both windows should be of the same size | |
| 1043 // again. | |
| 1044 widget_two->Activate(); | |
| 1045 EXPECT_EQ(widget_one->GetNativeWindow()->bounds().ToString(), | |
| 1046 widget_two->GetNativeWindow()->bounds().ToString()); | |
| 1047 } | |
| 1048 | |
| 1049 // Confirm that the shelf is dimmed only when content is maximized and | |
| 1050 // shelf is not autohidden. | |
| 1051 TEST_F(ShelfLayoutManagerTest, Dimming) { | |
| 1052 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
| 1053 scoped_ptr<aura::Window> w1(CreateTestWindow()); | |
| 1054 w1->Show(); | |
| 1055 wm::ActivateWindow(w1.get()); | |
| 1056 | |
| 1057 // Normal window doesn't dim shelf. | |
| 1058 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); | |
| 1059 Launcher* launcher = Launcher::ForPrimaryDisplay(); | |
| 1060 EXPECT_FALSE(launcher->GetDimsShelf()); | |
| 1061 | |
| 1062 // Maximized window does. | |
| 1063 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); | |
| 1064 EXPECT_TRUE(launcher->GetDimsShelf()); | |
| 1065 | |
| 1066 // Change back to normal stops dimming. | |
| 1067 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); | |
| 1068 EXPECT_FALSE(launcher->GetDimsShelf()); | |
| 1069 | |
| 1070 // Changing back to maximized dims again. | |
| 1071 w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); | |
| 1072 EXPECT_TRUE(launcher->GetDimsShelf()); | |
| 1073 | |
| 1074 // Changing shelf to autohide stops dimming. | |
| 1075 GetShelfLayoutManager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 1076 EXPECT_FALSE(launcher->GetDimsShelf()); | |
| 1077 } | |
| 1078 | |
| 1079 // Make sure that the shelf will not hide if the mouse is between a bubble and | |
| 1080 // the shelf. | |
| 1081 TEST_F(ShelfLayoutManagerTest, BubbleEnlargesShelfMouseHitArea) { | |
| 1082 ShelfLayoutManager* shelf = GetShelfLayoutManager(); | |
| 1083 StatusAreaWidget* status_area_widget = | |
| 1084 Shell::GetPrimaryRootWindowController()->status_area_widget(); | |
| 1085 SystemTray* tray = GetSystemTray(); | |
| 1086 | |
| 1087 // Create a visible window so auto-hide behavior is enforced. | |
| 1088 CreateTestWidget(); | |
| 1089 | |
| 1090 shelf->LayoutShelf(); | |
| 1091 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); | |
| 1092 | |
| 1093 // Make two iterations - first without a message bubble which should make | |
| 1094 // the shelf disappear and then with a message bubble which should keep it | |
| 1095 // visible. | |
| 1096 for (int i = 0; i < 2; i++) { | |
| 1097 // Make sure the shelf is visible and position the mouse over it. Then | |
| 1098 // allow auto hide. | |
| 1099 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
| 1100 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); | |
| 1101 gfx::Point center = | |
| 1102 status_area_widget->GetWindowBoundsInScreen().CenterPoint(); | |
| 1103 generator.MoveMouseTo(center.x(), center.y()); | |
| 1104 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | |
| 1105 EXPECT_TRUE(shelf->IsVisible()); | |
| 1106 if (!i) { | |
| 1107 // In our first iteration we make sure there is no bubble. | |
| 1108 tray->CloseBubbleForTest(); | |
| 1109 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); | |
| 1110 } else { | |
| 1111 // In our second iteration we show a bubble. | |
| 1112 TestItem *item = new TestItem; | |
| 1113 tray->AddTrayItem(item); | |
| 1114 tray->ShowNotificationView(item); | |
| 1115 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown()); | |
| 1116 } | |
| 1117 // Move the pointer over the edge of the shelf. | |
| 1118 generator.MoveMouseTo( | |
| 1119 center.x(), status_area_widget->GetWindowBoundsInScreen().y() - 8); | |
| 1120 shelf->UpdateVisibilityState(); | |
| 1121 if (i) { | |
| 1122 EXPECT_TRUE(shelf->IsVisible()); | |
| 1123 EXPECT_TRUE(status_area_widget->IsMessageBubbleShown()); | |
| 1124 } else { | |
| 1125 EXPECT_FALSE(shelf->IsVisible()); | |
| 1126 EXPECT_FALSE(status_area_widget->IsMessageBubbleShown()); | |
| 1127 } | |
| 1128 } | |
| 1129 } | |
| 1130 | |
| 1131 } // namespace internal | |
| 1132 } // namespace ash | |
| OLD | NEW |