diff options
-rw-r--r-- | ash/ash.gyp | 2 | ||||
-rw-r--r-- | ash/root_window_controller.cc | 3 | ||||
-rw-r--r-- | ash/root_window_controller.h | 4 | ||||
-rw-r--r-- | ash/shell.cc | 8 | ||||
-rw-r--r-- | ash/shell.h | 3 | ||||
-rw-r--r-- | ash/wm/dim_window.cc | 79 | ||||
-rw-r--r-- | ash/wm/dim_window.h | 35 | ||||
-rw-r--r-- | ash/wm/screen_dimmer.cc | 100 | ||||
-rw-r--r-- | ash/wm/screen_dimmer.h | 53 | ||||
-rw-r--r-- | ash/wm/screen_dimmer_unittest.cc | 47 | ||||
-rw-r--r-- | ash/wm/system_modal_container_layout_manager.cc | 66 | ||||
-rw-r--r-- | ash/wm/system_modal_container_layout_manager.h | 8 | ||||
-rw-r--r-- | chrome/browser/chromeos/dbus/chrome_display_power_service_provider_delegate.cc | 3 | ||||
-rw-r--r-- | ui/wm/core/visibility_controller.cc | 14 | ||||
-rw-r--r-- | ui/wm/core/visibility_controller.h | 12 | ||||
-rw-r--r-- | ui/wm/core/visibility_controller_unittest.cc | 34 |
16 files changed, 320 insertions, 151 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp index e994b16..20960ee 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -525,6 +525,8 @@ 'wm/default_state.h', 'wm/default_window_resizer.cc', 'wm/default_window_resizer.h', + 'wm/dim_window.cc', + 'wm/dim_window.h', 'wm/dock/docked_window_layout_manager.cc', 'wm/dock/docked_window_layout_manager.h', 'wm/dock/docked_window_layout_manager_observer.h', diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index 97fd09e..c693858 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc @@ -39,7 +39,6 @@ #include "ash/wm/panels/panel_layout_manager.h" #include "ash/wm/panels/panel_window_event_handler.h" #include "ash/wm/root_window_layout_manager.h" -#include "ash/wm/screen_dimmer.h" #include "ash/wm/stacking_controller.h" #include "ash/wm/status_area_layout_manager.h" #include "ash/wm/system_background_controller.h" @@ -367,7 +366,6 @@ void RootWindowController::Shutdown() { CloseChildWindows(); GetRootWindowSettings(root_window)->controller = NULL; - screen_dimmer_.reset(); workspace_controller_.reset(); // Forget with the display ID so that display lookup // ends up with invalid display. @@ -694,7 +692,6 @@ RootWindowController::RootWindowController(AshWindowTreeHost* ash_host) touch_hud_projection_(NULL) { aura::Window* root_window = GetRootWindow(); GetRootWindowSettings(root_window)->controller = this; - screen_dimmer_.reset(new ScreenDimmer(root_window)); stacking_controller_.reset(new StackingController); aura::client::SetWindowTreeClient(root_window, stacking_controller_.get()); diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h index ffa19e1..1138a0d 100644 --- a/ash/root_window_controller.h +++ b/ash/root_window_controller.h @@ -54,7 +54,6 @@ class DesktopBackgroundWidgetController; class DockedWindowLayoutManager; class PanelLayoutManager; class RootWindowLayoutManager; -class ScreenDimmer; class ShelfLayoutManager; class ShelfWidget; class StackingController; @@ -121,8 +120,6 @@ class ASH_EXPORT RootWindowController : public ShellObserver { return always_on_top_controller_.get(); } - ScreenDimmer* screen_dimmer() { return screen_dimmer_.get(); } - // Access the shelf associated with this root window controller, // NULL if no such shelf exists. ShelfWidget* shelf() { return shelf_.get(); } @@ -296,7 +293,6 @@ class ASH_EXPORT RootWindowController : public ShellObserver { scoped_ptr<AshTouchExplorationManager> touch_exploration_manager_; #endif - scoped_ptr<ScreenDimmer> screen_dimmer_; scoped_ptr<WorkspaceController> workspace_controller_; scoped_ptr<AlwaysOnTopController> always_on_top_controller_; diff --git a/ash/shell.cc b/ash/shell.cc index 72eb8eb..27697f6 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -68,7 +68,6 @@ #include "ash/wm/power_button_controller.h" #include "ash/wm/resize_shadow_controller.h" #include "ash/wm/root_window_layout_manager.h" -#include "ash/wm/screen_dimmer.h" #include "ash/wm/system_gesture_event_filter.h" #include "ash/wm/system_modal_container_event_filter.h" #include "ash/wm/system_modal_container_layout_manager.h" @@ -524,13 +523,6 @@ ShelfAlignment Shell::GetShelfAlignment(const aura::Window* root_window) { ->GetAlignment(); } -void Shell::SetDimming(bool should_dim) { - RootWindowControllerList controllers = GetAllRootWindowControllers(); - for (RootWindowControllerList::iterator iter = controllers.begin(); - iter != controllers.end(); ++iter) - (*iter)->screen_dimmer()->SetDimming(should_dim); -} - void Shell::NotifyFullscreenStateChange(bool is_fullscreen, aura::Window* root_window) { FOR_EACH_OBSERVER(ShellObserver, observers_, OnFullscreenStateChanged( diff --git a/ash/shell.h b/ash/shell.h index 86382cd..5bdf6dd 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -467,9 +467,6 @@ class ASH_EXPORT Shell : public SystemModalContainerEventFilterDelegate, aura::Window* root_window); ShelfAlignment GetShelfAlignment(const aura::Window* root_window); - // Dims or undims the screen. - void SetDimming(bool should_dim); - // Notifies |observers_| when entering or exiting fullscreen mode in // |root_window|. void NotifyFullscreenStateChange(bool is_fullscreen, diff --git a/ash/wm/dim_window.cc b/ash/wm/dim_window.cc new file mode 100644 index 0000000..552789f --- /dev/null +++ b/ash/wm/dim_window.cc @@ -0,0 +1,79 @@ +// Copyright 2015 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 "ash/wm/dim_window.h" +#include "base/time/time.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/aura/window_property.h" +#include "ui/compositor/layer.h" +#include "ui/compositor/scoped_layer_animation_settings.h" +#include "ui/wm/core/visibility_controller.h" +#include "ui/wm/core/window_animations.h" + +DECLARE_WINDOW_PROPERTY_TYPE(ash::DimWindow*); + +namespace ash { +namespace { + +DEFINE_LOCAL_WINDOW_PROPERTY_KEY(DimWindow*, kDimWindowKey, nullptr); + +const int kDefaultDimAnimationDurationMs = 200; + +const float kDefaultDimOpacity = 0.5f; + +} // namespace + +// static +DimWindow* DimWindow::Get(aura::Window* container) { + return container->GetProperty(kDimWindowKey); +} + +DimWindow::DimWindow(aura::Window* parent) + : aura::Window(nullptr), parent_(parent) { + SetType(ui::wm::WINDOW_TYPE_NORMAL); + Init(ui::LAYER_SOLID_COLOR); + wm::SetWindowVisibilityChangesAnimated(this); + wm::SetWindowVisibilityAnimationType( + this, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); + wm::SetWindowVisibilityAnimationDuration( + this, base::TimeDelta::FromMilliseconds(kDefaultDimAnimationDurationMs)); + + SetDimOpacity(kDefaultDimOpacity); + + parent->AddChild(this); + parent->AddObserver(this); + parent->SetProperty(kDimWindowKey, this); + parent->StackChildAtTop(this); + + SetBounds(parent->bounds()); +} + +DimWindow::~DimWindow() { + if (parent_) { + parent_->ClearProperty(kDimWindowKey); + parent_->RemoveObserver(this); + parent_ = nullptr; + } +} + +void DimWindow::SetDimOpacity(float target_opacity) { + layer()->SetColor(SkColorSetA(SK_ColorBLACK, 255 * target_opacity)); +} + +void DimWindow::OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds) { + if (window == parent_) + SetBounds(new_bounds); +} + +void DimWindow::OnWindowDestroying(Window* window) { + if (window == parent_) { + window->ClearProperty(kDimWindowKey); + window->RemoveObserver(this); + parent_ = nullptr; + } +} + +} // namespace ash diff --git a/ash/wm/dim_window.h b/ash/wm/dim_window.h new file mode 100644 index 0000000..8d86c63 --- /dev/null +++ b/ash/wm/dim_window.h @@ -0,0 +1,35 @@ +// Copyright 2015 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 "ash/ash_export.h" +#include "base/macros.h" +#include "ui/aura/window.h" +#include "ui/aura/window_observer.h" + +namespace ash { + +// A window used to dim the child windows of the given container. +class ASH_EXPORT DimWindow : public aura::Window, public aura::WindowObserver { + public: + // Return a dim window for the container if any, or nullptr. + static DimWindow* Get(aura::Window* container); + + explicit DimWindow(aura::Window* parent); + ~DimWindow() override; + + void SetDimOpacity(float target_opacity); + + // aura::WindowObserver: + void OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds) override; + void OnWindowDestroying(aura::Window* window) override; + + private: + aura::Window* parent_; + + DISALLOW_COPY_AND_ASSIGN(DimWindow); +}; + +} // namespace ash diff --git a/ash/wm/screen_dimmer.cc b/ash/wm/screen_dimmer.cc index 90edc69..6c74888 100644 --- a/ash/wm/screen_dimmer.cc +++ b/ash/wm/screen_dimmer.cc @@ -5,62 +5,102 @@ #include "ash/wm/screen_dimmer.h" #include "ash/shell.h" +#include "ash/wm/dim_window.h" #include "base/time/time.h" #include "ui/aura/window_event_dispatcher.h" +#include "ui/aura/window_property.h" #include "ui/compositor/layer.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" +DECLARE_WINDOW_PROPERTY_TYPE(ash::ScreenDimmer*); + namespace ash { namespace { +DEFINE_OWNED_WINDOW_PROPERTY_KEY(ScreenDimmer, kScreenDimmerKey, nullptr); + +// Opacity when it's dimming the entire screen. +const float kDimmingLayerOpacityForRoot = 0.4f; -// Opacity for |dimming_layer_| when it's dimming the screen. -const float kDimmingLayerOpacity = 0.4f; +const int kRootWindowMagicId = -100; -// Duration for dimming animations, in milliseconds. -const int kDimmingTransitionMs = 200; +std::vector<aura::Window*> GetAllContainers(int container_id) { + return container_id == kRootWindowMagicId + ? Shell::GetAllRootWindows() + : Shell::GetContainersFromAllRootWindows(container_id, nullptr); +} } // namespace -ScreenDimmer::ScreenDimmer(aura::Window* root_window) - : root_window_(root_window), - currently_dimming_(false) { - root_window_->AddObserver(this); +// static +ScreenDimmer* ScreenDimmer::GetForContainer(int container_id) { + aura::Window* primary_container = FindContainer(container_id); + ScreenDimmer* dimmer = primary_container->GetProperty(kScreenDimmerKey); + if (!dimmer) { + dimmer = new ScreenDimmer(container_id); + primary_container->SetProperty(kScreenDimmerKey, dimmer); + } + return dimmer; +} + +// static +ScreenDimmer* ScreenDimmer::GetForRoot() { + ScreenDimmer* dimmer = GetForContainer(kRootWindowMagicId); + // Root window's dimmer + dimmer->target_opacity_ = kDimmingLayerOpacityForRoot; + return dimmer; +} + +ScreenDimmer::ScreenDimmer(int container_id) + : container_id_(container_id), target_opacity_(0.5f), is_dimming_(false) { + Shell::GetInstance()->AddShellObserver(this); } ScreenDimmer::~ScreenDimmer() { - root_window_->RemoveObserver(this); + Shell::GetInstance()->RemoveShellObserver(this); } void ScreenDimmer::SetDimming(bool should_dim) { - if (should_dim == currently_dimming_) + if (should_dim == is_dimming_) return; + is_dimming_ = should_dim; - if (!dimming_layer_) { - dimming_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR)); - dimming_layer_->SetColor(SK_ColorBLACK); - dimming_layer_->SetOpacity(0.0f); - ui::Layer* root_layer = root_window_->layer(); - dimming_layer_->SetBounds(root_layer->bounds()); - root_layer->Add(dimming_layer_.get()); - root_layer->StackAtTop(dimming_layer_.get()); - } + Update(should_dim); +} - currently_dimming_ = should_dim; +ScreenDimmer* ScreenDimmer::FindForTest(int container_id) { + return FindContainer(container_id)->GetProperty(kScreenDimmerKey); +} - ui::ScopedLayerAnimationSettings scoped_settings( - dimming_layer_->GetAnimator()); - scoped_settings.SetTransitionDuration( - base::TimeDelta::FromMilliseconds(kDimmingTransitionMs)); - dimming_layer_->SetOpacity(should_dim ? kDimmingLayerOpacity : 0.0f); +// static +aura::Window* ScreenDimmer::FindContainer(int container_id) { + aura::Window* primary = Shell::GetPrimaryRootWindow(); + return container_id == kRootWindowMagicId + ? primary + : primary->GetChildById(container_id); } -void ScreenDimmer::OnWindowBoundsChanged(aura::Window* root, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds) { - if (dimming_layer_) - dimming_layer_->SetBounds(gfx::Rect(root->bounds().size())); +void ScreenDimmer::OnRootWindowAdded(aura::Window* root_window) { + Update(is_dimming_); +} + +void ScreenDimmer::Update(bool should_dim) { + for (aura::Window* container : GetAllContainers(container_id_)) { + DimWindow* dim = DimWindow::Get(container); + if (should_dim) { + if (!dim) { + dim = new DimWindow(container); + dim->SetDimOpacity(target_opacity_); + } + dim->Show(); + } else { + if (dim) { + dim->Hide(); + delete dim; + } + } + } } } // namespace ash diff --git a/ash/wm/screen_dimmer.h b/ash/wm/screen_dimmer.h index a0b3fa5..6d26e68 100644 --- a/ash/wm/screen_dimmer.h +++ b/ash/wm/screen_dimmer.h @@ -6,6 +6,7 @@ #define ASH_WM_SCREEN_DIMMER_H_ #include "ash/ash_export.h" +#include "ash/shell_observer.h" #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" @@ -16,50 +17,52 @@ class Layer; } namespace ash { +class DimWindow; // ScreenDimmer displays a partially-opaque layer above everything -// else in the root window to darken the display. It shouldn't be used -// for long-term brightness adjustments due to performance +// else in the given container window to darken the display. It shouldn't be +// used for long-term brightness adjustments due to performance // considerations -- it's only intended for cases where we want to // briefly dim the screen (e.g. to indicate to the user that we're // about to suspend a machine that lacks an internal backlight that // can be adjusted). -class ASH_EXPORT ScreenDimmer : public aura::WindowObserver { +class ASH_EXPORT ScreenDimmer : ShellObserver { public: - class TestApi { - public: - explicit TestApi(ScreenDimmer* dimmer) : dimmer_(dimmer) {} + // Creates a screen dimmer for the containers given by |container_id|. + // It's owned by the container in the primary root window and will be + // destroyed when the container is destroyed. + static ScreenDimmer* GetForContainer(int container_id); - ui::Layer* layer() { return dimmer_->dimming_layer_.get(); } + // Creates a dimmer a root window level. This is used for suspend animation. + static ScreenDimmer* GetForRoot(); - private: - ScreenDimmer* dimmer_; // not owned - - DISALLOW_COPY_AND_ASSIGN(TestApi); - }; - - explicit ScreenDimmer(aura::Window* root_window); ~ScreenDimmer() override; - // Dim or undim the root window. + // Dim or undim the layers. void SetDimming(bool should_dim); - // aura::WindowObserver overrides: - void OnWindowBoundsChanged(aura::Window* root_window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds) override; + bool is_dimming() const { return is_dimming_; } + + // Find a ScreenDimmer in the container, or nullptr if it does not exist. + static ScreenDimmer* FindForTest(int container_id); private: - friend class TestApi; + static aura::Window* FindContainer(int container_id); + + explicit ScreenDimmer(int container_id); + + // ShellObserver: + void OnRootWindowAdded(aura::Window* root_window) override; - aura::Window* root_window_; + // Update the dimming state. This will also create a new DimWindow + // if necessary. (Used when a new display is connected) + void Update(bool should_dim); - // Partially-opaque layer that's stacked above all of the root window's - // children and used to dim the screen. NULL until the first time we dim. - scoped_ptr<ui::Layer> dimming_layer_; + int container_id_; + float target_opacity_; // Are we currently dimming the screen? - bool currently_dimming_; + bool is_dimming_; DISALLOW_COPY_AND_ASSIGN(ScreenDimmer); }; diff --git a/ash/wm/screen_dimmer_unittest.cc b/ash/wm/screen_dimmer_unittest.cc index 244beec..9b1bdc6 100644 --- a/ash/wm/screen_dimmer_unittest.cc +++ b/ash/wm/screen_dimmer_unittest.cc @@ -7,6 +7,7 @@ #include "ash/root_window_controller.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/dim_window.h" #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "ui/aura/window_event_dispatcher.h" @@ -17,53 +18,56 @@ namespace test { class ScreenDimmerTest : public AshTestBase { public: - ScreenDimmerTest() : dimmer_(NULL) {} + ScreenDimmerTest() : dimmer_(nullptr) {} ~ScreenDimmerTest() override {} void SetUp() override { AshTestBase::SetUp(); - dimmer_ = Shell::GetPrimaryRootWindowController()->screen_dimmer(); - test_api_.reset(new ScreenDimmer::TestApi(dimmer_)); + dimmer_ = ScreenDimmer::GetForRoot(); + } + + aura::Window* GetDimWindow() { + return DimWindow::Get(Shell::GetPrimaryRootWindow()); + } + + ui::Layer* GetDimWindowLayer() { + aura::Window* window = GetDimWindow(); + return window ? window->layer() : nullptr; } protected: ScreenDimmer* dimmer_; // not owned - scoped_ptr<ScreenDimmer::TestApi> test_api_; - private: DISALLOW_COPY_AND_ASSIGN(ScreenDimmerTest); }; TEST_F(ScreenDimmerTest, DimAndUndim) { // Don't create a layer until we need to. - EXPECT_TRUE(test_api_->layer() == NULL); + EXPECT_EQ(nullptr, GetDimWindowLayer()); dimmer_->SetDimming(false); - EXPECT_TRUE(test_api_->layer() == NULL); + EXPECT_EQ(nullptr, GetDimWindowLayer()); // When we enable dimming, the layer should be created and stacked at the top // of the root's children. dimmer_->SetDimming(true); - ASSERT_TRUE(test_api_->layer() != NULL); + ASSERT_NE(nullptr, GetDimWindowLayer()); ui::Layer* root_layer = Shell::GetPrimaryRootWindow()->layer(); ASSERT_TRUE(!root_layer->children().empty()); - EXPECT_EQ(test_api_->layer(), root_layer->children().back()); - EXPECT_TRUE(test_api_->layer()->visible()); - EXPECT_GT(test_api_->layer()->GetTargetOpacity(), 0.0f); + EXPECT_EQ(GetDimWindowLayer(), root_layer->children().back()); + EXPECT_TRUE(GetDimWindowLayer()->visible()); + EXPECT_GT(GetDimWindowLayer()->GetTargetOpacity(), 0.0f); - // When we disable dimming, the layer should be animated back to full - // transparency. + // When we disable dimming, the layer should be removed. dimmer_->SetDimming(false); - ASSERT_TRUE(test_api_->layer() != NULL); - EXPECT_TRUE(test_api_->layer()->visible()); - EXPECT_FLOAT_EQ(0.0f, test_api_->layer()->GetTargetOpacity()); + ASSERT_EQ(nullptr, GetDimWindowLayer()); } TEST_F(ScreenDimmerTest, ResizeLayer) { // The dimming layer should be initially sized to cover the root window. dimmer_->SetDimming(true); - ui::Layer* dimming_layer = test_api_->layer(); - ASSERT_TRUE(dimming_layer != NULL); + ui::Layer* dimming_layer = GetDimWindowLayer(); + ASSERT_TRUE(dimming_layer != nullptr); ui::Layer* root_layer = Shell::GetPrimaryRootWindow()->layer(); EXPECT_EQ(gfx::Rect(root_layer->bounds().size()).ToString(), dimming_layer->bounds().ToString()); @@ -75,5 +79,12 @@ TEST_F(ScreenDimmerTest, ResizeLayer) { EXPECT_EQ(kNewBounds.ToString(), dimming_layer->bounds().ToString()); } +TEST_F(ScreenDimmerTest, RootDimmer) { + ScreenDimmer* root_dimmer = ScreenDimmer::GetForRoot(); + // -100 is the magic number for root window. + EXPECT_EQ(root_dimmer, ScreenDimmer::FindForTest(-100)); + EXPECT_EQ(nullptr, ScreenDimmer::FindForTest(-1)); +} + } // namespace test } // namespace ash diff --git a/ash/wm/system_modal_container_layout_manager.cc b/ash/wm/system_modal_container_layout_manager.cc index e5702fa..725cd2b 100644 --- a/ash/wm/system_modal_container_layout_manager.cc +++ b/ash/wm/system_modal_container_layout_manager.cc @@ -9,35 +9,26 @@ #include "ash/session/session_state_delegate.h" #include "ash/shell.h" #include "ash/shell_window_ids.h" -#include "ash/wm/system_modal_container_event_filter.h" -#include "ash/wm/window_animations.h" +#include "ash/wm/dim_window.h" #include "ash/wm/window_util.h" -#include "base/bind.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/capture_client.h" #include "ui/aura/window.h" -#include "ui/aura/window_event_dispatcher.h" #include "ui/aura/window_property.h" -#include "ui/base/ui_base_switches_util.h" #include "ui/compositor/layer.h" -#include "ui/compositor/layer_animator.h" -#include "ui/compositor/scoped_layer_animation_settings.h" -#include "ui/events/event.h" -#include "ui/gfx/screen.h" #include "ui/keyboard/keyboard_controller.h" -#include "ui/views/background.h" -#include "ui/views/view.h" -#include "ui/views/widget/widget.h" -#include "ui/wm/core/compound_event_filter.h" namespace ash { +namespace { +// The center point of the window can diverge this much from the center point // If this is set to true, the window will get centered. DEFINE_WINDOW_PROPERTY_KEY(bool, kCenteredKey, false); // The center point of the window can diverge this much from the center point // of the container to be kept centered upon resizing operations. const int kCenterPixelDelta = 32; +} //////////////////////////////////////////////////////////////////////////////// // SystemModalContainerLayoutManager, public: @@ -46,8 +37,7 @@ SystemModalContainerLayoutManager::SystemModalContainerLayoutManager( aura::Window* container) : SnapToPixelLayoutManager(container), container_(container), - modal_background_(NULL) { -} + modal_background_(nullptr) {} SystemModalContainerLayoutManager::~SystemModalContainerLayoutManager() { } @@ -56,17 +46,12 @@ SystemModalContainerLayoutManager::~SystemModalContainerLayoutManager() { // SystemModalContainerLayoutManager, aura::LayoutManager implementation: void SystemModalContainerLayoutManager::OnWindowResized() { - if (modal_background_) { - // Note: we have to set the entire bounds with the screen offset. - modal_background_->SetBounds( - Shell::GetScreen()->GetDisplayNearestWindow(container_).bounds()); - } PositionDialogsAfterWorkAreaResize(); } void SystemModalContainerLayoutManager::OnWindowAddedToLayout( aura::Window* child) { - DCHECK((modal_background_ && child == modal_background_->GetNativeView()) || + DCHECK(child == modal_background_ || child->type() == ui::wm::WINDOW_TYPE_NORMAL || child->type() == ui::wm::WINDOW_TYPE_POPUP); DCHECK( @@ -112,10 +97,10 @@ void SystemModalContainerLayoutManager::OnWindowPropertyChanged( void SystemModalContainerLayoutManager::OnWindowDestroying( aura::Window* window) { - if (modal_background_ && modal_background_->GetNativeView() == window) { + if (modal_background_ == window) { if (keyboard::KeyboardController::GetInstance()) keyboard::KeyboardController::GetInstance()->RemoveObserver(this); - modal_background_ = NULL; + modal_background_ = nullptr; } } @@ -155,32 +140,14 @@ bool SystemModalContainerLayoutManager::ActivateNextModalWindow() { void SystemModalContainerLayoutManager::CreateModalBackground() { if (!modal_background_) { - modal_background_ = new views::Widget; - views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL); - params.parent = container_; - params.bounds = Shell::GetScreen()->GetDisplayNearestWindow( - container_).bounds(); - modal_background_->Init(params); - modal_background_->GetNativeView()->SetName( + modal_background_ = new DimWindow(container_); + modal_background_->SetName( "SystemModalContainerLayoutManager.ModalBackground"); - views::View* contents_view = new views::View(); - // TODO(jamescook): This could be SK_ColorWHITE for the new dialog style. - contents_view->set_background( - views::Background::CreateSolidBackground(SK_ColorBLACK)); - modal_background_->SetContentsView(contents_view); - modal_background_->GetNativeView()->layer()->SetOpacity(0.0f); // There isn't always a keyboard controller. if (keyboard::KeyboardController::GetInstance()) keyboard::KeyboardController::GetInstance()->AddObserver(this); } - - ui::ScopedLayerAnimationSettings settings( - modal_background_->GetNativeView()->layer()->GetAnimator()); - // Show should not be called with a target opacity of 0. We therefore start - // the fade to show animation before Show() is called. - modal_background_->GetNativeView()->layer()->SetOpacity(0.5f); modal_background_->Show(); - container_->StackChildAtTop(modal_background_->GetNativeView()); } void SystemModalContainerLayoutManager::DestroyModalBackground() { @@ -189,11 +156,11 @@ void SystemModalContainerLayoutManager::DestroyModalBackground() { if (modal_background_) { if (keyboard::KeyboardController::GetInstance()) keyboard::KeyboardController::GetInstance()->RemoveObserver(this); - ::wm::ScopedHidingAnimationSettings settings( - modal_background_->GetNativeView()); - modal_background_->Close(); - modal_background_->GetNativeView()->layer()->SetOpacity(0.0f); - modal_background_ = NULL; + modal_background_->Hide(); + // Explicitly delete instead of using scoped_ptr as the owner of the + // window is its parent. + delete modal_background_; + modal_background_ = nullptr; } } @@ -207,8 +174,7 @@ bool SystemModalContainerLayoutManager::IsModalBackground( SystemModalContainerLayoutManager* layout_manager = static_cast<SystemModalContainerLayoutManager*>( window->parent()->layout_manager()); - return layout_manager->modal_background_ && - layout_manager->modal_background_->GetNativeWindow() == window; + return layout_manager->modal_background_ == window; } //////////////////////////////////////////////////////////////////////////////// diff --git a/ash/wm/system_modal_container_layout_manager.h b/ash/wm/system_modal_container_layout_manager.h index 59c0eac..5818708 100644 --- a/ash/wm/system_modal_container_layout_manager.h +++ b/ash/wm/system_modal_container_layout_manager.h @@ -22,11 +22,9 @@ class EventFilter; namespace gfx { class Rect; } -namespace views { -class Widget; -} namespace ash { +class DimWindow; // LayoutManager for the modal window container. // System modal windows which are centered on the screen will be kept centered @@ -98,9 +96,9 @@ class ASH_EXPORT SystemModalContainerLayoutManager // The container that owns the layout manager. aura::Window* container_; - // A widget that dims the windows behind the modal window(s) being + // A window that dims the windows behind the modal window(s) being // shown in |container_|. - views::Widget* modal_background_; + DimWindow* modal_background_; // A stack of modal windows. Only the topmost can receive events. std::vector<aura::Window*> modal_windows_; diff --git a/chrome/browser/chromeos/dbus/chrome_display_power_service_provider_delegate.cc b/chrome/browser/chromeos/dbus/chrome_display_power_service_provider_delegate.cc index 57269d9..e5badf7 100644 --- a/chrome/browser/chromeos/dbus/chrome_display_power_service_provider_delegate.cc +++ b/chrome/browser/chromeos/dbus/chrome_display_power_service_provider_delegate.cc @@ -5,6 +5,7 @@ #include "chrome/browser/chromeos/dbus/chrome_display_power_service_provider_delegate.h" #include "ash/shell.h" +#include "ash/wm/screen_dimmer.h" #include "ui/base/user_activity/user_activity_detector.h" #include "ui/display/chromeos/display_configurator.h" @@ -32,7 +33,7 @@ void ChromeDisplayPowerServiceProviderDelegate::SetDisplayPower( } void ChromeDisplayPowerServiceProviderDelegate::SetDimming(bool dimmed) { - ash::Shell::GetInstance()->SetDimming(dimmed); + ash::ScreenDimmer::GetForRoot()->SetDimming(dimmed); } } // namespace chromeos diff --git a/ui/wm/core/visibility_controller.cc b/ui/wm/core/visibility_controller.cc index fc187a9..fd7bb88a 100644 --- a/ui/wm/core/visibility_controller.cc +++ b/ui/wm/core/visibility_controller.cc @@ -18,9 +18,14 @@ namespace { DEFINE_WINDOW_PROPERTY_KEY( bool, kChildWindowVisibilityChangesAnimatedKey, false); +// A window with this property set will animate upon its visibility changes. +DEFINE_WINDOW_PROPERTY_KEY(bool, kWindowVisibilityChangesAnimatedKey, false); + bool ShouldAnimateWindow(aura::Window* window) { - return window->parent() && window->parent()->GetProperty( - kChildWindowVisibilityChangesAnimatedKey); + return (window->parent() && + window->parent()->GetProperty( + kChildWindowVisibilityChangesAnimatedKey)) || + window->GetProperty(kWindowVisibilityChangesAnimatedKey); } } // namespace @@ -81,9 +86,12 @@ SuspendChildWindowVisibilityAnimations:: window_->ClearProperty(kChildWindowVisibilityChangesAnimatedKey); } +void SetWindowVisibilityChangesAnimated(aura::Window* window) { + window->SetProperty(kWindowVisibilityChangesAnimatedKey, true); +} + void SetChildWindowVisibilityChangesAnimated(aura::Window* window) { window->SetProperty(kChildWindowVisibilityChangesAnimatedKey, true); } } // namespace wm - diff --git a/ui/wm/core/visibility_controller.h b/ui/wm/core/visibility_controller.h index c6f5258..0e30454 100644 --- a/ui/wm/core/visibility_controller.h +++ b/ui/wm/core/visibility_controller.h @@ -64,7 +64,17 @@ class WM_EXPORT SuspendChildWindowVisibilityAnimations { DISALLOW_COPY_AND_ASSIGN(SuspendChildWindowVisibilityAnimations); }; -// Tells |window| to animate visibility changes to its children. +// Enable visibility change animation for specific |window|. Use this if +// you want to enable visibility change animation on a specific window without +// affecting other windows in the same container. Calling this on a window +// whose animation is already enabled either by this function, or +// via SetChildWindowVisibilityChangesAnimatedbelow below is allowed and +// the animation stays enabled. +void WM_EXPORT SetWindowVisibilityChangesAnimated(aura::Window* window); + +// Enable visibiilty change animation for all children of the |window|. +// Tyically applied to a container whose child windows should be animated +// when their visibility changes. void WM_EXPORT SetChildWindowVisibilityChangesAnimated( aura::Window* window); diff --git a/ui/wm/core/visibility_controller_unittest.cc b/ui/wm/core/visibility_controller_unittest.cc index 01731ef..39a1d49 100644 --- a/ui/wm/core/visibility_controller_unittest.cc +++ b/ui/wm/core/visibility_controller_unittest.cc @@ -13,6 +13,7 @@ #include "ui/compositor/layer_animator.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/compositor/scoped_layer_animation_settings.h" +#include "ui/wm/core/window_animations.h" namespace wm { @@ -53,4 +54,37 @@ TEST_F(VisibilityControllerTest, AnimateTransparencyToZeroAndHideHides) { EXPECT_FALSE(window->IsVisible()); } +// Test if SetWindowVisibilityChagngesAnimated will animate the specified +// window. +TEST_F(VisibilityControllerTest, SetWindowVisibilityChagnesAnimated) { + // We cannot disable animations for this test. + ui::ScopedAnimationDurationScaleMode test_duration_mode( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + VisibilityController controller; + aura::client::SetVisibilityClient(root_window(), &controller); + + aura::test::TestWindowDelegate d; + scoped_ptr<aura::Window> window(aura::test::CreateTestWindowWithDelegate( + &d, -2, gfx::Rect(0, 0, 50, 50), root_window())); + // Test using Show animation because Hide animation detaches the window's + // layer. + window->Hide(); + ASSERT_FALSE(window->IsVisible()); + + SetWindowVisibilityChangesAnimated(window.get()); + SetWindowVisibilityAnimationDuration(window.get(), + base::TimeDelta::FromMilliseconds(5)); + SetWindowVisibilityAnimationType(window.get(), + WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); + window->Show(); + EXPECT_TRUE(window->layer()->GetAnimator()->is_animating()); + EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity()); + EXPECT_EQ(0.0f, window->layer()->opacity()); + + window->layer()->GetAnimator()->StopAnimating(); + EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity()); + EXPECT_EQ(1.0f, window->layer()->opacity()); +} + } // namespace wm |