| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 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 | |
| 5 #include "components/mus/ws/server_window_drawn_tracker.h" | |
| 6 | |
| 7 #include "components/mus/ws/server_window.h" | |
| 8 #include "components/mus/ws/server_window_drawn_tracker_observer.h" | |
| 9 | |
| 10 namespace mus { | |
| 11 | |
| 12 namespace ws { | |
| 13 | |
| 14 ServerWindowDrawnTracker::ServerWindowDrawnTracker( | |
| 15 ServerWindow* window, | |
| 16 ServerWindowDrawnTrackerObserver* observer) | |
| 17 : window_(window), observer_(observer), drawn_(window->IsDrawn()) { | |
| 18 AddObservers(); | |
| 19 } | |
| 20 | |
| 21 ServerWindowDrawnTracker::~ServerWindowDrawnTracker() { | |
| 22 RemoveObservers(); | |
| 23 } | |
| 24 | |
| 25 void ServerWindowDrawnTracker::SetDrawn(ServerWindow* ancestor, bool drawn) { | |
| 26 // If |windows_| is empty when this code runs, that means |window_| has been | |
| 27 // destroyed. So set |window_| to nullptr, but make sure the right value is | |
| 28 // sent to OnDrawnStateChanged(). | |
| 29 ServerWindow* window = window_; | |
| 30 if (windows_.empty()) | |
| 31 window_ = nullptr; | |
| 32 | |
| 33 if (drawn == drawn_) | |
| 34 return; | |
| 35 | |
| 36 drawn_ = drawn; | |
| 37 observer_->OnDrawnStateChanged(ancestor, window, drawn); | |
| 38 } | |
| 39 | |
| 40 void ServerWindowDrawnTracker::AddObservers() { | |
| 41 if (!window_) | |
| 42 return; | |
| 43 | |
| 44 for (ServerWindow* v = window_; v; v = v->parent()) { | |
| 45 v->AddObserver(this); | |
| 46 windows_.insert(v); | |
| 47 } | |
| 48 } | |
| 49 | |
| 50 void ServerWindowDrawnTracker::RemoveObservers() { | |
| 51 for (ServerWindow* window : windows_) | |
| 52 window->RemoveObserver(this); | |
| 53 | |
| 54 windows_.clear(); | |
| 55 } | |
| 56 | |
| 57 void ServerWindowDrawnTracker::OnWindowDestroying(ServerWindow* window) { | |
| 58 if (!drawn_) | |
| 59 return; | |
| 60 observer_->OnDrawnStateWillChange(window->parent(), window_, false); | |
| 61 } | |
| 62 | |
| 63 void ServerWindowDrawnTracker::OnWindowDestroyed(ServerWindow* window) { | |
| 64 // As windows are removed before being destroyed, resulting in | |
| 65 // OnWindowHierarchyChanged() and us removing ourself as an observer, the only | |
| 66 // window we should ever get notified of destruction on is |window_|. | |
| 67 DCHECK_EQ(window, window_); | |
| 68 RemoveObservers(); | |
| 69 SetDrawn(nullptr, false); | |
| 70 } | |
| 71 | |
| 72 void ServerWindowDrawnTracker::OnWillChangeWindowHierarchy( | |
| 73 ServerWindow* window, | |
| 74 ServerWindow* new_parent, | |
| 75 ServerWindow* old_parent) { | |
| 76 bool new_is_drawn = new_parent && new_parent->IsDrawn(); | |
| 77 if (new_is_drawn) { | |
| 78 for (ServerWindow* w = window_; new_is_drawn && w != old_parent; | |
| 79 w = w->parent()) { | |
| 80 new_is_drawn = w->visible(); | |
| 81 } | |
| 82 } | |
| 83 if (drawn_ != new_is_drawn) { | |
| 84 observer_->OnDrawnStateWillChange(new_is_drawn ? nullptr : old_parent, | |
| 85 window_, new_is_drawn); | |
| 86 } | |
| 87 } | |
| 88 | |
| 89 void ServerWindowDrawnTracker::OnWindowHierarchyChanged( | |
| 90 ServerWindow* window, | |
| 91 ServerWindow* new_parent, | |
| 92 ServerWindow* old_parent) { | |
| 93 RemoveObservers(); | |
| 94 AddObservers(); | |
| 95 const bool is_drawn = window_->IsDrawn(); | |
| 96 SetDrawn(is_drawn ? nullptr : old_parent, is_drawn); | |
| 97 } | |
| 98 | |
| 99 void ServerWindowDrawnTracker::OnWillChangeWindowVisibility( | |
| 100 ServerWindow* window) { | |
| 101 bool will_change = false; | |
| 102 if (drawn_) { | |
| 103 // If |window_| is currently drawn, then any change of visibility of the | |
| 104 // windows will toggle the drawn status. | |
| 105 will_change = true; | |
| 106 } else { | |
| 107 // If |window| is currently visible, then it's becoming invisible, and so | |
| 108 // |window_| will remain not drawn. | |
| 109 if (window->visible()) { | |
| 110 will_change = false; | |
| 111 } else { | |
| 112 bool is_drawn = (window->GetRoot() == window) || | |
| 113 (window->parent() && window->parent()->IsDrawn()); | |
| 114 if (is_drawn) { | |
| 115 for (ServerWindow* w = window_; is_drawn && w != window; | |
| 116 w = w->parent()) | |
| 117 is_drawn = w->visible(); | |
| 118 } | |
| 119 will_change = drawn_ != is_drawn; | |
| 120 } | |
| 121 } | |
| 122 if (will_change) { | |
| 123 bool new_is_drawn = !drawn_; | |
| 124 observer_->OnDrawnStateWillChange(new_is_drawn ? nullptr : window->parent(), | |
| 125 window_, new_is_drawn); | |
| 126 } | |
| 127 } | |
| 128 | |
| 129 void ServerWindowDrawnTracker::OnWindowVisibilityChanged(ServerWindow* window) { | |
| 130 const bool is_drawn = window_->IsDrawn(); | |
| 131 SetDrawn(is_drawn ? nullptr : window->parent(), is_drawn); | |
| 132 } | |
| 133 | |
| 134 } // namespace ws | |
| 135 | |
| 136 } // namespace mus | |
| OLD | NEW |