diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-01 04:06:35 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-01 04:06:35 +0000 |
commit | 16690b0f338b90fa6365c60286af23678c29e9d6 (patch) | |
tree | 7da85cea2d095df6a83e71375b3083450adbd0cb | |
parent | cb288b63c936591fa6d78c8d5b54506775b8460e (diff) | |
download | chromium_src-16690b0f338b90fa6365c60286af23678c29e9d6.zip chromium_src-16690b0f338b90fa6365c60286af23678c29e9d6.tar.gz chromium_src-16690b0f338b90fa6365c60286af23678c29e9d6.tar.bz2 |
Adds two new observer methods to allow code to be notified when a Window is added/removed from a RootWindow. This allows hierarchy-specific cleanup code to execute when a Window is removed rather than when it is destroyed, necessary for multiple root windows.
http://crbug.com/112131
TEST=see unittests
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=119976
Review URL: http://codereview.chromium.org/9315015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@120025 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ui/aura/root_window.cc | 52 | ||||
-rw-r--r-- | ui/aura/root_window.h | 12 | ||||
-rw-r--r-- | ui/aura/window.cc | 36 | ||||
-rw-r--r-- | ui/aura/window.h | 15 | ||||
-rw-r--r-- | ui/aura/window_observer.h | 6 | ||||
-rw-r--r-- | ui/aura/window_unittest.cc | 93 |
6 files changed, 165 insertions, 49 deletions
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc index 3363b98..1090209 100644 --- a/ui/aura/root_window.cc +++ b/ui/aura/root_window.cc @@ -413,6 +413,9 @@ void RootWindow::ToggleFullScreen() { } #endif +//////////////////////////////////////////////////////////////////////////////// +// RootWindow, Window overrides: + RootWindow* RootWindow::GetRootWindow() { return this; } @@ -427,6 +430,17 @@ void RootWindow::SetTransform(const ui::Transform& transform) { } //////////////////////////////////////////////////////////////////////////////// +// RootWindow, ui::CompositorDelegate implementation: + +void RootWindow::ScheduleDraw() { + if (!schedule_paint_factory_.HasWeakPtrs()) { + MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&RootWindow::Draw, schedule_paint_factory_.GetWeakPtr())); + } +} + +//////////////////////////////////////////////////////////////////////////////// // RootWindow, private: RootWindow::RootWindow() @@ -615,27 +629,7 @@ bool RootWindow::ProcessGestures(GestureRecognizer::Gestures* gestures) { return handled; } -void RootWindow::ScheduleDraw() { - if (!schedule_paint_factory_.HasWeakPtrs()) { - MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&RootWindow::Draw, schedule_paint_factory_.GetWeakPtr())); - } -} - -bool RootWindow::CanFocus() const { - return IsVisible(); -} - -bool RootWindow::CanReceiveEvents() const { - return IsVisible(); -} - -internal::FocusManager* RootWindow::GetFocusManager() { - return this; -} - -void RootWindow::OnWindowDetachingFromRootWindow(Window* detached) { +void RootWindow::OnWindowRemovedFromRootWindow(Window* detached) { DCHECK(capture_window_ != this); // If the ancestor of the capture window is detached, @@ -663,12 +657,24 @@ void RootWindow::OnWindowDetachingFromRootWindow(Window* detached) { } } -void RootWindow::OnWindowAttachedToRootWindow(Window* attached) { +void RootWindow::OnWindowAddedToRootWindow(Window* attached) { if (attached->IsVisible() && attached->ContainsPointInRoot(last_mouse_location_)) PostMouseMoveEventAfterWindowChange(); } +bool RootWindow::CanFocus() const { + return IsVisible(); +} + +bool RootWindow::CanReceiveEvents() const { + return IsVisible(); +} + +internal::FocusManager* RootWindow::GetFocusManager() { + return this; +} + void RootWindow::OnLayerAnimationEnded( const ui::LayerAnimationSequence* animation) { OnHostResized(host_->GetSize()); @@ -765,7 +771,7 @@ void RootWindow::SynthesizeMouseMoveEvent() { orig_mouse_location, orig_mouse_location, 0); - DispatchMouseEvent(&event); + //DispatchMouseEvent(&event); } } // namespace aura diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h index 823d87b..ec0f09f 100644 --- a/ui/aura/root_window.h +++ b/ui/aura/root_window.h @@ -192,13 +192,9 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate, // Overridden from ui::CompositorDelegate: virtual void ScheduleDraw() OVERRIDE; - // Overridden from Window: - virtual void OnWindowAttachedToRootWindow( - Window* window) OVERRIDE; - virtual void OnWindowDetachingFromRootWindow( - Window* window) OVERRIDE; - private: + friend class Window; + RootWindow(); virtual ~RootWindow(); @@ -212,6 +208,10 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate, ui::GestureStatus ProcessGestureEvent(Window* target, GestureEvent* event); bool ProcessGestures(GestureRecognizer::Gestures* gestures); + // Called when a Window is attached or detached from the RootWindow. + void OnWindowAddedToRootWindow(Window* window); + void OnWindowRemovedFromRootWindow(Window* window); + // Overridden from Window: virtual bool CanFocus() const OVERRIDE; virtual bool CanReceiveEvents() const OVERRIDE; diff --git a/ui/aura/window.cc b/ui/aura/window.cc index 30ecc1f..a5869ba 100644 --- a/ui/aura/window.cc +++ b/ui/aura/window.cc @@ -294,8 +294,10 @@ void Window::AddChild(Window* child) { child->OnParentChanged(); RootWindow* root_window = child->GetRootWindow(); - if (root_window) - root_window->OnWindowAttachedToRootWindow(child); + if (root_window) { + root_window->OnWindowAddedToRootWindow(child); + NotifyAddedToRootWindow(); + } } void Window::AddTransientChild(Window* child) { @@ -323,8 +325,10 @@ void Window::RemoveChild(Window* child) { layout_manager_->OnWillRemoveWindowFromLayout(child); FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child)); RootWindow* root_window = child->GetRootWindow(); - if (root_window) - root_window->OnWindowDetachingFromRootWindow(child); + if (root_window) { + root_window->OnWindowRemovedFromRootWindow(child); + child->NotifyRemovingFromRootWindow(); + } child->parent_ = NULL; // We should only remove the child's layer if the child still owns that layer. // Someone else may have acquired ownership of it via AcquireLayer() and may @@ -519,12 +523,6 @@ bool Window::StopsEventPropagation() const { return it != children_.end(); } -void Window::OnWindowDetachingFromRootWindow(aura::Window* window) { -} - -void Window::OnWindowAttachedToRootWindow(aura::Window* window) { -} - void Window::SetBoundsInternal(const gfx::Rect& new_bounds) { gfx::Rect actual_new_bounds(new_bounds); @@ -643,6 +641,24 @@ void Window::OnStackingChanged() { FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowStackingChanged(this)); } +void Window::NotifyRemovingFromRootWindow() { + FOR_EACH_OBSERVER(WindowObserver, observers_, + OnWindowRemovingFromRootWindow(this)); + for (Window::Windows::const_iterator it = children_.begin(); + it != children_.end(); ++it) { + (*it)->NotifyRemovingFromRootWindow(); + } +} + +void Window::NotifyAddedToRootWindow() { + FOR_EACH_OBSERVER(WindowObserver, observers_, + OnWindowAddedToRootWindow(this)); + for (Window::Windows::const_iterator it = children_.begin(); + it != children_.end(); ++it) { + (*it)->NotifyAddedToRootWindow(); + } +} + void Window::OnPaintLayer(gfx::Canvas* canvas) { if (delegate_) delegate_->OnPaint(canvas); diff --git a/ui/aura/window.h b/ui/aura/window.h index 6ff7051..c1b49f1 100644 --- a/ui/aura/window.h +++ b/ui/aura/window.h @@ -293,16 +293,6 @@ class AURA_EXPORT Window : public ui::LayerDelegate { // propagation for any windows behind it in the z-order. bool StopsEventPropagation() const; - protected: - // Called when the |window| is being detached from the root window - // by being removed from its parent. It is called before |parent_| is - // set to NULL. - virtual void OnWindowDetachingFromRootWindow(aura::Window* window); - - // Called when the |window| is attached to the root window by being added - // to its parent. - virtual void OnWindowAttachedToRootWindow(aura::Window* window); - private: friend class LayoutManager; @@ -332,6 +322,11 @@ class AURA_EXPORT Window : public ui::LayerDelegate { // Called when this window's stacking order among its siblings is changed. void OnStackingChanged(); + // 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(); + // Overridden from ui::LayerDelegate: virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE; diff --git a/ui/aura/window_observer.h b/ui/aura/window_observer.h index a4f51ac..59360bf 100644 --- a/ui/aura/window_observer.h +++ b/ui/aura/window_observer.h @@ -58,6 +58,12 @@ class AURA_EXPORT WindowObserver { // destructor). This is called after the window is removed from its parent. virtual void OnWindowDestroyed(Window* window) {} + // Called when a Window has been added to a RootWindow. + virtual void OnWindowAddedToRootWindow(Window* window) {} + + // Called when a Window is about to be removed from a RootWindow. + virtual void OnWindowRemovingFromRootWindow(Window* window) {} + protected: virtual ~WindowObserver() {} }; diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc index 6c53e6b..b8d6121 100644 --- a/ui/aura/window_unittest.cc +++ b/ui/aura/window_unittest.cc @@ -1462,5 +1462,98 @@ TEST_F(WindowTest, StackingMadrigal) { EXPECT_TRUE(LayerIsAbove(window12.get(), window1.get())); } +class RootWindowAttachmentObserver : public WindowObserver { + public: + RootWindowAttachmentObserver() : added_count_(0), removed_count_(0) {} + virtual ~RootWindowAttachmentObserver() {} + + int added_count() const { return added_count_; } + int removed_count() const { return removed_count_; } + + void Clear() { + added_count_ = 0; + removed_count_ = 0; + } + + // Overridden from WindowObserver: + virtual void OnWindowAddedToRootWindow(Window* window) OVERRIDE { + ++added_count_; + } + virtual void OnWindowRemovingFromRootWindow(Window* window) OVERRIDE { + ++removed_count_; + } + + private: + int added_count_; + int removed_count_; + + DISALLOW_COPY_AND_ASSIGN(RootWindowAttachmentObserver); +}; + +TEST_F(WindowTest, RootWindowAttachment) { + RootWindowAttachmentObserver observer; + + // Test a direct add/remove from the RootWindow. + scoped_ptr<Window> w1(new Window(NULL)); + w1->Init(ui::Layer::LAYER_NOT_DRAWN); + w1->AddObserver(&observer); + + w1->SetParent(NULL); + EXPECT_EQ(1, observer.added_count()); + EXPECT_EQ(0, observer.removed_count()); + + w1.reset(); + EXPECT_EQ(1, observer.added_count()); + EXPECT_EQ(1, observer.removed_count()); + + observer.Clear(); + + // Test an indirect add/remove from the RootWindow. + w1.reset(new Window(NULL)); + w1->Init(ui::Layer::LAYER_NOT_DRAWN); + Window* w11 = new Window(NULL); + w11->Init(ui::Layer::LAYER_NOT_DRAWN); + w11->AddObserver(&observer); + w11->SetParent(w1.get()); + EXPECT_EQ(0, observer.added_count()); + EXPECT_EQ(0, observer.removed_count()); + + w1->SetParent(NULL); + EXPECT_EQ(1, observer.added_count()); + EXPECT_EQ(0, observer.removed_count()); + + w1.reset(); // Deletes w11. + w11 = NULL; + EXPECT_EQ(1, observer.added_count()); + EXPECT_EQ(1, observer.removed_count()); + + observer.Clear(); + + // Test an indirect add/remove with nested observers. + w1.reset(new Window(NULL)); + w1->Init(ui::Layer::LAYER_NOT_DRAWN); + w11 = new Window(NULL); + w11->Init(ui::Layer::LAYER_NOT_DRAWN); + w11->AddObserver(&observer); + w11->SetParent(w1.get()); + Window* w111 = new Window(NULL); + w111->Init(ui::Layer::LAYER_NOT_DRAWN); + w111->AddObserver(&observer); + w111->SetParent(w11); + + EXPECT_EQ(0, observer.added_count()); + EXPECT_EQ(0, observer.removed_count()); + + w1->SetParent(NULL); + EXPECT_EQ(2, observer.added_count()); + EXPECT_EQ(0, observer.removed_count()); + + w1.reset(); // Deletes w11 and w111. + w11 = NULL; + w111 = NULL; + EXPECT_EQ(2, observer.added_count()); + EXPECT_EQ(2, observer.removed_count()); +} + } // namespace test } // namespace aura |