| // Copyright 2018 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 "ui/aura_extra/window_position_in_root_monitor.h" |
| |
| #include "ui/aura/window.h" |
| |
| namespace aura_extra { |
| |
| WindowPositionInRootMonitor::WindowPositionInRootMonitor( |
| aura::Window* window, |
| base::RepeatingClosure callback) |
| : callback_(std::move(callback)) { |
| DCHECK(window); |
| AddAncestors(window); |
| } |
| |
| WindowPositionInRootMonitor::~WindowPositionInRootMonitor() { |
| for (aura::Window* ancestor : ancestors_) |
| ancestor->RemoveObserver(this); |
| } |
| |
| void WindowPositionInRootMonitor::AddAncestors(aura::Window* window) { |
| while (window) { |
| ancestors_.push_back(window); |
| window->AddObserver(this); |
| window = window->parent(); |
| } |
| } |
| |
| void WindowPositionInRootMonitor::OnWindowDestroyed(aura::Window* window) { |
| // This should only be hit when window has no ancestors (because destroying |
| // a window implicitly removes children). |
| DCHECK_EQ(1u, ancestors_.size()); |
| DCHECK_EQ(window, ancestors_[0]); |
| window->RemoveObserver(this); |
| ancestors_.clear(); |
| } |
| |
| void WindowPositionInRootMonitor::OnWindowParentChanged(aura::Window* window, |
| aura::Window* parent) { |
| // |window|'s parent is now |parent|. Iterate through the list backwards, |
| // removing windows until |window| is found. Then add all the new ancestors |
| // of |window|. |
| while (!ancestors_.empty()) { |
| if (ancestors_.back() == window) { |
| AddAncestors(parent); |
| // When adding to a root, notify the callback. |
| if (window->GetRootWindow()) |
| callback_.Run(); |
| return; |
| } |
| ancestors_.back()->RemoveObserver(this); |
| ancestors_.pop_back(); |
| } |
| NOTREACHED(); |
| } |
| |
| void WindowPositionInRootMonitor::OnWindowBoundsChanged( |
| aura::Window* window, |
| const gfx::Rect& old_bounds, |
| const gfx::Rect& new_bounds, |
| ui::PropertyChangeReason reason) { |
| if (old_bounds.origin() != new_bounds.origin() && |
| ancestors_.back()->GetRootWindow()) { |
| callback_.Run(); |
| } |
| } |
| |
| } // namespace aura_extra |