diff options
-rw-r--r-- | ash/wm/image_grid.cc | 4 | ||||
-rw-r--r-- | ash/wm/image_grid.h | 1 | ||||
-rw-r--r-- | ui/aura/bench/bench_main.cc | 4 | ||||
-rw-r--r-- | ui/aura/window.cc | 57 | ||||
-rw-r--r-- | ui/aura/window.h | 9 | ||||
-rw-r--r-- | ui/aura/window_unittest.cc | 62 | ||||
-rw-r--r-- | ui/compositor/compositor.gyp | 1 | ||||
-rw-r--r-- | ui/compositor/layer.cc | 5 | ||||
-rw-r--r-- | ui/compositor/layer_delegate.h | 5 | ||||
-rw-r--r-- | ui/compositor/layer_unittest.cc | 18 | ||||
-rw-r--r-- | ui/views/view.cc | 4 | ||||
-rw-r--r-- | ui/views/view.h | 1 |
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 |