summaryrefslogtreecommitdiffstats
path: root/ash/wm
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-27 16:03:48 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-27 16:03:48 +0000
commitddd91e99989b2aa7539516f673f746f088cc607c (patch)
tree3f32d988f46f677e504b8fe42829cfce80962da7 /ash/wm
parent92c0ca8e8f3873d7cbd8b72d751ba0106486c7dc (diff)
downloadchromium_src-ddd91e99989b2aa7539516f673f746f088cc607c.zip
chromium_src-ddd91e99989b2aa7539516f673f746f088cc607c.tar.gz
chromium_src-ddd91e99989b2aa7539516f673f746f088cc607c.tar.bz2
Allow hide animations to work again:
- Introduces VisibilityClient, which aura::Window defers to to update layer visibility, if present. This replaces code which previously undid layer visibility changes after they were set. Layer visibility changes are potentially destructiver (they can drop textures associated with the layer and require a repaint). - Implements this in ash in VisibilityController, which animates the visibility changes of children in annotated parents. - Annotates various windows as requiring child window visibility change animations. This replaces animating visibility changes in LayoutManagers. - Adds a second layer of visibility determination to aura::Window. Some code may check Window->IsVisible which was simply testing layer visibility. We want Window->IsVisible to return false as soon as Window::Hide() is called, so we add a member for this. - We prevent stacking changes to the window from being propagated to the layer if the layer's delegate has been detached (i.e. the layer is hiding) BUG=none TEST=none Review URL: https://chromiumcodereview.appspot.com/9235016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@119453 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/wm')
-rw-r--r--ash/wm/menu_container_layout_manager.cc46
-rw-r--r--ash/wm/menu_container_layout_manager.h36
-rw-r--r--ash/wm/system_modal_container_layout_manager.cc1
-rw-r--r--ash/wm/toplevel_layout_manager.cc1
-rw-r--r--ash/wm/visibility_controller.cc54
-rw-r--r--ash/wm/visibility_controller.h37
-rw-r--r--ash/wm/visibility_controller_unittest.cc46
-rw-r--r--ash/wm/window_animations.cc19
8 files changed, 145 insertions, 95 deletions
diff --git a/ash/wm/menu_container_layout_manager.cc b/ash/wm/menu_container_layout_manager.cc
deleted file mode 100644
index f440f5b..0000000
--- a/ash/wm/menu_container_layout_manager.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2012 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/menu_container_layout_manager.h"
-
-#include "ash/wm/window_animations.h"
-#include "ui/aura/client/window_types.h"
-#include "ui/aura/window.h"
-
-namespace ash {
-namespace internal {
-
-MenuContainerLayoutManager::MenuContainerLayoutManager() {
-}
-
-MenuContainerLayoutManager::~MenuContainerLayoutManager() {
-}
-
-void MenuContainerLayoutManager::OnWindowResized() {
-}
-
-void MenuContainerLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
- DCHECK(child->type() == aura::client::WINDOW_TYPE_MENU ||
- child->type() == aura::client::WINDOW_TYPE_TOOLTIP);
-}
-
-void MenuContainerLayoutManager::OnWillRemoveWindowFromLayout(
- aura::Window* child) {
-}
-
-void MenuContainerLayoutManager::OnChildWindowVisibilityChanged(
- aura::Window* child,
- bool visible) {
- if (child->type() == aura::client::WINDOW_TYPE_TOOLTIP)
- AnimateOnChildWindowVisibilityChanged(child, visible);
-}
-
-void MenuContainerLayoutManager::SetChildBounds(
- aura::Window* child,
- const gfx::Rect& requested_bounds) {
- SetChildBoundsDirect(child, requested_bounds);
-}
-
-} // namespace internal
-} // namespace ash
diff --git a/ash/wm/menu_container_layout_manager.h b/ash/wm/menu_container_layout_manager.h
deleted file mode 100644
index 9395c1f..0000000
--- a/ash/wm/menu_container_layout_manager.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef ASH_WM_MENU_CONTAINER_LAYOUT_MANAGER_H_
-#define ASH_WM_MENU_CONTAINER_LAYOUT_MANAGER_H_
-#pragma once
-
-#include "base/compiler_specific.h"
-#include "ui/aura/layout_manager.h"
-
-namespace ash {
-namespace internal {
-
-class MenuContainerLayoutManager : public aura::LayoutManager {
- public:
- MenuContainerLayoutManager();
- virtual ~MenuContainerLayoutManager();
-
- // Overridden from aura::LayoutManager:
- virtual void OnWindowResized() OVERRIDE;
- virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE;
- virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE;
- virtual void OnChildWindowVisibilityChanged(aura::Window* child,
- bool visible) OVERRIDE;
- virtual void SetChildBounds(aura::Window* child,
- const gfx::Rect& requested_bounds) OVERRIDE;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MenuContainerLayoutManager);
-};
-
-} // namespace internal
-} // namespace ash
-
-#endif // ASH_WM_MENU_CONTAINER_LAYOUT_MANAGER_H_
diff --git a/ash/wm/system_modal_container_layout_manager.cc b/ash/wm/system_modal_container_layout_manager.cc
index 8a585ac..01a7bfb 100644
--- a/ash/wm/system_modal_container_layout_manager.cc
+++ b/ash/wm/system_modal_container_layout_manager.cc
@@ -95,7 +95,6 @@ void SystemModalContainerLayoutManager::OnWillRemoveWindowFromLayout(
void SystemModalContainerLayoutManager::OnChildWindowVisibilityChanged(
aura::Window* child,
bool visible) {
- AnimateOnChildWindowVisibilityChanged(child, visible);
}
void SystemModalContainerLayoutManager::SetChildBounds(
diff --git a/ash/wm/toplevel_layout_manager.cc b/ash/wm/toplevel_layout_manager.cc
index e880eec..64302d2 100644
--- a/ash/wm/toplevel_layout_manager.cc
+++ b/ash/wm/toplevel_layout_manager.cc
@@ -62,7 +62,6 @@ void ToplevelLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
void ToplevelLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
bool visible) {
BaseLayoutManager::OnChildWindowVisibilityChanged(child, visible);
- AnimateOnChildWindowVisibilityChanged(child, visible);
UpdateShelfVisibility();
}
diff --git a/ash/wm/visibility_controller.cc b/ash/wm/visibility_controller.cc
new file mode 100644
index 0000000..8006ff3
--- /dev/null
+++ b/ash/wm/visibility_controller.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2012 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/visibility_controller.h"
+
+#include "ash/wm/window_animations.h"
+#include "ui/aura/window.h"
+
+namespace ash {
+namespace internal {
+namespace {
+
+// Property set on all windows whose child windows' visibility changes are
+// animated. The type of the value is bool.
+const char kChildWindowVisibilityChangesAnimated[] =
+ "ash/wm/ChildWindowVisibilityChangesAnimated";
+
+bool GetChildWindowVisibilityChangesAnimated(aura::Window* window) {
+ if (!window)
+ return false;
+ return window->GetIntProperty(kChildWindowVisibilityChangesAnimated) != 0;
+}
+
+} // namespace
+
+VisibilityController::VisibilityController() {
+}
+
+VisibilityController::~VisibilityController() {
+}
+
+void VisibilityController::UpdateLayerVisibility(aura::Window* window,
+ bool visible) {
+ bool animated = GetChildWindowVisibilityChangesAnimated(window->parent()) &&
+ window->type() != aura::client::WINDOW_TYPE_CONTROL &&
+ window->type() != aura::client::WINDOW_TYPE_UNKNOWN;
+ if (animated)
+ AnimateOnChildWindowVisibilityChanged(window, visible);
+
+ // When a window is made visible, we always make its layer visible
+ // immediately. When a window is hidden, the layer must be left visible and
+ // only made not visible once the animation is complete.
+ if (!animated || visible)
+ window->layer()->SetVisible(visible);
+}
+
+} // namespace internal
+
+void SetChildWindowVisibilityChangesAnimated(aura::Window* window) {
+ window->SetIntProperty(internal::kChildWindowVisibilityChangesAnimated, 1);
+}
+
+} // namespace ash
diff --git a/ash/wm/visibility_controller.h b/ash/wm/visibility_controller.h
new file mode 100644
index 0000000..df8f82f
--- /dev/null
+++ b/ash/wm/visibility_controller.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2012 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.
+
+#ifndef ASH_WM_VISIBILITY_CONTROLLER_H_
+#define ASH_WM_VISIBILITY_CONTROLLER_H_
+#pragma once
+
+#include "ash/ash_export.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "ui/aura/client/visibility_client.h"
+
+namespace ash {
+namespace internal {
+
+class VisibilityController : public aura::client::VisibilityClient {
+ public:
+ VisibilityController();
+ virtual ~VisibilityController();
+
+ // Overridden from aura::client::VisibilityClient:
+ virtual void UpdateLayerVisibility(aura::Window* window,
+ bool visible) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VisibilityController);
+};
+
+} // namespace internal
+
+// Tells |window| to animate visibility changes to its children.
+void ASH_EXPORT SetChildWindowVisibilityChangesAnimated(aura::Window* window);
+
+} // namespace ash
+
+#endif // ASH_WM_VISIBILITY_CONTROLLER_H_
diff --git a/ash/wm/visibility_controller_unittest.cc b/ash/wm/visibility_controller_unittest.cc
new file mode 100644
index 0000000..aaa15a5
--- /dev/null
+++ b/ash/wm/visibility_controller_unittest.cc
@@ -0,0 +1,46 @@
+// Copyright (c) 2012 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/visibility_controller.h"
+
+#include "ash/test/aura_shell_test_base.h"
+#include "ui/aura/test/test_windows.h"
+#include "ui/aura/test/test_window_delegate.h"
+#include "ui/aura/window.h"
+
+namespace ash {
+namespace internal {
+
+typedef test::AuraShellTestBase VisibilityControllerTest;
+
+// Hiding a window in an animatable container should not hide the window's layer
+// immediately.
+TEST_F(VisibilityControllerTest, AnimateHideDoesntHideWindowLayer) {
+ scoped_ptr<aura::Window> container(
+ aura::test::CreateTestWindowWithId(-1, NULL));
+ SetChildWindowVisibilityChangesAnimated(container.get());
+
+ aura::test::TestWindowDelegate d;
+ scoped_ptr<aura::Window> animatable(
+ aura::test::CreateTestWindowWithDelegate(
+ &d, -2, gfx::Rect(0, 0, 50, 50), container.get()));
+ scoped_ptr<aura::Window> non_animatable(
+ aura::test::CreateTestWindowWithDelegateAndType(
+ &d, aura::client::WINDOW_TYPE_CONTROL, -3, gfx::Rect(51, 51, 50, 50),
+ container.get()));
+ EXPECT_TRUE(animatable->IsVisible());
+ EXPECT_TRUE(animatable->layer()->visible());
+ animatable->Hide();
+ EXPECT_FALSE(animatable->IsVisible());
+ EXPECT_TRUE(animatable->layer()->visible());
+
+ EXPECT_TRUE(non_animatable->IsVisible());
+ EXPECT_TRUE(non_animatable->layer()->visible());
+ non_animatable->Hide();
+ EXPECT_FALSE(non_animatable->IsVisible());
+ EXPECT_FALSE(non_animatable->layer()->visible());
+}
+
+} // namespace internal
+} // namespace ash
diff --git a/ash/wm/window_animations.cc b/ash/wm/window_animations.cc
index 91779da..d644f2e 100644
--- a/ash/wm/window_animations.cc
+++ b/ash/wm/window_animations.cc
@@ -102,6 +102,7 @@ class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver,
void AnimateShowWindowCommon(aura::Window* window,
const ui::Transform& start_transform,
const ui::Transform& end_transform) {
+ window->layer()->set_delegate(window);
window->layer()->SetOpacity(kWindowAnimation_HideOpacity);
window->layer()->SetTransform(start_transform);
@@ -117,18 +118,14 @@ void AnimateShowWindowCommon(aura::Window* window,
// its transform to |end_transform|.
void AnimateHideWindowCommon(aura::Window* window,
const ui::Transform& end_transform) {
- // The window's layer was just hidden, but we need it to draw until it's fully
- // transparent, so we show it again. This is undone once the animation is
- // complete.
- window->layer()->SetVisible(true);
- {
- // Property sets within this scope will be implicitly animated.
- ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
- settings.AddImplicitObserver(new HidingWindowAnimationObserver(window));
+ window->layer()->set_delegate(NULL);
- window->layer()->SetOpacity(kWindowAnimation_HideOpacity);
- window->layer()->SetTransform(end_transform);
- }
+ // Property sets within this scope will be implicitly animated.
+ ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
+ settings.AddImplicitObserver(new HidingWindowAnimationObserver(window));
+
+ window->layer()->SetOpacity(kWindowAnimation_HideOpacity);
+ window->layer()->SetTransform(end_transform);
}
// Show/Hide windows using a shrink animation.