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