summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroshima <oshima@chromium.org>2015-10-21 18:08:08 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-22 01:09:51 +0000
commitcefa50b01ed3d5d592f66ab56b5b3934b5ad9070 (patch)
tree82ae51cbe6a1343145a4ccd34dbbd7a9ed95fb3d
parent1effc29d7e15f64791405c5d0af30b24040fc1d7 (diff)
downloadchromium_src-cefa50b01ed3d5d592f66ab56b5b3934b5ad9070.zip
chromium_src-cefa50b01ed3d5d592f66ab56b5b3934b5ad9070.tar.gz
chromium_src-cefa50b01ed3d5d592f66ab56b5b3934b5ad9070.tar.bz2
Refactor screen_dimmer to share code and shrink Shell interface.
DimWindow : a window that implement dimming. You can just add it to container and let it handle its state. ScreenDimmer : an object that keeps the state consistent across multiple root windows. It's owned by the primary container and gets destroyed when the container is destroyed. * Added wm::SetWindowVisiblityChangesAnimated to ui/wm/core/visibility_controller.h, to animate individual window's visibility change. The dim layer can be added to root (or any other container), and we probably don't want to enable animation for all children in such case. * Use solid color layer for modal background. it's more efficient. BUG=478438 TEST=updated existing screen_dimmer_unittest, VisibilityControllerTest.SetWindowVisibilityChangesAnimated Review URL: https://codereview.chromium.org/1415033002 Cr-Commit-Position: refs/heads/master@{#355468}
-rw-r--r--ash/ash.gyp2
-rw-r--r--ash/root_window_controller.cc3
-rw-r--r--ash/root_window_controller.h4
-rw-r--r--ash/shell.cc8
-rw-r--r--ash/shell.h3
-rw-r--r--ash/wm/dim_window.cc79
-rw-r--r--ash/wm/dim_window.h35
-rw-r--r--ash/wm/screen_dimmer.cc100
-rw-r--r--ash/wm/screen_dimmer.h53
-rw-r--r--ash/wm/screen_dimmer_unittest.cc47
-rw-r--r--ash/wm/system_modal_container_layout_manager.cc66
-rw-r--r--ash/wm/system_modal_container_layout_manager.h8
-rw-r--r--chrome/browser/chromeos/dbus/chrome_display_power_service_provider_delegate.cc3
-rw-r--r--ui/wm/core/visibility_controller.cc14
-rw-r--r--ui/wm/core/visibility_controller.h12
-rw-r--r--ui/wm/core/visibility_controller_unittest.cc34
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