• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "ui/aura/window.h"
6 
7 #include <algorithm>
8 
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/callback.h"
12 #include "base/logging.h"
13 #include "base/stl_util.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/stringprintf.h"
17 #include "ui/aura/client/capture_client.h"
18 #include "ui/aura/client/cursor_client.h"
19 #include "ui/aura/client/event_client.h"
20 #include "ui/aura/client/focus_client.h"
21 #include "ui/aura/client/screen_position_client.h"
22 #include "ui/aura/client/visibility_client.h"
23 #include "ui/aura/client/window_stacking_client.h"
24 #include "ui/aura/env.h"
25 #include "ui/aura/layout_manager.h"
26 #include "ui/aura/root_window.h"
27 #include "ui/aura/window_delegate.h"
28 #include "ui/aura/window_observer.h"
29 #include "ui/aura/window_tracker.h"
30 #include "ui/aura/window_tree_host.h"
31 #include "ui/compositor/compositor.h"
32 #include "ui/compositor/layer.h"
33 #include "ui/events/event_target_iterator.h"
34 #include "ui/gfx/animation/multi_animation.h"
35 #include "ui/gfx/canvas.h"
36 #include "ui/gfx/path.h"
37 #include "ui/gfx/scoped_canvas.h"
38 #include "ui/gfx/screen.h"
39 
40 namespace aura {
41 
42 namespace {
43 
UILayerTypeToWindowLayerType(ui::LayerType layer_type)44 WindowLayerType UILayerTypeToWindowLayerType(ui::LayerType layer_type) {
45   switch (layer_type) {
46     case ui::LAYER_NOT_DRAWN:
47       return WINDOW_LAYER_NOT_DRAWN;
48     case ui::LAYER_TEXTURED:
49       return WINDOW_LAYER_TEXTURED;
50     case ui::LAYER_SOLID_COLOR:
51       return WINDOW_LAYER_SOLID_COLOR;
52   }
53   NOTREACHED();
54   return WINDOW_LAYER_NOT_DRAWN;
55 }
56 
WindowLayerTypeToUILayerType(WindowLayerType window_layer_type)57 ui::LayerType WindowLayerTypeToUILayerType(WindowLayerType window_layer_type) {
58   switch (window_layer_type) {
59     case WINDOW_LAYER_NONE:
60       break;
61     case WINDOW_LAYER_NOT_DRAWN:
62       return ui::LAYER_NOT_DRAWN;
63     case WINDOW_LAYER_TEXTURED:
64       return ui::LAYER_TEXTURED;
65     case WINDOW_LAYER_SOLID_COLOR:
66       return ui::LAYER_SOLID_COLOR;
67   }
68   NOTREACHED();
69   return ui::LAYER_NOT_DRAWN;
70 }
71 
72 // Used when searching for a Window to stack relative to.
73 template <class T>
74 T IteratorForDirectionBegin(aura::Window* window);
75 
76 template <>
IteratorForDirectionBegin(aura::Window * window)77 Window::Windows::const_iterator IteratorForDirectionBegin(
78     aura::Window* window) {
79   return window->children().begin();
80 }
81 
82 template <>
IteratorForDirectionBegin(aura::Window * window)83 Window::Windows::const_reverse_iterator IteratorForDirectionBegin(
84     aura::Window* window) {
85   return window->children().rbegin();
86 }
87 
88 template <class T>
89 T IteratorForDirectionEnd(aura::Window* window);
90 
91 template <>
IteratorForDirectionEnd(aura::Window * window)92 Window::Windows::const_iterator IteratorForDirectionEnd(aura::Window* window) {
93   return window->children().end();
94 }
95 
96 template <>
IteratorForDirectionEnd(aura::Window * window)97 Window::Windows::const_reverse_iterator IteratorForDirectionEnd(
98     aura::Window* window) {
99   return window->children().rend();
100 }
101 
102 // Depth first search for the first Window with a layer to stack relative
103 // to. Starts at target. Does not descend into |ignore|.
104 template <class T>
FindStackingTargetLayerDown(aura::Window * target,aura::Window * ignore)105 ui::Layer* FindStackingTargetLayerDown(aura::Window* target,
106                                        aura::Window* ignore) {
107   if (target == ignore)
108     return NULL;
109 
110   if (target->layer())
111     return target->layer();
112 
113   for (T i = IteratorForDirectionBegin<T>(target);
114        i != IteratorForDirectionEnd<T>(target); ++i) {
115     ui::Layer* layer = FindStackingTargetLayerDown<T>(*i, ignore);
116     if (layer)
117       return layer;
118   }
119   return NULL;
120 }
121 
122 // Depth first search through the siblings of |target||. This does not search
123 // all the siblings, only those before/after |target| (depening upon the
124 // template type) and ignoring |ignore|. Returns the Layer of the first Window
125 // encountered with a Layer.
126 template <class T>
FindStackingLayerInSiblings(aura::Window * target,aura::Window * ignore)127 ui::Layer* FindStackingLayerInSiblings(aura::Window* target,
128                                        aura::Window* ignore) {
129   aura::Window* parent = target->parent();
130   for (T i = std::find(IteratorForDirectionBegin<T>(parent),
131                   IteratorForDirectionEnd<T>(parent), target);
132        i != IteratorForDirectionEnd<T>(parent); ++i) {
133     ui::Layer* layer = FindStackingTargetLayerDown<T>(*i, ignore);
134     if (layer)
135       return layer;
136   }
137   return NULL;
138 }
139 
140 // Returns the first Window that has a Layer. This does a depth first search
141 // through the descendants of |target| first, then ascends up doing a depth
142 // first search through siblings of all ancestors until a Layer is found or an
143 // ancestor with a layer is found. This is intended to locate a layer to stack
144 // other layers relative to.
145 template <class T>
FindStackingTargetLayer(aura::Window * target,aura::Window * ignore)146 ui::Layer* FindStackingTargetLayer(aura::Window* target, aura::Window* ignore) {
147   ui::Layer* result = FindStackingTargetLayerDown<T>(target, ignore);
148   if (result)
149     return result;
150   while (target->parent()) {
151     ui::Layer* result = FindStackingLayerInSiblings<T>(target, ignore);
152     if (result)
153       return result;
154     target = target->parent();
155     if (target->layer())
156       return NULL;
157   }
158   return NULL;
159 }
160 
161 // Does a depth first search for all descendants of |child| that have layers.
162 // This stops at any descendants that have layers (and adds them to |layers|).
GetLayersToStack(aura::Window * child,std::vector<ui::Layer * > * layers)163 void GetLayersToStack(aura::Window* child, std::vector<ui::Layer*>* layers) {
164   if (child->layer()) {
165     layers->push_back(child->layer());
166     return;
167   }
168   for (size_t i = 0; i < child->children().size(); ++i)
169     GetLayersToStack(child->children()[i], layers);
170 }
171 
172 }  // namespace
173 
174 class ScopedCursorHider {
175  public:
ScopedCursorHider(Window * window)176   explicit ScopedCursorHider(Window* window)
177       : window_(window),
178         hid_cursor_(false) {
179     if (!window_->HasDispatcher())
180       return;
181     const bool cursor_is_in_bounds = window_->GetBoundsInScreen().Contains(
182         Env::GetInstance()->last_mouse_location());
183     client::CursorClient* cursor_client = client::GetCursorClient(window_);
184     if (cursor_is_in_bounds && cursor_client &&
185         cursor_client->IsCursorVisible()) {
186       cursor_client->HideCursor();
187       hid_cursor_ = true;
188     }
189   }
~ScopedCursorHider()190   ~ScopedCursorHider() {
191     if (!window_->HasDispatcher())
192       return;
193 
194     // Update the device scale factor of the cursor client only when the last
195     // mouse location is on this root window.
196     if (hid_cursor_) {
197       client::CursorClient* cursor_client = client::GetCursorClient(window_);
198       if (cursor_client) {
199         const gfx::Display& display =
200             gfx::Screen::GetScreenFor(window_)->GetDisplayNearestWindow(
201                 window_);
202         cursor_client->SetDisplay(display);
203         cursor_client->ShowCursor();
204       }
205     }
206   }
207 
208  private:
209   Window* window_;
210   bool hid_cursor_;
211 
212   DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider);
213 };
214 
Window(WindowDelegate * delegate)215 Window::Window(WindowDelegate* delegate)
216     : dispatcher_(NULL),
217       type_(client::WINDOW_TYPE_UNKNOWN),
218       owned_by_parent_(true),
219       delegate_(delegate),
220       parent_(NULL),
221       transient_parent_(NULL),
222       visible_(false),
223       id_(-1),
224       transparent_(false),
225       user_data_(NULL),
226       ignore_events_(false),
227       // Don't notify newly added observers during notification. This causes
228       // problems for code that adds an observer as part of an observer
229       // notification (such as the workspace code).
230       observers_(ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY) {
231   set_target_handler(delegate_);
232 }
233 
~Window()234 Window::~Window() {
235   // |layer_| can be NULL during tests, or if this Window is layerless.
236   if (layer_)
237     layer_->SuppressPaint();
238 
239   // Let the delegate know we're in the processing of destroying.
240   if (delegate_)
241     delegate_->OnWindowDestroying();
242   FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this));
243 
244   // Let the root know so that it can remove any references to us.
245   WindowEventDispatcher* dispatcher = GetDispatcher();
246   if (dispatcher)
247     dispatcher->OnWindowDestroying(this);
248 
249   // Then destroy the children.
250   RemoveOrDestroyChildren();
251 
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
258   // WindowDestroyed callbacks of delegate and the observers.
259   if (parent_)
260     parent_->RemoveChild(this);
261 
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_)
271     delegate_->OnWindowDestroyed();
272   ObserverListBase<WindowObserver>::Iterator iter(observers_);
273   WindowObserver* observer;
274   while ((observer = iter.GetNext())) {
275     RemoveObserver(observer);
276     observer->OnWindowDestroyed(this);
277   }
278 
279   // Clear properties.
280   for (std::map<const void*, Value>::const_iterator iter = prop_map_.begin();
281        iter != prop_map_.end();
282        ++iter) {
283     if (iter->second.deallocator)
284       (*iter->second.deallocator)(iter->second.value);
285   }
286   prop_map_.clear();
287 
288   // If we have layer it will either be destroyed by |layer_owner_|'s dtor, or
289   // by whoever acquired it. We don't have a layer if Init() wasn't invoked or
290   // we are layerless.
291   if (layer_) {
292     layer_->set_delegate(NULL);
293     layer_ = NULL;
294   }
295 }
296 
Init(ui::LayerType layer_type)297 void Window::Init(ui::LayerType layer_type) {
298   InitWithWindowLayerType(UILayerTypeToWindowLayerType(layer_type));
299 }
300 
InitWithWindowLayerType(WindowLayerType window_layer_type)301 void Window::InitWithWindowLayerType(WindowLayerType window_layer_type) {
302   if (window_layer_type != WINDOW_LAYER_NONE) {
303     layer_ = new ui::Layer(WindowLayerTypeToUILayerType(window_layer_type));
304     layer_owner_.reset(layer_);
305     layer_->SetVisible(false);
306     layer_->set_delegate(this);
307     UpdateLayerName(name_);
308     layer_->SetFillsBoundsOpaquely(!transparent_);
309   }
310 
311   Env::GetInstance()->NotifyWindowInitialized(this);
312 }
313 
RecreateLayer()314 ui::Layer* Window::RecreateLayer() {
315   // Disconnect the old layer, but don't delete it.
316   ui::Layer* old_layer = AcquireLayer();
317   if (!old_layer)
318     return NULL;
319 
320   old_layer->set_delegate(NULL);
321 
322   layer_ = new ui::Layer(old_layer->type());
323   layer_owner_.reset(layer_);
324   layer_->SetVisible(old_layer->visible());
325   layer_->set_scale_content(old_layer->scale_content());
326   layer_->set_delegate(this);
327   layer_->SetMasksToBounds(old_layer->GetMasksToBounds());
328 
329   if (delegate_)
330     delegate_->DidRecreateLayer(old_layer, layer_);
331 
332   UpdateLayerName(name_);
333   layer_->SetFillsBoundsOpaquely(!transparent_);
334   // Install new layer as a sibling of the old layer, stacked below it.
335   if (old_layer->parent()) {
336     old_layer->parent()->Add(layer_);
337     old_layer->parent()->StackBelow(layer_, old_layer);
338   }
339   // Migrate all the child layers over to the new layer. Copy the list because
340   // the items are removed during iteration.
341   std::vector<ui::Layer*> children_copy = old_layer->children();
342   for (std::vector<ui::Layer*>::const_iterator it = children_copy.begin();
343        it != children_copy.end();
344        ++it) {
345     ui::Layer* child = *it;
346     layer_->Add(child);
347   }
348   return old_layer;
349 }
350 
SetType(client::WindowType type)351 void Window::SetType(client::WindowType type) {
352   // Cannot change type after the window is initialized.
353   DCHECK(!layer_);
354   type_ = type;
355 }
356 
SetName(const std::string & name)357 void Window::SetName(const std::string& name) {
358   name_ = name;
359 
360   if (layer_)
361     UpdateLayerName(name_);
362 }
363 
SetTransparent(bool transparent)364 void Window::SetTransparent(bool transparent) {
365   transparent_ = transparent;
366   if (layer_)
367     layer_->SetFillsBoundsOpaquely(!transparent_);
368 }
369 
GetRootWindow()370 Window* Window::GetRootWindow() {
371   return const_cast<Window*>(
372       static_cast<const Window*>(this)->GetRootWindow());
373 }
374 
GetRootWindow() const375 const Window* Window::GetRootWindow() const {
376   return dispatcher_ ? this : parent_ ? parent_->GetRootWindow() : NULL;
377 }
378 
GetDispatcher()379 WindowEventDispatcher* Window::GetDispatcher() {
380   return const_cast<WindowEventDispatcher*>(const_cast<const Window*>(this)->
381       GetDispatcher());
382 }
383 
GetDispatcher() const384 const WindowEventDispatcher* Window::GetDispatcher() const {
385   const Window* root_window = GetRootWindow();
386   return root_window ? root_window->dispatcher_ : NULL;
387 }
388 
Show()389 void Window::Show() {
390   SetVisible(true);
391 }
392 
Hide()393 void Window::Hide() {
394   for (Windows::iterator it = transient_children_.begin();
395        it != transient_children_.end(); ++it) {
396     (*it)->Hide();
397   }
398   SetVisible(false);
399   ReleaseCapture();
400 }
401 
IsVisible() const402 bool Window::IsVisible() const {
403   // Layer visibility can be inconsistent with window visibility, for example
404   // 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
406   // so the layer will be visible for some time after Hide() is called).
407   for (const Window* window = this; window; window = window->parent()) {
408     if (!window->visible_)
409       return false;
410     if (window->layer_)
411       return window->layer_->IsDrawn();
412   }
413   return false;
414 }
415 
GetBoundsInRootWindow() const416 gfx::Rect Window::GetBoundsInRootWindow() const {
417   // TODO(beng): There may be a better way to handle this, and the existing code
418   //             is likely wrong anyway in a multi-display world, but this will
419   //             do for now.
420   if (!GetRootWindow())
421     return bounds();
422   gfx::Point origin = bounds().origin();
423   ConvertPointToTarget(parent_, GetRootWindow(), &origin);
424   return gfx::Rect(origin, bounds().size());
425 }
426 
GetBoundsInScreen() const427 gfx::Rect Window::GetBoundsInScreen() const {
428   gfx::Rect bounds(GetBoundsInRootWindow());
429   const Window* root = GetRootWindow();
430   if (root) {
431     aura::client::ScreenPositionClient* screen_position_client =
432         aura::client::GetScreenPositionClient(root);
433     if (screen_position_client) {
434       gfx::Point origin = bounds.origin();
435       screen_position_client->ConvertPointToScreen(root, &origin);
436       bounds.set_origin(origin);
437     }
438   }
439   return bounds;
440 }
441 
SetTransform(const gfx::Transform & transform)442 void Window::SetTransform(const gfx::Transform& transform) {
443   if (!layer_) {
444     // Transforms aren't supported on layerless windows.
445     NOTREACHED();
446     return;
447   }
448   WindowEventDispatcher* dispatcher = GetDispatcher();
449   bool contained_mouse = IsVisible() && dispatcher &&
450       ContainsPointInRoot(dispatcher->GetLastMouseLocationInRoot());
451   layer_->SetTransform(transform);
452   if (dispatcher)
453     dispatcher->OnWindowTransformed(this, contained_mouse);
454 }
455 
SetLayoutManager(LayoutManager * layout_manager)456 void Window::SetLayoutManager(LayoutManager* layout_manager) {
457   if (layout_manager == layout_manager_)
458     return;
459   layout_manager_.reset(layout_manager);
460   if (!layout_manager)
461     return;
462   // If we're changing to a new layout manager, ensure it is aware of all the
463   // existing child windows.
464   for (Windows::const_iterator it = children_.begin();
465        it != children_.end();
466        ++it)
467     layout_manager_->OnWindowAddedToLayout(*it);
468 }
469 
SetBounds(const gfx::Rect & new_bounds)470 void Window::SetBounds(const gfx::Rect& new_bounds) {
471   if (parent_ && parent_->layout_manager())
472     parent_->layout_manager()->SetChildBounds(this, new_bounds);
473   else
474     SetBoundsInternal(new_bounds);
475 }
476 
SetBoundsInScreen(const gfx::Rect & new_bounds_in_screen,const gfx::Display & dst_display)477 void Window::SetBoundsInScreen(const gfx::Rect& new_bounds_in_screen,
478                                const gfx::Display& dst_display) {
479   Window* root = GetRootWindow();
480   if (root) {
481     gfx::Point origin = new_bounds_in_screen.origin();
482     aura::client::ScreenPositionClient* screen_position_client =
483         aura::client::GetScreenPositionClient(root);
484     screen_position_client->SetBounds(this, new_bounds_in_screen, dst_display);
485     return;
486   }
487   SetBounds(new_bounds_in_screen);
488 }
489 
GetTargetBounds() const490 gfx::Rect Window::GetTargetBounds() const {
491   if (!layer_)
492     return bounds();
493 
494   if (!parent_ || parent_->layer_)
495     return layer_->GetTargetBounds();
496 
497   // We have a layer but our parent (who is valid) doesn't. This means the
498   // coordinates of the layer are relative to the first ancestor with a layer;
499   // convert to be relative to parent.
500   gfx::Vector2d offset;
501   const aura::Window* ancestor_with_layer =
502       parent_->GetAncestorWithLayer(&offset);
503   if (!ancestor_with_layer)
504     return layer_->GetTargetBounds();
505 
506   gfx::Rect layer_target_bounds = layer_->GetTargetBounds();
507   layer_target_bounds -= offset;
508   return layer_target_bounds;
509 }
510 
SchedulePaintInRect(const gfx::Rect & rect)511 void Window::SchedulePaintInRect(const gfx::Rect& rect) {
512   if (!layer_ && parent_) {
513     // Notification of paint scheduled happens for the window with a layer.
514     gfx::Rect parent_rect(bounds().size());
515     parent_rect.Intersect(rect);
516     if (!parent_rect.IsEmpty()) {
517       parent_rect.Offset(bounds().origin().OffsetFromOrigin());
518       parent_->SchedulePaintInRect(parent_rect);
519     }
520   } else if (layer_ && layer_->SchedulePaint(rect)) {
521     FOR_EACH_OBSERVER(
522         WindowObserver, observers_, OnWindowPaintScheduled(this, rect));
523   }
524 }
525 
StackChildAtTop(Window * child)526 void Window::StackChildAtTop(Window* child) {
527   if (children_.size() <= 1 || child == children_.back())
528     return;  // In the front already.
529   StackChildAbove(child, children_.back());
530 }
531 
StackChildAbove(Window * child,Window * target)532 void Window::StackChildAbove(Window* child, Window* target) {
533   StackChildRelativeTo(child, target, STACK_ABOVE);
534 }
535 
StackChildAtBottom(Window * child)536 void Window::StackChildAtBottom(Window* child) {
537   if (children_.size() <= 1 || child == children_.front())
538     return;  // At the bottom already.
539   StackChildBelow(child, children_.front());
540 }
541 
StackChildBelow(Window * child,Window * target)542 void Window::StackChildBelow(Window* child, Window* target) {
543   StackChildRelativeTo(child, target, STACK_BELOW);
544 }
545 
AddChild(Window * child)546 void Window::AddChild(Window* child) {
547   WindowObserver::HierarchyChangeParams params;
548   params.target = child;
549   params.new_parent = this;
550   params.old_parent = child->parent();
551   params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
552   NotifyWindowHierarchyChange(params);
553 
554   Window* old_root = child->GetRootWindow();
555 
556   DCHECK(std::find(children_.begin(), children_.end(), child) ==
557       children_.end());
558   if (child->parent())
559     child->parent()->RemoveChildImpl(child, this);
560 
561   gfx::Vector2d offset;
562   aura::Window* ancestor_with_layer = GetAncestorWithLayer(&offset);
563   if (ancestor_with_layer) {
564     offset += child->bounds().OffsetFromOrigin();
565     child->ReparentLayers(ancestor_with_layer->layer(), offset);
566   }
567 
568   child->parent_ = this;
569 
570   children_.push_back(child);
571   if (layout_manager_)
572     layout_manager_->OnWindowAddedToLayout(child);
573   FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child));
574   child->OnParentChanged();
575 
576   Window* root_window = GetRootWindow();
577   if (root_window && old_root != root_window) {
578     root_window->GetDispatcher()->OnWindowAddedToRootWindow(child);
579     child->NotifyAddedToRootWindow();
580   }
581 
582   params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
583   NotifyWindowHierarchyChange(params);
584 }
585 
RemoveChild(Window * child)586 void Window::RemoveChild(Window* child) {
587   WindowObserver::HierarchyChangeParams params;
588   params.target = child;
589   params.new_parent = NULL;
590   params.old_parent = this;
591   params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
592   NotifyWindowHierarchyChange(params);
593 
594   RemoveChildImpl(child, NULL);
595 
596   params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
597   NotifyWindowHierarchyChange(params);
598 }
599 
Contains(const Window * other) const600 bool Window::Contains(const Window* other) const {
601   for (const Window* parent = other; parent; parent = parent->parent_) {
602     if (parent == this)
603       return true;
604   }
605   return false;
606 }
607 
AddTransientChild(Window * child)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 
RemoveTransientChild(Window * child)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 
GetChildById(int id)630 Window* Window::GetChildById(int id) {
631   return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id));
632 }
633 
GetChildById(int id) const634 const Window* Window::GetChildById(int id) const {
635   Windows::const_iterator i;
636   for (i = children_.begin(); i != children_.end(); ++i) {
637     if ((*i)->id() == id)
638       return *i;
639     const Window* result = (*i)->GetChildById(id);
640     if (result)
641       return result;
642   }
643   return NULL;
644 }
645 
646 // static
ConvertPointToTarget(const Window * source,const Window * target,gfx::Point * point)647 void Window::ConvertPointToTarget(const Window* source,
648                                   const Window* target,
649                                   gfx::Point* point) {
650   if (!source)
651     return;
652   if (source->GetRootWindow() != target->GetRootWindow()) {
653     client::ScreenPositionClient* source_client =
654         client::GetScreenPositionClient(source->GetRootWindow());
655     source_client->ConvertPointToScreen(source, point);
656 
657     client::ScreenPositionClient* target_client =
658         client::GetScreenPositionClient(target->GetRootWindow());
659     target_client->ConvertPointFromScreen(target, point);
660   } else if ((source != target) && (!source->layer_ || !target->layer_)) {
661     if (!source->layer_) {
662       gfx::Vector2d offset_to_layer;
663       source = source->GetAncestorWithLayer(&offset_to_layer);
664       *point += offset_to_layer;
665     }
666     if (!target->layer_) {
667       gfx::Vector2d offset_to_layer;
668       target = target->GetAncestorWithLayer(&offset_to_layer);
669       *point -= offset_to_layer;
670     }
671     ui::Layer::ConvertPointToLayer(source->layer_, target->layer_, point);
672   } else {
673     ui::Layer::ConvertPointToLayer(source->layer_, target->layer_, point);
674   }
675 }
676 
MoveCursorTo(const gfx::Point & point_in_window)677 void Window::MoveCursorTo(const gfx::Point& point_in_window) {
678   Window* root_window = GetRootWindow();
679   DCHECK(root_window);
680   gfx::Point point_in_root(point_in_window);
681   ConvertPointToTarget(this, root_window, &point_in_root);
682   root_window->GetDispatcher()->MoveCursorTo(point_in_root);
683 }
684 
GetCursor(const gfx::Point & point) const685 gfx::NativeCursor Window::GetCursor(const gfx::Point& point) const {
686   return delegate_ ? delegate_->GetCursor(point) : gfx::kNullCursor;
687 }
688 
SetEventFilter(ui::EventHandler * event_filter)689 void Window::SetEventFilter(ui::EventHandler* event_filter) {
690   if (event_filter_)
691     RemovePreTargetHandler(event_filter_.get());
692   event_filter_.reset(event_filter);
693   if (event_filter)
694     AddPreTargetHandler(event_filter);
695 }
696 
AddObserver(WindowObserver * observer)697 void Window::AddObserver(WindowObserver* observer) {
698   observers_.AddObserver(observer);
699 }
700 
RemoveObserver(WindowObserver * observer)701 void Window::RemoveObserver(WindowObserver* observer) {
702   observers_.RemoveObserver(observer);
703 }
704 
HasObserver(WindowObserver * observer)705 bool Window::HasObserver(WindowObserver* observer) {
706   return observers_.HasObserver(observer);
707 }
708 
ContainsPointInRoot(const gfx::Point & point_in_root) const709 bool Window::ContainsPointInRoot(const gfx::Point& point_in_root) const {
710   const Window* root_window = GetRootWindow();
711   if (!root_window)
712     return false;
713   gfx::Point local_point(point_in_root);
714   ConvertPointToTarget(root_window, this, &local_point);
715   return gfx::Rect(GetTargetBounds().size()).Contains(local_point);
716 }
717 
ContainsPoint(const gfx::Point & local_point) const718 bool Window::ContainsPoint(const gfx::Point& local_point) const {
719   return gfx::Rect(bounds().size()).Contains(local_point);
720 }
721 
HitTest(const gfx::Point & local_point)722 bool Window::HitTest(const gfx::Point& local_point) {
723   // Expand my bounds for hit testing (override is usually zero but it's
724   // probably cheaper to do the math every time than to branch).
725   gfx::Rect local_bounds(gfx::Point(), bounds().size());
726   local_bounds.Inset(aura::Env::GetInstance()->is_touch_down() ?
727       hit_test_bounds_override_outer_touch_ :
728       hit_test_bounds_override_outer_mouse_);
729 
730   if (!delegate_ || !delegate_->HasHitTestMask())
731     return local_bounds.Contains(local_point);
732 
733   gfx::Path mask;
734   delegate_->GetHitTestMask(&mask);
735 
736   SkRegion clip_region;
737   clip_region.setRect(local_bounds.x(), local_bounds.y(),
738                       local_bounds.width(), local_bounds.height());
739   SkRegion mask_region;
740   return mask_region.setPath(mask, clip_region) &&
741       mask_region.contains(local_point.x(), local_point.y());
742 }
743 
GetEventHandlerForPoint(const gfx::Point & local_point)744 Window* Window::GetEventHandlerForPoint(const gfx::Point& local_point) {
745   return GetWindowForPoint(local_point, true, true);
746 }
747 
GetTopWindowContainingPoint(const gfx::Point & local_point)748 Window* Window::GetTopWindowContainingPoint(const gfx::Point& local_point) {
749   return GetWindowForPoint(local_point, false, false);
750 }
751 
GetToplevelWindow()752 Window* Window::GetToplevelWindow() {
753   Window* topmost_window_with_delegate = NULL;
754   for (aura::Window* window = this; window != NULL; window = window->parent()) {
755     if (window->delegate())
756       topmost_window_with_delegate = window;
757   }
758   return topmost_window_with_delegate;
759 }
760 
Focus()761 void Window::Focus() {
762   client::FocusClient* client = client::GetFocusClient(this);
763   DCHECK(client);
764   client->FocusWindow(this);
765 }
766 
Blur()767 void Window::Blur() {
768   client::FocusClient* client = client::GetFocusClient(this);
769   DCHECK(client);
770   client->FocusWindow(NULL);
771 }
772 
HasFocus() const773 bool Window::HasFocus() const {
774   client::FocusClient* client = client::GetFocusClient(this);
775   return client && client->GetFocusedWindow() == this;
776 }
777 
CanFocus() const778 bool Window::CanFocus() const {
779   if (dispatcher_)
780     return IsVisible();
781 
782   // NOTE: as part of focusing the window the ActivationClient may make the
783   // window visible (by way of making a hidden ancestor visible). For this
784   // reason we can't check visibility here and assume the client is doing it.
785   if (!parent_ || (delegate_ && !delegate_->CanFocus()))
786     return false;
787 
788   // The client may forbid certain windows from receiving focus at a given point
789   // in time.
790   client::EventClient* client = client::GetEventClient(GetRootWindow());
791   if (client && !client->CanProcessEventsWithinSubtree(this))
792     return false;
793 
794   return parent_->CanFocus();
795 }
796 
CanReceiveEvents() const797 bool Window::CanReceiveEvents() const {
798   if (dispatcher_)
799     return IsVisible();
800 
801   // The client may forbid certain windows from receiving events at a given
802   // point in time.
803   client::EventClient* client = client::GetEventClient(GetRootWindow());
804   if (client && !client->CanProcessEventsWithinSubtree(this))
805     return false;
806 
807   return parent_ && IsVisible() && parent_->CanReceiveEvents();
808 }
809 
SetCapture()810 void Window::SetCapture() {
811   if (!IsVisible())
812     return;
813 
814   Window* root_window = GetRootWindow();
815   if (!root_window)
816     return;
817   client::GetCaptureClient(root_window)->SetCapture(this);
818 }
819 
ReleaseCapture()820 void Window::ReleaseCapture() {
821   Window* root_window = GetRootWindow();
822   if (!root_window)
823     return;
824   client::GetCaptureClient(root_window)->ReleaseCapture(this);
825 }
826 
HasCapture()827 bool Window::HasCapture() {
828   Window* root_window = GetRootWindow();
829   if (!root_window)
830     return false;
831   client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
832   return capture_client && capture_client->GetCaptureWindow() == this;
833 }
834 
SuppressPaint()835 void Window::SuppressPaint() {
836   if (layer_)
837     layer_->SuppressPaint();
838 }
839 
840 // {Set,Get,Clear}Property are implemented in window_property.h.
841 
SetNativeWindowProperty(const char * key,void * value)842 void Window::SetNativeWindowProperty(const char* key, void* value) {
843   SetPropertyInternal(
844       key, key, NULL, reinterpret_cast<int64>(value), 0);
845 }
846 
GetNativeWindowProperty(const char * key) const847 void* Window::GetNativeWindowProperty(const char* key) const {
848   return reinterpret_cast<void*>(GetPropertyInternal(key, 0));
849 }
850 
OnDeviceScaleFactorChanged(float device_scale_factor)851 void Window::OnDeviceScaleFactorChanged(float device_scale_factor) {
852   ScopedCursorHider hider(this);
853   if (dispatcher_)
854     dispatcher_->host()->OnDeviceScaleFactorChanged(device_scale_factor);
855   if (delegate_)
856     delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
857 }
858 
859 #if !defined(NDEBUG)
GetDebugInfo() const860 std::string Window::GetDebugInfo() const {
861   return base::StringPrintf(
862       "%s<%d> bounds(%d, %d, %d, %d) %s %s opacity=%.1f",
863       name().empty() ? "Unknown" : name().c_str(), id(),
864       bounds().x(), bounds().y(), bounds().width(), bounds().height(),
865       visible_ ? "WindowVisible" : "WindowHidden",
866       layer_ ?
867           (layer_->GetTargetVisibility() ? "LayerVisible" : "LayerHidden") :
868           "NoLayer",
869       layer_ ? layer_->opacity() : 1.0f);
870 }
871 
PrintWindowHierarchy(int depth) const872 void Window::PrintWindowHierarchy(int depth) const {
873   VLOG(0) << base::StringPrintf(
874       "%*s%s", depth * 2, "", GetDebugInfo().c_str());
875   for (Windows::const_iterator it = children_.begin();
876        it != children_.end(); ++it) {
877     Window* child = *it;
878     child->PrintWindowHierarchy(depth + 1);
879   }
880 }
881 #endif
882 
RemoveOrDestroyChildren()883 void Window::RemoveOrDestroyChildren() {
884   while (!children_.empty()) {
885     Window* child = children_[0];
886     if (child->owned_by_parent_) {
887       delete child;
888       // Deleting the child so remove it from out children_ list.
889       DCHECK(std::find(children_.begin(), children_.end(), child) ==
890              children_.end());
891     } else {
892       // Even if we can't delete the child, we still need to remove it from the
893       // parent so that relevant bookkeeping (parent_ back-pointers etc) are
894       // updated.
895       RemoveChild(child);
896     }
897   }
898 }
899 
900 ///////////////////////////////////////////////////////////////////////////////
901 // Window, private:
902 
SetPropertyInternal(const void * key,const char * name,PropertyDeallocator deallocator,int64 value,int64 default_value)903 int64 Window::SetPropertyInternal(const void* key,
904                                   const char* name,
905                                   PropertyDeallocator deallocator,
906                                   int64 value,
907                                   int64 default_value) {
908   int64 old = GetPropertyInternal(key, default_value);
909   if (value == default_value) {
910     prop_map_.erase(key);
911   } else {
912     Value prop_value;
913     prop_value.name = name;
914     prop_value.value = value;
915     prop_value.deallocator = deallocator;
916     prop_map_[key] = prop_value;
917   }
918   FOR_EACH_OBSERVER(WindowObserver, observers_,
919                     OnWindowPropertyChanged(this, key, old));
920   return old;
921 }
922 
GetPropertyInternal(const void * key,int64 default_value) const923 int64 Window::GetPropertyInternal(const void* key,
924                                   int64 default_value) const {
925   std::map<const void*, Value>::const_iterator iter = prop_map_.find(key);
926   if (iter == prop_map_.end())
927     return default_value;
928   return iter->second.value;
929 }
930 
SetBoundsInternal(const gfx::Rect & new_bounds)931 void Window::SetBoundsInternal(const gfx::Rect& new_bounds) {
932   gfx::Rect actual_new_bounds(new_bounds);
933 
934   // Ensure we don't go smaller than our minimum bounds.
935   if (delegate_) {
936     const gfx::Size& min_size = delegate_->GetMinimumSize();
937     actual_new_bounds.set_width(
938         std::max(min_size.width(), actual_new_bounds.width()));
939     actual_new_bounds.set_height(
940         std::max(min_size.height(), actual_new_bounds.height()));
941   }
942 
943   gfx::Rect old_bounds = GetTargetBounds();
944 
945   // Always need to set the layer's bounds -- even if it is to the same thing.
946   // This may cause important side effects such as stopping animation.
947   if (!layer_) {
948     const gfx::Vector2d origin_delta = new_bounds.OffsetFromOrigin() -
949         bounds_.OffsetFromOrigin();
950     bounds_ = new_bounds;
951     OffsetLayerBounds(origin_delta);
952   } else {
953     if (parent_ && !parent_->layer_) {
954       gfx::Vector2d offset;
955       const aura::Window* ancestor_with_layer =
956           parent_->GetAncestorWithLayer(&offset);
957       if (ancestor_with_layer)
958         actual_new_bounds.Offset(offset);
959     }
960     layer_->SetBounds(actual_new_bounds);
961   }
962 
963   // If we are currently not the layer's delegate, we will not get bounds
964   // changed notification from the layer (this typically happens after animating
965   // hidden). We must notify ourselves.
966   if (!layer_ || layer_->delegate() != this)
967     OnWindowBoundsChanged(old_bounds, ContainsMouse());
968 }
969 
SetVisible(bool visible)970 void Window::SetVisible(bool visible) {
971   if ((layer_ && visible == layer_->GetTargetVisibility()) ||
972       (!layer_ && visible == visible_))
973     return;  // No change.
974 
975   FOR_EACH_OBSERVER(WindowObserver, observers_,
976                     OnWindowVisibilityChanging(this, visible));
977 
978   WindowEventDispatcher* dispatcher = GetDispatcher();
979   if (dispatcher)
980     dispatcher->DispatchMouseExitToHidingWindow(this);
981 
982   client::VisibilityClient* visibility_client =
983       client::GetVisibilityClient(this);
984   if (visibility_client)
985     visibility_client->UpdateLayerVisibility(this, visible);
986   else if (layer_)
987     layer_->SetVisible(visible);
988   visible_ = visible;
989   SchedulePaint();
990   if (parent_ && parent_->layout_manager_)
991     parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible);
992 
993   if (delegate_)
994     delegate_->OnWindowTargetVisibilityChanged(visible);
995 
996   NotifyWindowVisibilityChanged(this, visible);
997 
998   if (dispatcher)
999     dispatcher->OnWindowVisibilityChanged(this, visible);
1000 }
1001 
SchedulePaint()1002 void Window::SchedulePaint() {
1003   SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height()));
1004 }
1005 
Paint(gfx::Canvas * canvas)1006 void Window::Paint(gfx::Canvas* canvas) {
1007   if (delegate_)
1008     delegate_->OnPaint(canvas);
1009   PaintLayerlessChildren(canvas);
1010 }
1011 
PaintLayerlessChildren(gfx::Canvas * canvas)1012 void Window::PaintLayerlessChildren(gfx::Canvas* canvas) {
1013   for (size_t i = 0, count = children_.size(); i < count; ++i) {
1014     Window* child = children_[i];
1015     if (!child->layer_ && child->visible_) {
1016       gfx::ScopedCanvas scoped_canvas(canvas);
1017       if (canvas->ClipRect(child->bounds())) {
1018         canvas->Translate(child->bounds().OffsetFromOrigin());
1019         child->Paint(canvas);
1020       }
1021     }
1022   }
1023 }
1024 
GetWindowForPoint(const gfx::Point & local_point,bool return_tightest,bool for_event_handling)1025 Window* Window::GetWindowForPoint(const gfx::Point& local_point,
1026                                   bool return_tightest,
1027                                   bool for_event_handling) {
1028   if (!IsVisible())
1029     return NULL;
1030 
1031   if ((for_event_handling && !HitTest(local_point)) ||
1032       (!for_event_handling && !ContainsPoint(local_point)))
1033     return NULL;
1034 
1035   // Check if I should claim this event and not pass it to my children because
1036   // the location is inside my hit test override area.  For details, see
1037   // set_hit_test_bounds_override_inner().
1038   if (for_event_handling && !hit_test_bounds_override_inner_.empty()) {
1039     gfx::Rect inset_local_bounds(gfx::Point(), bounds().size());
1040     inset_local_bounds.Inset(hit_test_bounds_override_inner_);
1041     // We know we're inside the normal local bounds, so if we're outside the
1042     // inset bounds we must be in the special hit test override area.
1043     DCHECK(HitTest(local_point));
1044     if (!inset_local_bounds.Contains(local_point))
1045       return delegate_ ? this : NULL;
1046   }
1047 
1048   if (!return_tightest && delegate_)
1049     return this;
1050 
1051   for (Windows::const_reverse_iterator it = children_.rbegin(),
1052            rend = children_.rend();
1053        it != rend; ++it) {
1054     Window* child = *it;
1055 
1056     if (for_event_handling) {
1057       if (child->ignore_events_)
1058         continue;
1059       // The client may not allow events to be processed by certain subtrees.
1060       client::EventClient* client = client::GetEventClient(GetRootWindow());
1061       if (client && !client->CanProcessEventsWithinSubtree(child))
1062         continue;
1063       if (delegate_ && !delegate_->ShouldDescendIntoChildForEventHandling(
1064               child, local_point))
1065         continue;
1066     }
1067 
1068     gfx::Point point_in_child_coords(local_point);
1069     ConvertPointToTarget(this, child, &point_in_child_coords);
1070     Window* match = child->GetWindowForPoint(point_in_child_coords,
1071                                              return_tightest,
1072                                              for_event_handling);
1073     if (match)
1074       return match;
1075   }
1076 
1077   return delegate_ ? this : NULL;
1078 }
1079 
RemoveChildImpl(Window * child,Window * new_parent)1080 void Window::RemoveChildImpl(Window* child, Window* new_parent) {
1081   if (layout_manager_)
1082     layout_manager_->OnWillRemoveWindowFromLayout(child);
1083   FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child));
1084   Window* root_window = child->GetRootWindow();
1085   Window* new_root_window = new_parent ? new_parent->GetRootWindow() : NULL;
1086   if (root_window && root_window != new_root_window) {
1087     root_window->GetDispatcher()->OnWindowRemovedFromRootWindow(
1088         child, new_root_window);
1089     child->NotifyRemovingFromRootWindow();
1090   }
1091 
1092   gfx::Vector2d offset;
1093   GetAncestorWithLayer(&offset);
1094   child->UnparentLayers(!layer_, offset);
1095   child->parent_ = NULL;
1096   Windows::iterator i = std::find(children_.begin(), children_.end(), child);
1097   DCHECK(i != children_.end());
1098   children_.erase(i);
1099   child->OnParentChanged();
1100   if (layout_manager_)
1101     layout_manager_->OnWindowRemovedFromLayout(child);
1102 }
1103 
UnparentLayers(bool has_layerless_ancestor,const gfx::Vector2d & offset)1104 void Window::UnparentLayers(bool has_layerless_ancestor,
1105                             const gfx::Vector2d& offset) {
1106   if (!layer_) {
1107     const gfx::Vector2d new_offset = offset + bounds().OffsetFromOrigin();
1108     for (size_t i = 0; i < children_.size(); ++i) {
1109       children_[i]->UnparentLayers(true, new_offset);
1110     }
1111   } else {
1112     // Only remove the layer if we still own it.  Someone else may have acquired
1113     // ownership of it via AcquireLayer() and may expect the hierarchy to go
1114     // unchanged as the Window is destroyed.
1115     if (layer_owner_) {
1116       if (layer_->parent())
1117         layer_->parent()->Remove(layer_);
1118       if (has_layerless_ancestor) {
1119         const gfx::Rect real_bounds(bounds_);
1120         gfx::Rect layer_bounds(layer_->bounds());
1121         layer_bounds.Offset(-offset);
1122         layer_->SetBounds(layer_bounds);
1123         bounds_ = real_bounds;
1124       }
1125     }
1126   }
1127 }
1128 
ReparentLayers(ui::Layer * parent_layer,const gfx::Vector2d & offset)1129 void Window::ReparentLayers(ui::Layer* parent_layer,
1130                             const gfx::Vector2d& offset) {
1131   if (!layer_) {
1132     for (size_t i = 0; i < children_.size(); ++i) {
1133       children_[i]->ReparentLayers(
1134           parent_layer,
1135           offset + children_[i]->bounds().OffsetFromOrigin());
1136     }
1137   } else {
1138     const gfx::Rect real_bounds(bounds());
1139     parent_layer->Add(layer_);
1140     gfx::Rect layer_bounds(layer_->bounds().size());
1141     layer_bounds += offset;
1142     layer_->SetBounds(layer_bounds);
1143     bounds_ = real_bounds;
1144   }
1145 }
1146 
OffsetLayerBounds(const gfx::Vector2d & offset)1147 void Window::OffsetLayerBounds(const gfx::Vector2d& offset) {
1148   if (!layer_) {
1149     for (size_t i = 0; i < children_.size(); ++i)
1150       children_[i]->OffsetLayerBounds(offset);
1151   } else {
1152     gfx::Rect layer_bounds(layer_->bounds());
1153     layer_bounds += offset;
1154     layer_->SetBounds(layer_bounds);
1155   }
1156 }
1157 
OnParentChanged()1158 void Window::OnParentChanged() {
1159   FOR_EACH_OBSERVER(
1160       WindowObserver, observers_, OnWindowParentChanged(this, parent_));
1161 }
1162 
HasTransientAncestor(const Window * ancestor) const1163 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 
SkipNullDelegatesForStacking(StackDirection direction,Window ** target) const1170 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 
StackChildRelativeTo(Window * child,Window * target,StackDirection direction)1191 void Window::StackChildRelativeTo(Window* child,
1192                                   Window* target,
1193                                   StackDirection direction) {
1194   DCHECK_NE(child, target);
1195   DCHECK(child);
1196   DCHECK(target);
1197   DCHECK_EQ(this, child->parent());
1198   DCHECK_EQ(this, target->parent());
1199 
1200   client::WindowStackingClient* stacking_client =
1201       client::GetWindowStackingClient();
1202   if (stacking_client)
1203     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;
1211 
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 
StackChildRelativeToImpl(Window * child,Window * target,StackDirection direction)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 =
1244       std::find(children_.begin(), children_.end(), child) - children_.begin();
1245   const size_t target_i =
1246       std::find(children_.begin(), children_.end(), target) - children_.begin();
1247 
1248   // Don't move the child if it is already in the right place.
1249   if ((direction == STACK_ABOVE && child_i == target_i + 1) ||
1250       (direction == STACK_BELOW && child_i + 1 == target_i))
1251     return;
1252 
1253   const size_t dest_i =
1254       direction == STACK_ABOVE ?
1255       (child_i < target_i ? target_i : target_i + 1) :
1256       (child_i < target_i ? target_i - 1 : target_i);
1257   children_.erase(children_.begin() + child_i);
1258   children_.insert(children_.begin() + dest_i, child);
1259 
1260   StackChildLayerRelativeTo(child, target, direction);
1261 
1262   child->OnStackingChanged();
1263 }
1264 
StackChildLayerRelativeTo(Window * child,Window * target,StackDirection direction)1265 void Window::StackChildLayerRelativeTo(Window* child,
1266                                        Window* target,
1267                                        StackDirection direction) {
1268   Window* ancestor_with_layer = GetAncestorWithLayer(NULL);
1269   ui::Layer* ancestor_layer =
1270       ancestor_with_layer ? ancestor_with_layer->layer() : NULL;
1271   if (!ancestor_layer)
1272     return;
1273 
1274   if (child->layer_ && target->layer_) {
1275     if (direction == STACK_ABOVE)
1276       ancestor_layer->StackAbove(child->layer_, target->layer_);
1277     else
1278       ancestor_layer->StackBelow(child->layer_, target->layer_);
1279     return;
1280   }
1281   typedef std::vector<ui::Layer*> Layers;
1282   Layers layers;
1283   GetLayersToStack(child, &layers);
1284   if (layers.empty())
1285     return;
1286 
1287   ui::Layer* target_layer;
1288   if (direction == STACK_ABOVE) {
1289     target_layer =
1290         FindStackingTargetLayer<Windows::const_reverse_iterator>(target, child);
1291   } else {
1292     target_layer =
1293         FindStackingTargetLayer<Windows::const_iterator>(target, child);
1294   }
1295 
1296   if (!target_layer) {
1297     if (direction == STACK_ABOVE) {
1298       for (Layers::const_reverse_iterator i = layers.rbegin();
1299            i != layers.rend(); ++i) {
1300         ancestor_layer->StackAtBottom(*i);
1301       }
1302     } else {
1303       for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1304         ancestor_layer->StackAtTop(*i);
1305     }
1306     return;
1307   }
1308 
1309   if (direction == STACK_ABOVE) {
1310     for (Layers::const_reverse_iterator i = layers.rbegin();
1311          i != layers.rend(); ++i) {
1312       ancestor_layer->StackAbove(*i, target_layer);
1313     }
1314   } else {
1315     for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1316       ancestor_layer->StackBelow(*i, target_layer);
1317   }
1318 }
1319 
OnStackingChanged()1320 void Window::OnStackingChanged() {
1321   FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowStackingChanged(this));
1322 }
1323 
NotifyRemovingFromRootWindow()1324 void Window::NotifyRemovingFromRootWindow() {
1325   FOR_EACH_OBSERVER(WindowObserver, observers_,
1326                     OnWindowRemovingFromRootWindow(this));
1327   for (Window::Windows::const_iterator it = children_.begin();
1328        it != children_.end(); ++it) {
1329     (*it)->NotifyRemovingFromRootWindow();
1330   }
1331 }
1332 
NotifyAddedToRootWindow()1333 void Window::NotifyAddedToRootWindow() {
1334   FOR_EACH_OBSERVER(WindowObserver, observers_,
1335                     OnWindowAddedToRootWindow(this));
1336   for (Window::Windows::const_iterator it = children_.begin();
1337        it != children_.end(); ++it) {
1338     (*it)->NotifyAddedToRootWindow();
1339   }
1340 }
1341 
NotifyWindowHierarchyChange(const WindowObserver::HierarchyChangeParams & params)1342 void Window::NotifyWindowHierarchyChange(
1343     const WindowObserver::HierarchyChangeParams& params) {
1344   params.target->NotifyWindowHierarchyChangeDown(params);
1345   switch (params.phase) {
1346   case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1347     if (params.old_parent)
1348       params.old_parent->NotifyWindowHierarchyChangeUp(params);
1349     break;
1350   case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1351     if (params.new_parent)
1352       params.new_parent->NotifyWindowHierarchyChangeUp(params);
1353     break;
1354   default:
1355     NOTREACHED();
1356     break;
1357   }
1358 }
1359 
NotifyWindowHierarchyChangeDown(const WindowObserver::HierarchyChangeParams & params)1360 void Window::NotifyWindowHierarchyChangeDown(
1361     const WindowObserver::HierarchyChangeParams& params) {
1362   NotifyWindowHierarchyChangeAtReceiver(params);
1363   for (Window::Windows::const_iterator it = children_.begin();
1364        it != children_.end(); ++it) {
1365     (*it)->NotifyWindowHierarchyChangeDown(params);
1366   }
1367 }
1368 
NotifyWindowHierarchyChangeUp(const WindowObserver::HierarchyChangeParams & params)1369 void Window::NotifyWindowHierarchyChangeUp(
1370     const WindowObserver::HierarchyChangeParams& params) {
1371   for (Window* window = this; window; window = window->parent())
1372     window->NotifyWindowHierarchyChangeAtReceiver(params);
1373 }
1374 
NotifyWindowHierarchyChangeAtReceiver(const WindowObserver::HierarchyChangeParams & params)1375 void Window::NotifyWindowHierarchyChangeAtReceiver(
1376     const WindowObserver::HierarchyChangeParams& params) {
1377   WindowObserver::HierarchyChangeParams local_params = params;
1378   local_params.receiver = this;
1379 
1380   switch (params.phase) {
1381   case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1382     FOR_EACH_OBSERVER(WindowObserver, observers_,
1383                       OnWindowHierarchyChanging(local_params));
1384     break;
1385   case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1386     FOR_EACH_OBSERVER(WindowObserver, observers_,
1387                       OnWindowHierarchyChanged(local_params));
1388     break;
1389   default:
1390     NOTREACHED();
1391     break;
1392   }
1393 }
1394 
NotifyWindowVisibilityChanged(aura::Window * target,bool visible)1395 void Window::NotifyWindowVisibilityChanged(aura::Window* target,
1396                                            bool visible) {
1397   if (!NotifyWindowVisibilityChangedDown(target, visible)) {
1398     return; // |this| has been deleted.
1399   }
1400   NotifyWindowVisibilityChangedUp(target, visible);
1401 }
1402 
NotifyWindowVisibilityChangedAtReceiver(aura::Window * target,bool visible)1403 bool Window::NotifyWindowVisibilityChangedAtReceiver(aura::Window* target,
1404                                                      bool visible) {
1405   // |this| may be deleted during a call to OnWindowVisibilityChanged() on one
1406   // of the observers. We create an local observer for that. In that case we
1407   // exit without further access to any members.
1408   WindowTracker tracker;
1409   tracker.Add(this);
1410   FOR_EACH_OBSERVER(WindowObserver, observers_,
1411                     OnWindowVisibilityChanged(target, visible));
1412   return tracker.Contains(this);
1413 }
1414 
NotifyWindowVisibilityChangedDown(aura::Window * target,bool visible)1415 bool Window::NotifyWindowVisibilityChangedDown(aura::Window* target,
1416                                                bool visible) {
1417   if (!NotifyWindowVisibilityChangedAtReceiver(target, visible))
1418     return false; // |this| was deleted.
1419   std::set<const Window*> child_already_processed;
1420   bool child_destroyed = false;
1421   do {
1422     child_destroyed = false;
1423     for (Window::Windows::const_iterator it = children_.begin();
1424          it != children_.end(); ++it) {
1425       if (!child_already_processed.insert(*it).second)
1426         continue;
1427       if (!(*it)->NotifyWindowVisibilityChangedDown(target, visible)) {
1428         // |*it| was deleted, |it| is invalid and |children_| has changed.
1429         // We exit the current for-loop and enter a new one.
1430         child_destroyed = true;
1431         break;
1432       }
1433     }
1434   } while (child_destroyed);
1435   return true;
1436 }
1437 
NotifyWindowVisibilityChangedUp(aura::Window * target,bool visible)1438 void Window::NotifyWindowVisibilityChangedUp(aura::Window* target,
1439                                              bool visible) {
1440   for (Window* window = this; window; window = window->parent()) {
1441     bool ret = window->NotifyWindowVisibilityChangedAtReceiver(target, visible);
1442     DCHECK(ret);
1443   }
1444 }
1445 
OnWindowBoundsChanged(const gfx::Rect & old_bounds,bool contained_mouse)1446 void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds,
1447                                    bool contained_mouse) {
1448   if (layer_) {
1449     bounds_ = layer_->bounds();
1450     if (parent_ && !parent_->layer_) {
1451       gfx::Vector2d offset;
1452       aura::Window* ancestor_with_layer =
1453           parent_->GetAncestorWithLayer(&offset);
1454       if (ancestor_with_layer)
1455         bounds_.Offset(-offset);
1456     }
1457   }
1458 
1459   if (layout_manager_)
1460     layout_manager_->OnWindowResized();
1461   if (delegate_)
1462     delegate_->OnBoundsChanged(old_bounds, bounds());
1463   FOR_EACH_OBSERVER(WindowObserver,
1464                     observers_,
1465                     OnWindowBoundsChanged(this, old_bounds, bounds()));
1466   WindowEventDispatcher* dispatcher = GetDispatcher();
1467   if (dispatcher)
1468     dispatcher->OnWindowBoundsChanged(this, contained_mouse);
1469 }
1470 
OnPaintLayer(gfx::Canvas * canvas)1471 void Window::OnPaintLayer(gfx::Canvas* canvas) {
1472   Paint(canvas);
1473 }
1474 
PrepareForLayerBoundsChange()1475 base::Closure Window::PrepareForLayerBoundsChange() {
1476   return base::Bind(&Window::OnWindowBoundsChanged, base::Unretained(this),
1477                     bounds(), ContainsMouse());
1478 }
1479 
CanAcceptEvent(const ui::Event & event)1480 bool Window::CanAcceptEvent(const ui::Event& event) {
1481   // The client may forbid certain windows from receiving events at a given
1482   // point in time.
1483   client::EventClient* client = client::GetEventClient(GetRootWindow());
1484   if (client && !client->CanProcessEventsWithinSubtree(this))
1485     return false;
1486 
1487   // We need to make sure that a touch cancel event and any gesture events it
1488   // creates can always reach the window. This ensures that we receive a valid
1489   // touch / gesture stream.
1490   if (event.IsEndingEvent())
1491     return true;
1492 
1493   if (!IsVisible())
1494     return false;
1495 
1496   // The top-most window can always process an event.
1497   if (!parent_)
1498     return true;
1499 
1500   // For located events (i.e. mouse, touch etc.), an assumption is made that
1501   // windows that don't have a delegate cannot process the event (see more in
1502   // GetWindowForPoint()). This assumption is not made for key events.
1503   return event.IsKeyEvent() || delegate_;
1504 }
1505 
GetParentTarget()1506 ui::EventTarget* Window::GetParentTarget() {
1507   if (dispatcher_) {
1508     return client::GetEventClient(this) ?
1509         client::GetEventClient(this)->GetToplevelEventTarget() :
1510             Env::GetInstance();
1511   }
1512   return parent_;
1513 }
1514 
GetChildIterator() const1515 scoped_ptr<ui::EventTargetIterator> Window::GetChildIterator() const {
1516   return scoped_ptr<ui::EventTargetIterator>(
1517       new ui::EventTargetIteratorImpl<Window>(children()));
1518 }
1519 
GetEventTargeter()1520 ui::EventTargeter* Window::GetEventTargeter() {
1521   return targeter_.get();
1522 }
1523 
ConvertEventToTarget(ui::EventTarget * target,ui::LocatedEvent * event)1524 void Window::ConvertEventToTarget(ui::EventTarget* target,
1525                                   ui::LocatedEvent* event) {
1526   event->ConvertLocationToTarget(this,
1527                                  static_cast<Window*>(target));
1528 }
1529 
UpdateLayerName(const std::string & name)1530 void Window::UpdateLayerName(const std::string& name) {
1531 #if !defined(NDEBUG)
1532   DCHECK(layer_);
1533 
1534   std::string layer_name(name_);
1535   if (layer_name.empty())
1536     layer_name = "Unnamed Window";
1537 
1538   if (id_ != -1)
1539     layer_name += " " + base::IntToString(id_);
1540 
1541   layer_->set_name(layer_name);
1542 #endif
1543 }
1544 
ContainsMouse()1545 bool Window::ContainsMouse() {
1546   bool contains_mouse = false;
1547   if (IsVisible()) {
1548     WindowEventDispatcher* dispatcher = GetDispatcher();
1549     contains_mouse = dispatcher &&
1550         ContainsPointInRoot(dispatcher->GetLastMouseLocationInRoot());
1551   }
1552   return contains_mouse;
1553 }
1554 
GetAncestorWithLayer(gfx::Vector2d * offset) const1555 const Window* Window::GetAncestorWithLayer(gfx::Vector2d* offset) const {
1556   for (const aura::Window* window = this; window; window = window->parent()) {
1557     if (window->layer_)
1558       return window;
1559     if (offset)
1560       *offset += window->bounds().OffsetFromOrigin();
1561   }
1562   if (offset)
1563     *offset = gfx::Vector2d();
1564   return NULL;
1565 }
1566 
1567 }  // namespace aura
1568