summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/wm/image_grid.cc4
-rw-r--r--ash/wm/image_grid.h1
-rw-r--r--ui/aura/bench/bench_main.cc4
-rw-r--r--ui/aura/window.cc57
-rw-r--r--ui/aura/window.h9
-rw-r--r--ui/aura/window_unittest.cc62
-rw-r--r--ui/compositor/compositor.gyp1
-rw-r--r--ui/compositor/layer.cc5
-rw-r--r--ui/compositor/layer_delegate.h5
-rw-r--r--ui/compositor/layer_unittest.cc18
-rw-r--r--ui/views/view.cc4
-rw-r--r--ui/views/view.h1
12 files changed, 144 insertions, 27 deletions
diff --git a/ash/wm/image_grid.cc b/ash/wm/image_grid.cc
index c4fec2a..54ccca3 100644
--- a/ash/wm/image_grid.cc
+++ b/ash/wm/image_grid.cc
@@ -235,6 +235,10 @@ void ImageGrid::ImagePainter::OnDeviceScaleFactorChanged(
// Redrawing will take care of scale factor change.
}
+base::Closure ImageGrid::ImagePainter::PrepareForLayerBoundsChange() {
+ return base::Closure();
+}
+
// static
gfx::Size ImageGrid::GetImageSize(const gfx::Image* image) {
return image ?
diff --git a/ash/wm/image_grid.h b/ash/wm/image_grid.h
index ecbadf5..93ab694 100644
--- a/ash/wm/image_grid.h
+++ b/ash/wm/image_grid.h
@@ -140,6 +140,7 @@ class ASH_EXPORT ImageGrid {
// ui::LayerDelegate implementation:
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE;
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
+ virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE;
private:
friend class TestAPI;
diff --git a/ui/aura/bench/bench_main.cc b/ui/aura/bench/bench_main.cc
index 3dfb8e8..1445f08 100644
--- a/ui/aura/bench/bench_main.cc
+++ b/ui/aura/bench/bench_main.cc
@@ -67,6 +67,10 @@ class ColoredLayer : public Layer, public LayerDelegate {
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
}
+ virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
+ return base::Closure();
+ }
+
void set_color(SkColor color) { color_ = color; }
void set_draw(bool draw) { draw_ = draw; }
diff --git a/ui/aura/window.cc b/ui/aura/window.cc
index 82c442c..ef3a8b9 100644
--- a/ui/aura/window.cc
+++ b/ui/aura/window.cc
@@ -6,6 +6,9 @@
#include <algorithm>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/string_util.h"
@@ -546,6 +549,11 @@ void* Window::GetNativeWindowProperty(const char* key) const {
return reinterpret_cast<void*>(GetPropertyInternal(key, 0));
}
+void Window::OnDeviceScaleFactorChanged(float device_scale_factor) {
+ if (delegate_)
+ delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
+}
+
///////////////////////////////////////////////////////////////////////////////
// Window, private:
@@ -588,33 +596,10 @@ void Window::SetBoundsInternal(const gfx::Rect& new_bounds) {
actual_new_bounds.set_height(
std::max(min_size.height(), actual_new_bounds.height()));
}
- RootWindow* root_window = GetRootWindow();
-
- bool contained_mouse =
- IsVisible() &&
- root_window && ContainsPointInRoot(root_window->last_mouse_location());
-
- const gfx::Rect old_bounds = GetTargetBounds();
// Always need to set the layer's bounds -- even if it is to the same thing.
// This may cause important side effects such as stopping animation.
layer_->SetBounds(actual_new_bounds);
-
- // If we're not changing the effective bounds, then we can bail early and skip
- // notifying our listeners.
- if (old_bounds == actual_new_bounds)
- return;
-
- if (layout_manager_.get())
- layout_manager_->OnWindowResized();
- if (delegate_)
- delegate_->OnBoundsChanged(old_bounds, actual_new_bounds);
- FOR_EACH_OBSERVER(WindowObserver,
- observers_,
- OnWindowBoundsChanged(this, old_bounds, actual_new_bounds));
-
- if (root_window)
- root_window->OnWindowBoundsChanged(this, contained_mouse);
}
void Window::SetVisible(bool visible) {
@@ -808,14 +793,34 @@ void Window::NotifyAddedToRootWindow() {
}
}
+void Window::OnLayerBoundsChanged(const gfx::Rect& old_bounds,
+ bool contained_mouse) {
+ if (layout_manager_.get())
+ layout_manager_->OnWindowResized();
+ if (delegate_)
+ delegate_->OnBoundsChanged(old_bounds, bounds());
+ FOR_EACH_OBSERVER(WindowObserver,
+ observers_,
+ OnWindowBoundsChanged(this, old_bounds, bounds()));
+ RootWindow* root_window = GetRootWindow();
+ if (root_window)
+ root_window->OnWindowBoundsChanged(this, contained_mouse);
+}
+
void Window::OnPaintLayer(gfx::Canvas* canvas) {
if (delegate_)
delegate_->OnPaint(canvas);
}
-void Window::OnDeviceScaleFactorChanged(float device_scale_factor) {
- if (delegate_)
- delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
+base::Closure Window::PrepareForLayerBoundsChange() {
+ bool contains_mouse = false;
+ if (IsVisible()) {
+ RootWindow* root_window = GetRootWindow();
+ contains_mouse =
+ root_window && ContainsPointInRoot(root_window->last_mouse_location());
+ }
+ return base::Bind(&Window::OnLayerBoundsChanged, base::Unretained(this),
+ bounds(), contains_mouse);
}
void Window::UpdateLayerName(const std::string& name) {
diff --git a/ui/aura/window.h b/ui/aura/window.h
index 06f8812..4b812cb 100644
--- a/ui/aura/window.h
+++ b/ui/aura/window.h
@@ -388,11 +388,18 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
// Notifies observers registered with this Window (and its subtree) when the
// Window has been added or is about to be removed from a RootWindow.
- void NotifyAddedToRootWindow();
void NotifyRemovingFromRootWindow();
+ void NotifyAddedToRootWindow();
+
+ // Invoked from the closure returned by PrepareForLayerBoundsChange() after
+ // the bounds of the layer has changed. |old_bounds| is the previous bounds of
+ // the layer, and |contained_mouse| is true if the mouse was previously within
+ // the window's bounds.
+ void OnLayerBoundsChanged(const gfx::Rect& old_bounds, bool contained_mouse);
// Overridden from ui::LayerDelegate:
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE;
+ virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE;
// Updates the layer name with a name based on the window's name and id.
void UpdateLayerName(const std::string& name);
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc
index ed9e34c..cc257fa 100644
--- a/ui/aura/window_unittest.cc
+++ b/ui/aura/window_unittest.cc
@@ -2038,5 +2038,67 @@ TEST_F(WindowTest, DeleteWindowFromOnWindowDestroyed) {
parent.reset();
}
+namespace {
+
+// Used by DelegateNotifiedAsBoundsChange to verify OnBoundsChanged() is
+// invoked.
+class BoundsChangeDelegate : public TestWindowDelegate {
+ public:
+ BoundsChangeDelegate() : bounds_changed_(false) {}
+
+ void clear_bounds_changed() { bounds_changed_ = false; }
+ bool bounds_changed() const {
+ return bounds_changed_;
+ }
+
+ // Window
+ virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) OVERRIDE {
+ bounds_changed_ = true;
+ }
+
+ private:
+ // Was OnBoundsChanged() invoked?
+ bool bounds_changed_;
+
+ DISALLOW_COPY_AND_ASSIGN(BoundsChangeDelegate);
+};
+
+} // namespace
+
+// Verifies the delegate is notified when the actual bounds of the layer
+// change.
+TEST_F(WindowTest, DelegateNotifiedAsBoundsChange) {
+ BoundsChangeDelegate delegate;
+
+ // We cannot short-circuit animations in this test.
+ ui::LayerAnimator::set_disable_animations_for_test(false);
+
+ scoped_ptr<Window> window(
+ CreateTestWindowWithDelegate(&delegate, 1,
+ gfx::Rect(0, 0, 100, 100), NULL));
+ window->layer()->GetAnimator()->set_disable_timer_for_test(true);
+
+ delegate.clear_bounds_changed();
+
+ // Animate to a different position.
+ {
+ ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
+ window->SetBounds(gfx::Rect(100, 100, 100, 100));
+ }
+
+ // Bounds shouldn't immediately have changed.
+ EXPECT_EQ("0,0 100x100", window->bounds().ToString());
+ EXPECT_FALSE(delegate.bounds_changed());
+
+ // Animate to the end, which should notify of the change.
+ base::TimeTicks start_time =
+ window->layer()->GetAnimator()->last_step_time();
+ ui::AnimationContainerElement* element = window->layer()->GetAnimator();
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_TRUE(delegate.bounds_changed());
+ EXPECT_NE("0,0 100x100", window->bounds().ToString());
+}
+
} // namespace test
} // namespace aura
diff --git a/ui/compositor/compositor.gyp b/ui/compositor/compositor.gyp
index 4bec896..269d5bd 100644
--- a/ui/compositor/compositor.gyp
+++ b/ui/compositor/compositor.gyp
@@ -47,6 +47,7 @@
'layer_animation_sequence.h',
'layer_animator.cc',
'layer_animator.h',
+ 'layer_delegate.h',
'layer_owner.cc',
'layer_owner.h',
'layer_type.h',
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc
index 0085b8d..b965e1c 100644
--- a/ui/compositor/layer.cc
+++ b/ui/compositor/layer.cc
@@ -514,11 +514,16 @@ void Layer::SetBoundsImmediately(const gfx::Rect& bounds) {
if (bounds == bounds_)
return;
+ base::Closure closure;
+ if (delegate_)
+ closure = delegate_->PrepareForLayerBoundsChange();
bool was_move = bounds_.size() == bounds.size();
bounds_ = bounds;
RecomputeTransform();
RecomputeDrawsContentAndUVRect();
+ if (!closure.is_null())
+ closure.Run();
if (was_move) {
// Don't schedule a draw if we're invisible. We'll schedule one
diff --git a/ui/compositor/layer_delegate.h b/ui/compositor/layer_delegate.h
index cb00366..40c90db 100644
--- a/ui/compositor/layer_delegate.h
+++ b/ui/compositor/layer_delegate.h
@@ -6,6 +6,7 @@
#define UI_COMPOSITOR_LAYER_DELEGATE_H_
#pragma once
+#include "base/callback_forward.h"
#include "ui/compositor/compositor_export.h"
namespace gfx {
@@ -24,6 +25,10 @@ class COMPOSITOR_EXPORT LayerDelegate {
// Called when the layer's device scale factor has changed.
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) = 0;
+ // Invoked prior to the bounds changing. The returned closured is run after
+ // the bounds change.
+ virtual base::Closure PrepareForLayerBoundsChange() = 0;
+
protected:
virtual ~LayerDelegate() {}
};
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc
index df467ab..745534b 100644
--- a/ui/compositor/layer_unittest.cc
+++ b/ui/compositor/layer_unittest.cc
@@ -134,6 +134,10 @@ class ColoredLayer : public Layer, public LayerDelegate {
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
}
+ virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
+ return base::Closure();
+ }
+
private:
SkColor color_;
};
@@ -247,6 +251,10 @@ class TestLayerDelegate : public LayerDelegate {
device_scale_factor_ = device_scale_factor;
}
+ virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
+ return base::Closure();
+ }
+
void reset() {
color_index_ = 0;
paint_size_.SetSize(0, 0);
@@ -284,6 +292,9 @@ class DrawTreeLayerDelegate : public LayerDelegate {
}
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
}
+ virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
+ return base::Closure();
+ }
bool painted_;
@@ -302,6 +313,9 @@ class NullLayerDelegate : public LayerDelegate {
}
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
}
+ virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
+ return base::Closure();
+ }
DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate);
};
@@ -1035,6 +1049,10 @@ class SchedulePaintLayerDelegate : public LayerDelegate {
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
}
+ virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
+ return base::Closure();
+ }
+
int paint_count_;
Layer* layer_;
gfx::Rect schedule_paint_rect_;
diff --git a/ui/views/view.cc b/ui/views/view.cc
index 631deec..7da3a3b 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -1234,6 +1234,10 @@ void View::OnDeviceScaleFactorChanged(float device_scale_factor) {
// Repainting with new scale factor will paint the content at the right scale.
}
+base::Closure View::PrepareForLayerBoundsChange() {
+ return base::Closure();
+}
+
void View::ReorderLayers() {
View* v = this;
while (v && !v->layer())
diff --git a/ui/views/view.h b/ui/views/view.h
index 0fd781b..2a097a6 100644
--- a/ui/views/view.h
+++ b/ui/views/view.h
@@ -1003,6 +1003,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// Overridden from ui::LayerDelegate:
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE;
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
+ virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE;
// Finds the layer that this view paints to (it may belong to an ancestor
// view), then reorders the immediate children of that layer to match the