window_position_in_root_monitor.cc 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ui/aura_extra/window_position_in_root_monitor.h"
  5. #include "ui/aura/window.h"
  6. namespace aura_extra {
  7. WindowPositionInRootMonitor::WindowPositionInRootMonitor(
  8. aura::Window* window,
  9. base::RepeatingClosure callback)
  10. : callback_(std::move(callback)) {
  11. DCHECK(window);
  12. AddAncestors(window);
  13. }
  14. WindowPositionInRootMonitor::~WindowPositionInRootMonitor() {
  15. for (aura::Window* ancestor : ancestors_)
  16. ancestor->RemoveObserver(this);
  17. }
  18. void WindowPositionInRootMonitor::AddAncestors(aura::Window* window) {
  19. while (window) {
  20. ancestors_.push_back(window);
  21. window->AddObserver(this);
  22. window = window->parent();
  23. }
  24. }
  25. void WindowPositionInRootMonitor::OnWindowDestroyed(aura::Window* window) {
  26. // This should only be hit when window has no ancestors (because destroying
  27. // a window implicitly removes children).
  28. DCHECK_EQ(1u, ancestors_.size());
  29. DCHECK_EQ(window, ancestors_[0]);
  30. window->RemoveObserver(this);
  31. ancestors_.clear();
  32. }
  33. void WindowPositionInRootMonitor::OnWindowParentChanged(aura::Window* window,
  34. aura::Window* parent) {
  35. // |window|'s parent is now |parent|. Iterate through the list backwards,
  36. // removing windows until |window| is found. Then add all the new ancestors
  37. // of |window|.
  38. while (!ancestors_.empty()) {
  39. if (ancestors_.back() == window) {
  40. AddAncestors(parent);
  41. // When adding to a root, notify the callback.
  42. if (window->GetRootWindow())
  43. callback_.Run();
  44. return;
  45. }
  46. ancestors_.back()->RemoveObserver(this);
  47. ancestors_.pop_back();
  48. }
  49. NOTREACHED();
  50. }
  51. void WindowPositionInRootMonitor::OnWindowBoundsChanged(
  52. aura::Window* window,
  53. const gfx::Rect& old_bounds,
  54. const gfx::Rect& new_bounds,
  55. ui::PropertyChangeReason reason) {
  56. if (old_bounds.origin() != new_bounds.origin() &&
  57. ancestors_.back()->GetRootWindow()) {
  58. callback_.Run();
  59. }
  60. }
  61. } // namespace aura_extra