diff options
author | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-02 04:35:10 +0000 |
---|---|---|
committer | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-02 04:35:10 +0000 |
commit | 0bf6173343da9c7db8d9e57644be83676c4842c5 (patch) | |
tree | 2c446593d0b95367b23e7d4cac8c29bce79b2360 | |
parent | ef20a40442e4b398bf1b57bdf95c22ef4b4a4c10 (diff) | |
download | chromium_src-0bf6173343da9c7db8d9e57644be83676c4842c5.zip chromium_src-0bf6173343da9c7db8d9e57644be83676c4842c5.tar.gz chromium_src-0bf6173343da9c7db8d9e57644be83676c4842c5.tar.bz2 |
Wallpaper refactoring.
- Move the ownership of controllers to RootWindowController
Start wallpaper animation after animating controller is set.
BUG=157159
Review URL: https://chromiumcodereview.appspot.com/17910007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209613 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/desktop_background/desktop_background_controller.cc | 72 | ||||
-rw-r--r-- | ash/desktop_background/desktop_background_controller.h | 6 | ||||
-rw-r--r-- | ash/desktop_background/desktop_background_controller_unittest.cc | 67 | ||||
-rw-r--r-- | ash/desktop_background/desktop_background_view.cc | 79 | ||||
-rw-r--r-- | ash/desktop_background/desktop_background_widget_controller.cc | 85 | ||||
-rw-r--r-- | ash/desktop_background/desktop_background_widget_controller.h | 34 | ||||
-rw-r--r-- | ash/root_window_controller.cc | 59 | ||||
-rw-r--r-- | ash/root_window_controller.h | 24 | ||||
-rw-r--r-- | ash/wm/root_window_layout_manager.cc | 15 |
9 files changed, 226 insertions, 215 deletions
diff --git a/ash/desktop_background/desktop_background_controller.cc b/ash/desktop_background/desktop_background_controller.cc index a4f367b..25b63c3 100644 --- a/ash/desktop_background/desktop_background_controller.cc +++ b/ash/desktop_background/desktop_background_controller.cc @@ -14,6 +14,7 @@ #include "ash/shell.h" #include "ash/shell_factory.h" #include "ash/shell_window_ids.h" +#include "ash/wm/property_util.h" #include "ash/wm/root_window_layout_manager.h" #include "base/bind.h" #include "base/command_line.h" @@ -32,8 +33,6 @@ #include "ui/views/widget/widget.h" using ash::internal::DesktopBackgroundWidgetController; -using ash::internal::kAnimatingDesktopController; -using ash::internal::kDesktopController; using content::BrowserThread; namespace ash { @@ -359,13 +358,6 @@ bool DesktopBackgroundController::MoveDesktopToUnlockedContainer() { GetBackgroundContainerId(false)); } -void DesktopBackgroundController::OnWindowDestroying(aura::Window* window) { - window->SetProperty(kDesktopController, - static_cast<internal::DesktopBackgroundWidgetController*>(NULL)); - window->SetProperty(kAnimatingDesktopController, - static_cast<internal::AnimatingDesktopController*>(NULL)); -} - bool DesktopBackgroundController::DefaultWallpaperIsAlreadyLoadingOrLoaded( const base::FilePath& image_file, int image_resource_id) const { return (wallpaper_loader_ && @@ -402,12 +394,6 @@ void DesktopBackgroundController::OnDefaultWallpaperLoadCompleted( wallpaper_loader_ = NULL; } -void DesktopBackgroundController::NotifyAnimationFinished() { - Shell* shell = Shell::GetInstance(); - shell->GetPrimaryRootWindowController()->HandleDesktopBackgroundVisible(); - shell->user_wallpaper_delegate()->OnWallpaperAnimationFinished(); -} - ui::Layer* DesktopBackgroundController::SetColorLayerForContainer( SkColor color, aura::RootWindow* root_window, @@ -417,12 +403,6 @@ ui::Layer* DesktopBackgroundController::SetColorLayerForContainer( Shell::GetContainer(root_window,container_id)-> layer()->Add(background_layer); - - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&DesktopBackgroundController::NotifyAnimationFinished, - weak_ptr_factory_.GetWeakPtr())); - return background_layer; } @@ -449,17 +429,10 @@ void DesktopBackgroundController::InstallDesktopController( NOTREACHED(); return; } - // Ensure we're only observing the root window once. Don't rely on a window - // property check as those can be cleared by tests resetting the background. - if (!root_window->HasObserver(this)) - root_window->AddObserver(this); - - internal::AnimatingDesktopController* animating_controller = - root_window->GetProperty(kAnimatingDesktopController); - if (animating_controller) - animating_controller->StopAnimating(); - root_window->SetProperty(kAnimatingDesktopController, - new internal::AnimatingDesktopController(component)); + GetRootWindowController(root_window)->SetAnimatingWallpaperController( + new internal::AnimatingDesktopController(component)); + + component->StartAnimating(GetRootWindowController(root_window)); } void DesktopBackgroundController::InstallDesktopControllerForAllWindows() { @@ -473,33 +446,36 @@ void DesktopBackgroundController::InstallDesktopControllerForAllWindows() { bool DesktopBackgroundController::ReparentBackgroundWidgets(int src_container, int dst_container) { bool moved = false; - Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); - for (Shell::RootWindowList::iterator iter = root_windows.begin(); - iter != root_windows.end(); ++iter) { - aura::RootWindow* root_window = *iter; + Shell::RootWindowControllerList controllers = + Shell::GetAllRootWindowControllers(); + for (Shell::RootWindowControllerList::iterator iter = controllers.begin(); + iter != controllers.end(); ++iter) { + internal::RootWindowController* root_window_controller = *iter; // In the steady state (no animation playing) the background widget - // controller exists in the kDesktopController property. - DesktopBackgroundWidgetController* desktop_controller = root_window-> - GetProperty(kDesktopController); + // controller exists in the RootWindowController. + DesktopBackgroundWidgetController* desktop_controller = + root_window_controller->wallpaper_controller(); if (desktop_controller) { - moved |= desktop_controller->Reparent(root_window, - src_container, - dst_container); + moved |= desktop_controller->Reparent( + root_window_controller->root_window(), + src_container, + dst_container); } // During desktop show animations the controller lives in - // kAnimatingDesktopController. + // AnimatingDesktopController owned by RootWindowController. // NOTE: If a wallpaper load happens during a desktop show animation there // can temporarily be two desktop background widgets. We must reparent // both of them - one above and one here. DesktopBackgroundWidgetController* animating_controller = - root_window->GetProperty(kAnimatingDesktopController) ? - root_window->GetProperty(kAnimatingDesktopController)-> + root_window_controller->animating_wallpaper_controller() ? + root_window_controller->animating_wallpaper_controller()-> GetController(false) : NULL; if (animating_controller) { - moved |= animating_controller->Reparent(root_window, - src_container, - dst_container); + moved |= animating_controller->Reparent( + root_window_controller->root_window(), + src_container, + dst_container); } } return moved; diff --git a/ash/desktop_background/desktop_background_controller.h b/ash/desktop_background/desktop_background_controller.h index d89f3f7..afdc2dc 100644 --- a/ash/desktop_background/desktop_background_controller.h +++ b/ash/desktop_background/desktop_background_controller.h @@ -12,7 +12,6 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "ui/aura/window.h" -#include "ui/aura/window_observer.h" #include "ui/compositor/layer.h" #include "ui/gfx/image/image_skia.h" @@ -68,7 +67,7 @@ class WallpaperResizer; // Loads selected desktop wallpaper from file system asynchronously and updates // background layer if loaded successfully. -class ASH_EXPORT DesktopBackgroundController : public aura::WindowObserver { +class ASH_EXPORT DesktopBackgroundController { public: enum BackgroundMode { BACKGROUND_NONE, @@ -136,9 +135,6 @@ class ASH_EXPORT DesktopBackgroundController : public aura::WindowObserver { // Returns true if the desktop moved. bool MoveDesktopToUnlockedContainer(); - // WindowObserver implementation. - virtual void OnWindowDestroying(aura::Window* window) OVERRIDE; - private: friend class internal::DesktopBackgroundControllerTest; diff --git a/ash/desktop_background/desktop_background_controller_unittest.cc b/ash/desktop_background/desktop_background_controller_unittest.cc index be85341..4eb9b57 100644 --- a/ash/desktop_background/desktop_background_controller_unittest.cc +++ b/ash/desktop_background/desktop_background_controller_unittest.cc @@ -10,6 +10,7 @@ #include "ash/ash_switches.h" #include "ash/desktop_background/desktop_background_controller_observer.h" #include "ash/desktop_background/desktop_background_widget_controller.h" +#include "ash/root_window_controller.h" #include "ash/shell.h" #include "ash/shell_window_ids.h" #include "ash/test/ash_test_base.h" @@ -109,12 +110,10 @@ class DesktopBackgroundControllerTest : public test::AshTestBase { test::AshTestBase::SetUp(); // Ash shell initialization creates wallpaper. Reset it so we can manually // control wallpaper creation and animation in our tests. - RootWindow* root = Shell::GetPrimaryRootWindow(); - root->SetProperty(kDesktopController, - static_cast<DesktopBackgroundWidgetController*>(NULL)); - root->SetProperty(kAnimatingDesktopController, - static_cast<AnimatingDesktopController*>(NULL)); - + RootWindowController* root_window_controller = + Shell::GetPrimaryRootWindowController(); + root_window_controller->SetWallpaperController(NULL); + root_window_controller->SetAnimatingWallpaperController(NULL); controller_ = Shell::GetInstance()->desktop_background_controller(); } @@ -134,9 +133,9 @@ class DesktopBackgroundControllerTest : public test::AshTestBase { // Runs kAnimatingDesktopController's animation to completion. // TODO(bshe): Don't require tests to run animations; it's slow. void RunDesktopControllerAnimation() { - RootWindow* root = Shell::GetPrimaryRootWindow(); DesktopBackgroundWidgetController* controller = - root->GetProperty(kAnimatingDesktopController)->GetController(false); + Shell::GetPrimaryRootWindowController()-> + animating_wallpaper_controller()->GetController(false); ASSERT_NO_FATAL_FAILURE(RunAnimationForWidget(controller->widget())); } @@ -304,21 +303,22 @@ TEST_F(DesktopBackgroundControllerTest, ControllerOwnership) { // The new wallpaper is ready to start animating. kAnimatingDesktopController // holds the widget controller instance. kDesktopController will get it later. - RootWindow* root = Shell::GetPrimaryRootWindow(); - EXPECT_TRUE( - root->GetProperty(kAnimatingDesktopController)->GetController(false)); + RootWindowController* root_window_controller = + Shell::GetPrimaryRootWindowController(); + EXPECT_TRUE(root_window_controller->animating_wallpaper_controller()-> + GetController(false)); // kDesktopController will receive the widget controller when the animation // is done. - EXPECT_FALSE(root->GetProperty(kDesktopController)); + EXPECT_FALSE(root_window_controller->wallpaper_controller()); // Force the widget's layer animation to play to completion. RunDesktopControllerAnimation(); // Ownership has moved from kAnimatingDesktopController to kDesktopController. - EXPECT_FALSE( - root->GetProperty(kAnimatingDesktopController)->GetController(false)); - EXPECT_TRUE(root->GetProperty(kDesktopController)); + EXPECT_FALSE(root_window_controller->animating_wallpaper_controller()-> + GetController(false)); + EXPECT_TRUE(root_window_controller->wallpaper_controller()); } // Test for crbug.com/149043 "Unlock screen, no launcher appears". Ensure we @@ -345,10 +345,11 @@ TEST_F(DesktopBackgroundControllerTest, BackgroundMovementDuringUnlock) { // In this state we have two desktop background views stored in different // properties. Both are in the lock screen background container. - RootWindow* root = Shell::GetPrimaryRootWindow(); - EXPECT_TRUE( - root->GetProperty(kAnimatingDesktopController)->GetController(false)); - EXPECT_TRUE(root->GetProperty(kDesktopController)); + RootWindowController* root_window_controller = + Shell::GetPrimaryRootWindowController(); + EXPECT_TRUE(root_window_controller->animating_wallpaper_controller()-> + GetController(false)); + EXPECT_TRUE(root_window_controller->wallpaper_controller()); EXPECT_EQ(0, ChildCountForContainer(kDesktopBackgroundId)); EXPECT_EQ(2, ChildCountForContainer(kLockScreenBackgroundId)); @@ -386,33 +387,37 @@ TEST_F(DesktopBackgroundControllerTest, ChangeWallpaperQuick) { // Change to a new wallpaper. controller->CreateEmptyWallpaper(); - RootWindow* root = Shell::GetPrimaryRootWindow(); + RootWindowController* root_window_controller = + Shell::GetPrimaryRootWindowController(); DesktopBackgroundWidgetController* animating_controller = - root->GetProperty(kAnimatingDesktopController)->GetController(false); + root_window_controller->animating_wallpaper_controller()-> + GetController(false); EXPECT_TRUE(animating_controller); - EXPECT_TRUE(root->GetProperty(kDesktopController)); + EXPECT_TRUE(root_window_controller->wallpaper_controller()); // Change to another wallpaper before animation finished. controller->CreateEmptyWallpaper(); // The animating controller should immediately move to desktop controller. - EXPECT_EQ(animating_controller, root->GetProperty(kDesktopController)); + EXPECT_EQ(animating_controller, + root_window_controller->wallpaper_controller()); // Cache the new animating controller. - animating_controller = - root->GetProperty(kAnimatingDesktopController)->GetController(false); + animating_controller = root_window_controller-> + animating_wallpaper_controller()->GetController(false); // Run wallpaper show animation to completion. ASSERT_NO_FATAL_FAILURE( RunAnimationForWidget( - root->GetProperty(kAnimatingDesktopController)->GetController(false)-> - widget())); + root_window_controller->animating_wallpaper_controller()-> + GetController(false)->widget())); - EXPECT_TRUE(root->GetProperty(kDesktopController)); - EXPECT_FALSE( - root->GetProperty(kAnimatingDesktopController)->GetController(false)); + EXPECT_TRUE(root_window_controller->wallpaper_controller()); + EXPECT_FALSE(root_window_controller->animating_wallpaper_controller()-> + GetController(false)); // The desktop controller should be the last created animating controller. - EXPECT_EQ(animating_controller, root->GetProperty(kDesktopController)); + EXPECT_EQ(animating_controller, + root_window_controller->wallpaper_controller()); } TEST_F(DesktopBackgroundControllerTest, GetAppropriateResolution) { diff --git a/ash/desktop_background/desktop_background_view.cc b/ash/desktop_background/desktop_background_view.cc index bb020ad..daaa6b4 100644 --- a/ash/desktop_background/desktop_background_view.cc +++ b/ash/desktop_background/desktop_background_view.cc @@ -21,80 +21,14 @@ #include "ui/aura/root_window.h" #include "ui/base/resource/resource_bundle.h" #include "ui/compositor/layer.h" -#include "ui/compositor/layer_animation_observer.h" -#include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/gfx/canvas.h" #include "ui/gfx/image/image.h" #include "ui/views/widget/widget.h" -#include "ui/views/widget/widget_observer.h" namespace ash { namespace internal { namespace { -class ShowWallpaperAnimationObserver : public ui::ImplicitAnimationObserver, - public views::WidgetObserver { - public: - ShowWallpaperAnimationObserver(aura::RootWindow* root_window, - views::Widget* desktop_widget, - bool is_initial_animation) - : root_window_(root_window), - desktop_widget_(desktop_widget), - is_initial_animation_(is_initial_animation) { - DCHECK(desktop_widget_); - desktop_widget_->AddObserver(this); - } - - virtual ~ShowWallpaperAnimationObserver() { - StopObservingImplicitAnimations(); - if (desktop_widget_) - desktop_widget_->RemoveObserver(this); - } - - private: - // Overridden from ui::ImplicitAnimationObserver: - virtual void OnImplicitAnimationsScheduled() OVERRIDE { - if (is_initial_animation_) { - GetRootWindowController(root_window_)-> - HandleInitialDesktopBackgroundAnimationStarted(); - } - } - - virtual void OnImplicitAnimationsCompleted() OVERRIDE { - GetRootWindowController(root_window_)->HandleDesktopBackgroundVisible(); - ash::Shell::GetInstance()->user_wallpaper_delegate()-> - OnWallpaperAnimationFinished(); - // Only removes old component when wallpaper animation finished. If we - // remove the old one before the new wallpaper is done fading in there will - // be a white flash during the animation. - if (root_window_->GetProperty(kAnimatingDesktopController)) { - DesktopBackgroundWidgetController* controller = - root_window_->GetProperty(kAnimatingDesktopController)-> - GetController(true); - // |desktop_widget_| should be the same animating widget we try to move - // to |kDesktopController|. Otherwise, we may close |desktop_widget_| - // before move it to |kDesktopController|. - DCHECK_EQ(controller->widget(), desktop_widget_); - // Release the old controller and close its background widget. - root_window_->SetProperty(kDesktopController, controller); - } - delete this; - } - - // Overridden from views::WidgetObserver. - virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE { - delete this; - } - - aura::RootWindow* root_window_; - views::Widget* desktop_widget_; - - // Is this object observing the initial brightness/grayscale animation? - const bool is_initial_animation_; - - DISALLOW_COPY_AND_ASSIGN(ShowWallpaperAnimationObserver); -}; - // For our scaling ratios we need to round positive numbers. int RoundPositive(double x) { return static_cast<int>(floor(x + 0.5)); @@ -196,13 +130,16 @@ views::Widget* CreateDesktopBackground(aura::RootWindow* root_window, views::corewm::SetWindowVisibilityAnimationType( desktop_widget->GetNativeView(), animation_type); + RootWindowController* root_window_controller = + GetRootWindowController(root_window); + // Enable wallpaper transition for the following cases: // 1. Initial(OOBE) wallpaper animation. // 2. Wallpaper fades in from a non empty background. // 3. From an empty background, chrome transit to a logged in user session. // 4. From an empty background, guest user logged in. if (wallpaper_delegate->ShouldShowInitialAnimation() || - root_window->GetProperty(kAnimatingDesktopController) || + root_window_controller->animating_wallpaper_controller() || Shell::GetInstance()->session_state_delegate()->NumberOfLoggedInUsers()) { views::corewm::SetWindowVisibilityAnimationTransition( desktop_widget->GetNativeView(), views::corewm::ANIMATE_SHOW); @@ -213,14 +150,6 @@ views::Widget* CreateDesktopBackground(aura::RootWindow* root_window, } desktop_widget->SetBounds(params.parent->bounds()); - ui::ScopedLayerAnimationSettings settings( - desktop_widget->GetNativeView()->layer()->GetAnimator()); - settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); - settings.AddObserver(new ShowWallpaperAnimationObserver( - root_window, desktop_widget, - wallpaper_delegate->ShouldShowInitialAnimation())); - desktop_widget->Show(); - desktop_widget->GetNativeView()->SetName("DesktopBackgroundView"); return desktop_widget; } diff --git a/ash/desktop_background/desktop_background_widget_controller.cc b/ash/desktop_background/desktop_background_widget_controller.cc index 98d1ba4..cbd7727 100644 --- a/ash/desktop_background/desktop_background_widget_controller.cc +++ b/ash/desktop_background/desktop_background_widget_controller.cc @@ -5,23 +5,67 @@ #include "ash/desktop_background/desktop_background_widget_controller.h" #include "ash/ash_export.h" +#include "ash/desktop_background/user_wallpaper_delegate.h" +#include "ash/root_window_controller.h" +#include "ash/shell.h" #include "ui/aura/root_window.h" -#include "ui/aura/window_property.h" +#include "ui/compositor/layer_animation_observer.h" +#include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/views/widget/widget.h" - -// Exported for tests. -DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE( - ASH_EXPORT, ash::internal::DesktopBackgroundWidgetController*); -DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE( - ASH_EXPORT, ash::internal::AnimatingDesktopController*); +#include "ui/views/widget/widget_observer.h" namespace ash { namespace internal { +namespace { + +class ShowWallpaperAnimationObserver : public ui::ImplicitAnimationObserver, + public views::WidgetObserver { + public: + ShowWallpaperAnimationObserver(RootWindowController* root_window_controller, + views::Widget* desktop_widget, + bool is_initial_animation) + : root_window_controller_(root_window_controller), + desktop_widget_(desktop_widget), + is_initial_animation_(is_initial_animation) { + DCHECK(desktop_widget_); + desktop_widget_->AddObserver(this); + } + + virtual ~ShowWallpaperAnimationObserver() { + StopObservingImplicitAnimations(); + if (desktop_widget_) + desktop_widget_->RemoveObserver(this); + } + + private: + // Overridden from ui::ImplicitAnimationObserver: + virtual void OnImplicitAnimationsScheduled() OVERRIDE { + if (is_initial_animation_) { + root_window_controller_-> + HandleInitialDesktopBackgroundAnimationStarted(); + } + } + + virtual void OnImplicitAnimationsCompleted() OVERRIDE { + root_window_controller_->OnWallpaperAnimationFinished(desktop_widget_); + delete this; + } + + // Overridden from views::WidgetObserver. + virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE { + delete this; + } + + RootWindowController* root_window_controller_; + views::Widget* desktop_widget_; + + // Is this object observing the initial brightness/grayscale animation? + const bool is_initial_animation_; -DEFINE_OWNED_WINDOW_PROPERTY_KEY(DesktopBackgroundWidgetController, - kDesktopController, NULL); -DEFINE_OWNED_WINDOW_PROPERTY_KEY(AnimatingDesktopController, - kAnimatingDesktopController, NULL); + DISALLOW_COPY_AND_ASSIGN(ShowWallpaperAnimationObserver); +}; + +} // namespace DesktopBackgroundWidgetController::DesktopBackgroundWidgetController( views::Widget* widget) : widget_(widget) { @@ -63,8 +107,7 @@ bool DesktopBackgroundWidgetController::Reparent(aura::RootWindow* root_window, views::Widget::ReparentNativeView(widget_->GetNativeView(), root_window->GetChildById(dest_container)); return true; - } - if (layer_) { + } else if (layer_) { ui::Layer* layer = layer_.get(); root_window->GetChildById(src_container)->layer()->Remove(layer); root_window->GetChildById(dest_container)->layer()->Add(layer); @@ -74,6 +117,22 @@ bool DesktopBackgroundWidgetController::Reparent(aura::RootWindow* root_window, return false; } +void DesktopBackgroundWidgetController::StartAnimating( + RootWindowController* root_window_controller) { + if (widget_) { + ui::ScopedLayerAnimationSettings settings( + widget_->GetNativeView()->layer()->GetAnimator()); + settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); + settings.AddObserver(new ShowWallpaperAnimationObserver( + root_window_controller, widget_, + Shell::GetInstance()->user_wallpaper_delegate()-> + ShouldShowInitialAnimation())); + widget_->Show(); + widget_->GetNativeView()->SetName("DesktopBackgroundView"); + } else if (layer_) + root_window_controller->OnWallpaperAnimationFinished(NULL); +} + AnimatingDesktopController::AnimatingDesktopController( DesktopBackgroundWidgetController* component) { controller_.reset(component); diff --git a/ash/desktop_background/desktop_background_widget_controller.h b/ash/desktop_background/desktop_background_widget_controller.h index bf94619..8aa3449 100644 --- a/ash/desktop_background/desktop_background_widget_controller.h +++ b/ash/desktop_background/desktop_background_widget_controller.h @@ -14,14 +14,13 @@ namespace ash { namespace internal { +class RootWindowController; // This class hides difference between two possible background implementations: // effective Layer-based for solid color, and Widget-based for images. -// DesktopBackgroundWidgetController is installed as an owned property on the -// RootWindow. To avoid a white flash during wallpaper changes the old -// DesktopBackgroundWidgetController is moved to a secondary property -// (kComponentWrapper). When the animation completes the old -// DesktopBackgroundWidgetController is destroyed. Exported for tests. +// DesktopBackgroundWidgetController is owned by RootWindowController. +// When the animation completes the old DesktopBackgroundWidgetController is +// destroyed. Exported for tests. class ASH_EXPORT DesktopBackgroundWidgetController : public views::WidgetObserver { public: @@ -44,6 +43,11 @@ class ASH_EXPORT DesktopBackgroundWidgetController int src_container, int dest_container); + // Starts wallpaper fade in animation. |root_window_controller| is + // the root window where the animation will happen. (This is + // necessary this as |layer_| doesn't have access to the root window). + void StartAnimating(RootWindowController* root_window_controller); + views::Widget* widget() { return widget_; } ui::Layer* layer() { return layer_.get(); } @@ -54,11 +58,10 @@ class ASH_EXPORT DesktopBackgroundWidgetController DISALLOW_COPY_AND_ASSIGN(DesktopBackgroundWidgetController); }; -// This class wraps a DesktopBackgroundWidgetController pointer. It is installed -// as an owned property on the RootWindow. DesktopBackgroundWidgetController is -// moved to this property before animation completes. After animation completes, -// the kDesktopController property on RootWindow is set to the -// DesktopBackgroundWidgetController in this class. Exported for tests. +// This class wraps a DesktopBackgroundWidgetController pointer. It is owned +// by RootWindowController. The instance of DesktopBackgroundWidgetController is +// moved to this RootWindowController when the animation completes. +// Exported for tests. class ASH_EXPORT AnimatingDesktopController { public: explicit AnimatingDesktopController( @@ -90,17 +93,6 @@ class ASH_EXPORT AnimatingDesktopController { DISALLOW_COPY_AND_ASSIGN(AnimatingDesktopController); }; -// Window property key, that binds instance of DesktopBackgroundWidgetController -// to root windows. Owned property. -ASH_EXPORT extern - const aura::WindowProperty<DesktopBackgroundWidgetController*>* const - kDesktopController; - -// Wrapper for the DesktopBackgroundWidgetController for a desktop background -// that is animating in. Owned property. -ASH_EXPORT extern const aura::WindowProperty<AnimatingDesktopController*>* const - kAnimatingDesktopController; - } // namespace internal } // namespace ash diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index b9d13ab..5d97a31 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc @@ -9,6 +9,7 @@ #include "ash/ash_constants.h" #include "ash/ash_switches.h" #include "ash/desktop_background/desktop_background_widget_controller.h" +#include "ash/desktop_background/user_wallpaper_delegate.h" #include "ash/display/display_manager.h" #include "ash/focus_cycler.h" #include "ash/session_state_delegate.h" @@ -177,7 +178,7 @@ RootWindowController::RootWindowController(aura::RootWindow* root_window) SetRootWindowController(root_window, this); screen_dimmer_.reset(new ScreenDimmer(root_window)); - stacking_controller_.reset(new ash::StackingController); + stacking_controller_.reset(new StackingController); aura::client::SetStackingClient(root_window, stacking_controller_.get()); } @@ -202,7 +203,24 @@ RootWindowController* RootWindowController::ForActiveRootWindow() { return GetRootWindowController(Shell::GetActiveRootWindow()); } +void RootWindowController::SetWallpaperController( + DesktopBackgroundWidgetController* controller) { + wallpaper_controller_.reset(controller); +} + +void RootWindowController::SetAnimatingWallpaperController( + AnimatingDesktopController* controller) { + if (animating_wallpaper_controller_.get()) + animating_wallpaper_controller_->StopAnimating(); + animating_wallpaper_controller_.reset(controller); +} + void RootWindowController::Shutdown() { + if (animating_wallpaper_controller_.get()) + animating_wallpaper_controller_->StopAnimating(); + wallpaper_controller_.reset(); + animating_wallpaper_controller_.reset(); + CloseChildWindows(); if (Shell::GetActiveRootWindow() == root_window_) { Shell::GetInstance()->set_active_root_window( @@ -272,11 +290,11 @@ void RootWindowController::InitLayoutManagers() { void RootWindowController::InitForPrimaryDisplay() { DCHECK(!shelf_.get()); aura::Window* shelf_container = - GetContainer(ash::internal::kShellWindowId_ShelfContainer); + GetContainer(internal::kShellWindowId_ShelfContainer); // TODO(harrym): Remove when status area is view. aura::Window* status_container = - GetContainer(ash::internal::kShellWindowId_StatusContainer); - shelf_.reset(new ash::ShelfWidget( + GetContainer(internal::kShellWindowId_StatusContainer); + shelf_.reset(new ShelfWidget( shelf_container, status_container, workspace_controller())); // Create Docked windows layout manager @@ -368,9 +386,26 @@ void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() { } } -void RootWindowController::HandleDesktopBackgroundVisible() { +void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) { + // Make sure the wallpaper is visible. system_background_->SetColor(SK_ColorBLACK); boot_splash_screen_.reset(); + + Shell::GetInstance()->user_wallpaper_delegate()-> + OnWallpaperAnimationFinished(); + // Only removes old component when wallpaper animation finished. If we + // remove the old one before the new wallpaper is done fading in there will + // be a white flash during the animation. + if (animating_wallpaper_controller()) { + DesktopBackgroundWidgetController* controller = + animating_wallpaper_controller()->GetController(true); + // |desktop_widget_| should be the same animating widget we try to move + // to |kDesktopController|. Otherwise, we may close |desktop_widget_| + // before move it to |kDesktopController|. + DCHECK_EQ(controller->widget(), widget); + // Release the old controller and close its background widget. + SetWallpaperController(controller); + } } void RootWindowController::CloseChildWindows() { @@ -389,10 +424,8 @@ void RootWindowController::CloseChildWindows() { shelf_->shelf_layout_manager()->set_workspace_controller(NULL); // Close background widget first as it depends on tooltip. - root_window_->SetProperty(kDesktopController, - static_cast<DesktopBackgroundWidgetController*>(NULL)); - root_window_->SetProperty(kAnimatingDesktopController, - static_cast<AnimatingDesktopController*>(NULL)); + wallpaper_controller_.reset(); + animating_wallpaper_controller_.reset(); workspace_controller_.reset(); aura::client::SetTooltipClient(root_window_.get(), NULL); @@ -443,15 +476,13 @@ void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen, if (!menu_model) return; - internal::DesktopBackgroundWidgetController* background = - root_window_->GetProperty(kDesktopController); // Background controller may not be set yet if user clicked on status are // before initial animation completion. See crbug.com/222218 - if (!background) + if (!wallpaper_controller_.get()) return; views::MenuRunner menu_runner(menu_model.get()); - if (menu_runner.RunMenuAt(background->widget(), + if (menu_runner.RunMenuAt(wallpaper_controller_->widget(), NULL, gfx::Rect(location_in_screen, gfx::Size()), views::MenuItemView::TOPLEFT, source_type, views::MenuRunner::CONTEXT_MENU) == @@ -478,7 +509,7 @@ aura::Window* RootWindowController::GetFullscreenWindow() const { aura::Window* container = workspace_controller_->GetActiveWorkspaceWindow(); for (size_t i = 0; i < container->children().size(); ++i) { aura::Window* child = container->children()[i]; - if (ash::wm::IsWindowFullscreen(child)) + if (wm::IsWindowFullscreen(child)) return child; } return NULL; diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h index a6b81c1..2895466 100644 --- a/ash/root_window_controller.h +++ b/ash/root_window_controller.h @@ -27,6 +27,8 @@ class Point; } namespace views { +class Widget; + namespace corewm { class InputMethodEventFilter; class RootWindowEventFilter; @@ -46,7 +48,9 @@ class ToplevelWindowEventHandler; namespace internal { class AlwaysOnTopController; +class AnimatingDesktopController; class BootSplashScreen; +class DesktopBackgroundWidgetController; class DockedWindowLayoutManager; class PanelLayoutManager; class RootWindowLayoutManager; @@ -124,6 +128,15 @@ class ASH_EXPORT RootWindowController { // Disables projection touch HUD. void DisableTouchHudProjection(); + DesktopBackgroundWidgetController* wallpaper_controller() { + return wallpaper_controller_.get(); + } + void SetWallpaperController(DesktopBackgroundWidgetController* controller); + AnimatingDesktopController* animating_wallpaper_controller() { + return animating_wallpaper_controller_.get(); + } + void SetAnimatingWallpaperController(AnimatingDesktopController* controller); + // Access the shelf layout manager associated with this root // window controller, NULL if no such shelf exists. ShelfLayoutManager* GetShelfLayoutManager(); @@ -179,9 +192,11 @@ class ASH_EXPORT RootWindowController { // hiding animation (if the screen is non-NULL). void HandleInitialDesktopBackgroundAnimationStarted(); - // Called when the login background is fully visible. Updates |background_| - // to be black and drops |boot_splash_screen_|. - void HandleDesktopBackgroundVisible(); + // Called when the wallpaper ainmation is finished. Updates |background_| + // to be black and drops |boot_splash_screen_| and moves the wallpaper + // controller into the root window controller. |widget| holds the wallpaper + // image, or NULL if the background is a solid color. + void OnWallpaperAnimationFinished(views::Widget* widget); // Deletes associated objects and clears the state, but doesn't delete // the root window yet. This is used to delete a secondary displays' @@ -250,6 +265,9 @@ class ASH_EXPORT RootWindowController { scoped_ptr<ToplevelWindowEventHandler> panel_container_handler_; scoped_ptr<ToplevelWindowEventHandler> docked_container_handler_; + scoped_ptr<DesktopBackgroundWidgetController> wallpaper_controller_; + scoped_ptr<AnimatingDesktopController> animating_wallpaper_controller_; + DISALLOW_COPY_AND_ASSIGN(RootWindowController); }; diff --git a/ash/wm/root_window_layout_manager.cc b/ash/wm/root_window_layout_manager.cc index 481fe3f..584bc06 100644 --- a/ash/wm/root_window_layout_manager.cc +++ b/ash/wm/root_window_layout_manager.cc @@ -5,7 +5,9 @@ #include "ash/wm/root_window_layout_manager.h" #include "ash/desktop_background/desktop_background_widget_controller.h" -#include "ui/aura/window.h" +#include "ash/root_window_controller.h" +#include "ash/wm/property_util.h" +#include "ui/aura/root_window.h" #include "ui/compositor/layer.h" #include "ui/views/widget/widget.h" @@ -39,10 +41,13 @@ void RootWindowLayoutManager::OnWindowResized() { for (j = (*i)->children().begin(); j != (*i)->children().end(); ++j) (*j)->SetBounds(fullscreen_bounds); } - internal::DesktopBackgroundWidgetController* background = - owner_->GetProperty(kDesktopController); - if (!background && owner_->GetProperty(kAnimatingDesktopController)) { - background = owner_->GetProperty(kAnimatingDesktopController)-> + RootWindowController* root_window_controller = GetRootWindowController( + static_cast<aura::RootWindow*>(owner_)); + DesktopBackgroundWidgetController* background = + root_window_controller->wallpaper_controller(); + + if (!background && root_window_controller->animating_wallpaper_controller()) { + background = root_window_controller->animating_wallpaper_controller()-> GetController(false); } if (background) |