diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-14 16:19:58 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-14 16:19:58 +0000 |
commit | df5954fe284ed678e0380ce2f151b2f65926a463 (patch) | |
tree | ae099ba9334e9580ed27e94a4a71dbdf2cf5fe9b /ui | |
parent | 78e2eab5d0b777065e5029022fac5a66bb344c84 (diff) | |
download | chromium_src-df5954fe284ed678e0380ce2f151b2f65926a463.zip chromium_src-df5954fe284ed678e0380ce2f151b2f65926a463.tar.gz chromium_src-df5954fe284ed678e0380ce2f151b2f65926a463.tar.bz2 |
Fixes layout bugs in ShelfLayoutManager. The problem with invoking
SetBounds on the widget during the animation is we end up back in the
layoutmanager and cancel the change. Also adds some tests for
ShelfLayoutManager.
BUG=107287 107401
TEST=see bug, but now covered by unit tests.
R=ben@chromium.org
Review URL: http://codereview.chromium.org/8929023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114434 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/aura_shell/aura_shell.gyp | 1 | ||||
-rw-r--r-- | ui/aura_shell/shelf_layout_manager.cc | 6 | ||||
-rw-r--r-- | ui/aura_shell/shelf_layout_manager.h | 10 | ||||
-rw-r--r-- | ui/aura_shell/shelf_layout_manager_unittest.cc | 108 |
4 files changed, 121 insertions, 4 deletions
diff --git a/ui/aura_shell/aura_shell.gyp b/ui/aura_shell/aura_shell.gyp index 005d3a1..1414812 100644 --- a/ui/aura_shell/aura_shell.gyp +++ b/ui/aura_shell/aura_shell.gyp @@ -156,6 +156,7 @@ 'modal_container_layout_manager_unittest.cc', 'run_all_unittests.cc', 'shadow_controller_unittest.cc', + 'shelf_layout_manager_unittest.cc', 'shell_accelerator_controller_unittest.cc', 'shell_unittest.cc', 'test_suite.cc', diff --git a/ui/aura_shell/shelf_layout_manager.cc b/ui/aura_shell/shelf_layout_manager.cc index cdca6d8..c422aa7 100644 --- a/ui/aura_shell/shelf_layout_manager.cc +++ b/ui/aura_shell/shelf_layout_manager.cc @@ -39,7 +39,6 @@ ShelfLayoutManager::ShelfLayoutManager(views::Widget* launcher, GetLayer(launcher)->GetAnimator()->AddObserver(this); } - ShelfLayoutManager::~ShelfLayoutManager() { // Do not try to remove observer from layer as the Launcher is // already deleted. @@ -108,6 +107,7 @@ void ShelfLayoutManager::StopAnimating() { visible_ = !visible_; } GetLayer(launcher_)->GetAnimator()->StopAnimating(); + GetLayer(status_)->GetAnimator()->StopAnimating(); } void ShelfLayoutManager::CalculateTargetBounds(bool visible, @@ -133,7 +133,9 @@ void ShelfLayoutManager::AnimateWidgetTo(views::Widget* widget, float target_opacity) { ui::Layer* layer = GetLayer(widget); ui::LayerAnimator::ScopedSettings animation_setter(layer->GetAnimator()); - widget->SetBounds(target_bounds); + // Don't go through the widget, otherwise we end up back in SetChildBounds and + // cancel the animation/layout. + layer->SetBounds(target_bounds); layer->SetOpacity(target_opacity); } diff --git a/ui/aura_shell/shelf_layout_manager.h b/ui/aura_shell/shelf_layout_manager.h index 2c46867..e7ff8f9 100644 --- a/ui/aura_shell/shelf_layout_manager.h +++ b/ui/aura_shell/shelf_layout_manager.h @@ -26,8 +26,7 @@ namespace internal { class ShelfLayoutManager : public aura::LayoutManager, public ui::LayerAnimationObserver { public: - ShelfLayoutManager(views::Widget* launcher, - views::Widget* status); + ShelfLayoutManager(views::Widget* launcher, views::Widget* status); virtual ~ShelfLayoutManager(); bool in_layout() const { return in_layout_; } @@ -38,6 +37,13 @@ class ShelfLayoutManager : public aura::LayoutManager, // Sets the visbility of the shelf to |visible|. void SetVisible(bool visible); + bool visible() const { return animating_ ? !visible_ : visible_; } + + views::Widget* launcher() { return launcher_; } + views::Widget* status() { return status_; } + + // See description above field. + int max_height() const { return max_height_; } // Overridden from aura::LayoutManager: virtual void OnWindowResized() OVERRIDE; diff --git a/ui/aura_shell/shelf_layout_manager_unittest.cc b/ui/aura_shell/shelf_layout_manager_unittest.cc new file mode 100644 index 0000000..4596b1e --- /dev/null +++ b/ui/aura_shell/shelf_layout_manager_unittest.cc @@ -0,0 +1,108 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/aura_shell/shelf_layout_manager.h" + +#include "ui/aura/root_window.h" +#include "ui/aura/screen_aura.h" +#include "ui/aura/window.h" +#include "ui/aura_shell/shell.h" +#include "ui/aura_shell/shell_window_ids.h" +#include "ui/aura_shell/test/aura_shell_test_base.h" +#include "ui/base/animation/animation_container_element.h" +#include "ui/gfx/compositor/layer_animator.h" +#include "ui/gfx/compositor/layer.h" +#include "ui/views/widget/widget.h" + +namespace aura_shell { +namespace internal { + +namespace { + +void StepWidgetLayerAnimatorToEnd(views::Widget* widget) { + ui::AnimationContainerElement* element = + static_cast<ui::AnimationContainerElement*>( + widget->GetNativeView()->layer()->GetAnimator()); + element->Step(base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1)); +} + +ShelfLayoutManager* GetShelfLayoutManager() { + aura::Window* window = aura_shell::Shell::GetInstance()->GetContainer( + aura_shell::internal::kShellWindowId_LauncherContainer); + return static_cast<ShelfLayoutManager*>(window->layout_manager()); +} + +} // namespace + +typedef aura_shell::test::AuraShellTestBase ShelfLayoutManagerTest; + +// Makes sure SetVisible updates work area and widget appropriately. +TEST_F(ShelfLayoutManagerTest, SetVisible) { + ShelfLayoutManager* shelf = GetShelfLayoutManager(); + // Force an initial layout. + shelf->LayoutShelf(); + ASSERT_TRUE(shelf->visible()); + + aura::ScreenAura* screen = aura::RootWindow::GetInstance()->screen(); + ASSERT_TRUE(screen); + // Bottom inset should be the max of widget heights. + EXPECT_EQ(shelf->max_height(), screen->work_area_insets().bottom()); + + // Hide the shelf. + shelf->SetVisible(false); + // Run the animation to completion. + StepWidgetLayerAnimatorToEnd(shelf->launcher()); + StepWidgetLayerAnimatorToEnd(shelf->status()); + EXPECT_FALSE(shelf->visible()); + EXPECT_EQ(0, screen->work_area_insets().bottom()); + + // Make sure the bounds of the two widgets changed. + EXPECT_GE(shelf->launcher()->GetNativeView()->bounds().y(), + gfx::Screen::GetPrimaryMonitorBounds().bottom()); + EXPECT_GE(shelf->status()->GetNativeView()->bounds().y(), + gfx::Screen::GetPrimaryMonitorBounds().bottom()); + + // And show it again. + shelf->SetVisible(true); + // Run the animation to completion. + StepWidgetLayerAnimatorToEnd(shelf->launcher()); + StepWidgetLayerAnimatorToEnd(shelf->status()); + EXPECT_TRUE(shelf->visible()); + EXPECT_EQ(shelf->max_height(), screen->work_area_insets().bottom()); + + // Make sure the bounds of the two widgets changed. + gfx::Rect launcher_bounds(shelf->launcher()->GetNativeView()->bounds()); + int bottom = gfx::Screen::GetPrimaryMonitorBounds().bottom() - + shelf->max_height(); + EXPECT_EQ(launcher_bounds.y(), + bottom + (shelf->max_height() - launcher_bounds.height()) / 2); + gfx::Rect status_bounds(shelf->status()->GetNativeView()->bounds()); + EXPECT_EQ(status_bounds.y(), + bottom + (shelf->max_height() - status_bounds.height()) / 2); +} + +// Makes sure LayoutShelf invoked while animating cleans things up. +TEST_F(ShelfLayoutManagerTest, LayoutShelfWhileAnimating) { + ShelfLayoutManager* shelf = GetShelfLayoutManager(); + // Force an initial layout. + shelf->LayoutShelf(); + ASSERT_TRUE(shelf->visible()); + + aura::ScreenAura* screen = aura::RootWindow::GetInstance()->screen(); + + // Hide the shelf. + shelf->SetVisible(false); + shelf->LayoutShelf(); + EXPECT_FALSE(shelf->visible()); + EXPECT_FALSE(shelf->visible()); + EXPECT_EQ(0, screen->work_area_insets().bottom()); + // Make sure the bounds of the two widgets changed. + EXPECT_GE(shelf->launcher()->GetNativeView()->bounds().y(), + gfx::Screen::GetPrimaryMonitorBounds().bottom()); + EXPECT_GE(shelf->status()->GetNativeView()->bounds().y(), + gfx::Screen::GetPrimaryMonitorBounds().bottom()); +} + +} // namespace internal +} // namespace aura_shell |