Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(254)

Side by Side Diff: ui/aura/window.cc

Issue 115453004: Moves management of transients out of Window (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix MRUWindowTracker and MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerTest Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/aura/window.h" 5 #include "ui/aura/window.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/stl_util.h"
14 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
16 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
17 #include "ui/aura/client/capture_client.h" 16 #include "ui/aura/client/capture_client.h"
18 #include "ui/aura/client/cursor_client.h" 17 #include "ui/aura/client/cursor_client.h"
19 #include "ui/aura/client/event_client.h" 18 #include "ui/aura/client/event_client.h"
20 #include "ui/aura/client/focus_client.h" 19 #include "ui/aura/client/focus_client.h"
21 #include "ui/aura/client/screen_position_client.h" 20 #include "ui/aura/client/screen_position_client.h"
22 #include "ui/aura/client/visibility_client.h" 21 #include "ui/aura/client/visibility_client.h"
23 #include "ui/aura/client/window_stacking_client.h" 22 #include "ui/aura/client/window_stacking_client.h"
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 210
212 DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider); 211 DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider);
213 }; 212 };
214 213
215 Window::Window(WindowDelegate* delegate) 214 Window::Window(WindowDelegate* delegate)
216 : dispatcher_(NULL), 215 : dispatcher_(NULL),
217 type_(client::WINDOW_TYPE_UNKNOWN), 216 type_(client::WINDOW_TYPE_UNKNOWN),
218 owned_by_parent_(true), 217 owned_by_parent_(true),
219 delegate_(delegate), 218 delegate_(delegate),
220 parent_(NULL), 219 parent_(NULL),
221 transient_parent_(NULL),
222 visible_(false), 220 visible_(false),
223 id_(-1), 221 id_(-1),
224 transparent_(false), 222 transparent_(false),
225 user_data_(NULL), 223 user_data_(NULL),
226 ignore_events_(false), 224 ignore_events_(false),
227 // Don't notify newly added observers during notification. This causes 225 // Don't notify newly added observers during notification. This causes
228 // problems for code that adds an observer as part of an observer 226 // problems for code that adds an observer as part of an observer
229 // notification (such as the workspace code). 227 // notification (such as the workspace code).
230 observers_(ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY) { 228 observers_(ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY) {
231 set_target_handler(delegate_); 229 set_target_handler(delegate_);
(...skipping 10 matching lines...) Expand all
242 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this)); 240 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this));
243 241
244 // Let the root know so that it can remove any references to us. 242 // Let the root know so that it can remove any references to us.
245 WindowEventDispatcher* dispatcher = GetDispatcher(); 243 WindowEventDispatcher* dispatcher = GetDispatcher();
246 if (dispatcher) 244 if (dispatcher)
247 dispatcher->OnWindowDestroying(this); 245 dispatcher->OnWindowDestroying(this);
248 246
249 // Then destroy the children. 247 // Then destroy the children.
250 RemoveOrDestroyChildren(); 248 RemoveOrDestroyChildren();
251 249
252 // Removes ourselves from our transient parent (if it hasn't been done by the
253 // RootWindow).
254 if (transient_parent_)
255 transient_parent_->RemoveTransientChild(this);
256
257 // The window needs to be removed from the parent before calling the 250 // The window needs to be removed from the parent before calling the
258 // WindowDestroyed callbacks of delegate and the observers. 251 // WindowDestroyed callbacks of delegate and the observers.
259 if (parent_) 252 if (parent_)
260 parent_->RemoveChild(this); 253 parent_->RemoveChild(this);
261 254
262 // Destroy transient children, only after we've removed ourselves from our
263 // parent, as destroying an active transient child may otherwise attempt to
264 // refocus us.
265 Windows transient_children(transient_children_);
266 STLDeleteElements(&transient_children);
267 DCHECK(transient_children_.empty());
268
269 // Delegate and observers need to be notified after transients are deleted.
270 if (delegate_) 255 if (delegate_)
271 delegate_->OnWindowDestroyed(); 256 delegate_->OnWindowDestroyed();
272 ObserverListBase<WindowObserver>::Iterator iter(observers_); 257 ObserverListBase<WindowObserver>::Iterator iter(observers_);
273 WindowObserver* observer; 258 WindowObserver* observer;
274 while ((observer = iter.GetNext())) { 259 while ((observer = iter.GetNext())) {
275 RemoveObserver(observer); 260 RemoveObserver(observer);
276 observer->OnWindowDestroyed(this); 261 observer->OnWindowDestroyed(this);
277 } 262 }
278 263
279 // Clear properties. 264 // Clear properties.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 const WindowEventDispatcher* Window::GetDispatcher() const { 369 const WindowEventDispatcher* Window::GetDispatcher() const {
385 const Window* root_window = GetRootWindow(); 370 const Window* root_window = GetRootWindow();
386 return root_window ? root_window->dispatcher_ : NULL; 371 return root_window ? root_window->dispatcher_ : NULL;
387 } 372 }
388 373
389 void Window::Show() { 374 void Window::Show() {
390 SetVisible(true); 375 SetVisible(true);
391 } 376 }
392 377
393 void Window::Hide() { 378 void Window::Hide() {
394 for (Windows::iterator it = transient_children_.begin();
395 it != transient_children_.end(); ++it) {
396 (*it)->Hide();
397 }
398 SetVisible(false); 379 SetVisible(false);
399 ReleaseCapture(); 380 ReleaseCapture();
400 } 381 }
401 382
402 bool Window::IsVisible() const { 383 bool Window::IsVisible() const {
403 // Layer visibility can be inconsistent with window visibility, for example 384 // Layer visibility can be inconsistent with window visibility, for example
404 // when a Window is hidden, we want this function to return false immediately 385 // when a Window is hidden, we want this function to return false immediately
405 // after, even though the client may decide to animate the hide effect (and 386 // after, even though the client may decide to animate the hide effect (and
406 // so the layer will be visible for some time after Hide() is called). 387 // so the layer will be visible for some time after Hide() is called).
407 for (const Window* window = this; window; window = window->parent()) { 388 for (const Window* window = this; window; window = window->parent()) {
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 } 579 }
599 580
600 bool Window::Contains(const Window* other) const { 581 bool Window::Contains(const Window* other) const {
601 for (const Window* parent = other; parent; parent = parent->parent_) { 582 for (const Window* parent = other; parent; parent = parent->parent_) {
602 if (parent == this) 583 if (parent == this)
603 return true; 584 return true;
604 } 585 }
605 return false; 586 return false;
606 } 587 }
607 588
608 void Window::AddTransientChild(Window* child) {
609 if (child->transient_parent_)
610 child->transient_parent_->RemoveTransientChild(child);
611 DCHECK(std::find(transient_children_.begin(), transient_children_.end(),
612 child) == transient_children_.end());
613 transient_children_.push_back(child);
614 child->transient_parent_ = this;
615 FOR_EACH_OBSERVER(WindowObserver, observers_,
616 OnAddTransientChild(this, child));
617 }
618
619 void Window::RemoveTransientChild(Window* child) {
620 Windows::iterator i =
621 std::find(transient_children_.begin(), transient_children_.end(), child);
622 DCHECK(i != transient_children_.end());
623 transient_children_.erase(i);
624 if (child->transient_parent_ == this)
625 child->transient_parent_ = NULL;
626 FOR_EACH_OBSERVER(WindowObserver, observers_,
627 OnRemoveTransientChild(this, child));
628 }
629
630 Window* Window::GetChildById(int id) { 589 Window* Window::GetChildById(int id) {
631 return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id)); 590 return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id));
632 } 591 }
633 592
634 const Window* Window::GetChildById(int id) const { 593 const Window* Window::GetChildById(int id) const {
635 Windows::const_iterator i; 594 Windows::const_iterator i;
636 for (i = children_.begin(); i != children_.end(); ++i) { 595 for (i = children_.begin(); i != children_.end(); ++i) {
637 if ((*i)->id() == id) 596 if ((*i)->id() == id)
638 return *i; 597 return *i;
639 const Window* result = (*i)->GetChildById(id); 598 const Window* result = (*i)->GetChildById(id);
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 layer_bounds += offset; 1112 layer_bounds += offset;
1154 layer_->SetBounds(layer_bounds); 1113 layer_->SetBounds(layer_bounds);
1155 } 1114 }
1156 } 1115 }
1157 1116
1158 void Window::OnParentChanged() { 1117 void Window::OnParentChanged() {
1159 FOR_EACH_OBSERVER( 1118 FOR_EACH_OBSERVER(
1160 WindowObserver, observers_, OnWindowParentChanged(this, parent_)); 1119 WindowObserver, observers_, OnWindowParentChanged(this, parent_));
1161 } 1120 }
1162 1121
1163 bool Window::HasTransientAncestor(const Window* ancestor) const {
1164 if (transient_parent_ == ancestor)
1165 return true;
1166 return transient_parent_ ?
1167 transient_parent_->HasTransientAncestor(ancestor) : false;
1168 }
1169
1170 void Window::SkipNullDelegatesForStacking(StackDirection direction,
1171 Window** target) const {
1172 DCHECK_EQ(this, (*target)->parent());
1173 size_t target_i =
1174 std::find(children_.begin(), children_.end(), *target) -
1175 children_.begin();
1176
1177 // By convention we don't stack on top of windows with layers with NULL
1178 // delegates. Walk backward to find a valid target window.
1179 // See tests WindowTest.StackingMadrigal and StackOverClosingTransient
1180 // for an explanation of this.
1181 while (target_i > 0) {
1182 const size_t index = direction == STACK_ABOVE ? target_i : target_i - 1;
1183 if (!children_[index]->layer_ ||
1184 children_[index]->layer_->delegate() != NULL)
1185 break;
1186 --target_i;
1187 }
1188 *target = children_[target_i];
1189 }
1190
1191 void Window::StackChildRelativeTo(Window* child, 1122 void Window::StackChildRelativeTo(Window* child,
1192 Window* target, 1123 Window* target,
1193 StackDirection direction) { 1124 StackDirection direction) {
1194 DCHECK_NE(child, target); 1125 DCHECK_NE(child, target);
1195 DCHECK(child); 1126 DCHECK(child);
1196 DCHECK(target); 1127 DCHECK(target);
1197 DCHECK_EQ(this, child->parent()); 1128 DCHECK_EQ(this, child->parent());
1198 DCHECK_EQ(this, target->parent()); 1129 DCHECK_EQ(this, target->parent());
1199 1130
1200 client::WindowStackingClient* stacking_client = 1131 client::WindowStackingClient* stacking_client =
1201 client::GetWindowStackingClient(); 1132 client::GetWindowStackingClient();
1202 if (stacking_client) 1133 if (stacking_client &&
1203 stacking_client->AdjustStacking(&child, &target, &direction); 1134 !stacking_client->AdjustStacking(&child, &target, &direction))
1204
1205 SkipNullDelegatesForStacking(direction, &target);
1206
1207 // If we couldn't find a valid target position, don't move anything.
1208 if (direction == STACK_ABOVE &&
1209 (target->layer_ && target->layer_->delegate() == NULL))
1210 return; 1135 return;
1211 1136
1212 // Don't try to stack a child above itself.
1213 if (child == target)
1214 return;
1215
1216 // Move the child.
1217 StackChildRelativeToImpl(child, target, direction);
1218
1219 // Stack any transient children that share the same parent to be in front of
1220 // 'child'. Preserve the existing stacking order by iterating in the order
1221 // those children appear in children_ array.
1222 Window* last_transient = child;
1223 Windows children(children_);
1224 for (Windows::iterator it = children.begin(); it != children.end(); ++it) {
1225 Window* transient_child = *it;
1226 if (transient_child != last_transient &&
1227 transient_child->HasTransientAncestor(child)) {
1228 StackChildRelativeToImpl(transient_child, last_transient, STACK_ABOVE);
1229 last_transient = transient_child;
1230 }
1231 }
1232 }
1233
1234 void Window::StackChildRelativeToImpl(Window* child,
1235 Window* target,
1236 StackDirection direction) {
1237 DCHECK_NE(child, target);
1238 DCHECK(child);
1239 DCHECK(target);
1240 DCHECK_EQ(this, child->parent());
1241 DCHECK_EQ(this, target->parent());
1242
1243 const size_t child_i = 1137 const size_t child_i =
1244 std::find(children_.begin(), children_.end(), child) - children_.begin(); 1138 std::find(children_.begin(), children_.end(), child) - children_.begin();
1245 const size_t target_i = 1139 const size_t target_i =
1246 std::find(children_.begin(), children_.end(), target) - children_.begin(); 1140 std::find(children_.begin(), children_.end(), target) - children_.begin();
1247 1141
1248 // Don't move the child if it is already in the right place. 1142 // Don't move the child if it is already in the right place.
1249 if ((direction == STACK_ABOVE && child_i == target_i + 1) || 1143 if ((direction == STACK_ABOVE && child_i == target_i + 1) ||
1250 (direction == STACK_BELOW && child_i + 1 == target_i)) 1144 (direction == STACK_BELOW && child_i + 1 == target_i))
1251 return; 1145 return;
1252 1146
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1558 return window; 1452 return window;
1559 if (offset) 1453 if (offset)
1560 *offset += window->bounds().OffsetFromOrigin(); 1454 *offset += window->bounds().OffsetFromOrigin();
1561 } 1455 }
1562 if (offset) 1456 if (offset)
1563 *offset = gfx::Vector2d(); 1457 *offset = gfx::Vector2d();
1564 return NULL; 1458 return NULL;
1565 } 1459 }
1566 1460
1567 } // namespace aura 1461 } // namespace aura
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698