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 |