Propagate window transformed notification to child hierarchy
[chromium-blink-merge.git] / ui / aura / window.cc
blobfb25f62a3d24ed8e984851e5454033187a7baeb1
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.
5 #include "ui/aura/window.h"
7 #include <algorithm>
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"
38 namespace aura {
40 namespace {
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;
53 NOTREACHED();
54 return ui::LAYER_NOT_DRAWN;
57 // Used when searching for a Window to stack relative to.
58 template <class T>
59 T IteratorForDirectionBegin(aura::Window* window);
61 template <>
62 Window::Windows::const_iterator IteratorForDirectionBegin(
63 aura::Window* window) {
64 return window->children().begin();
67 template <>
68 Window::Windows::const_reverse_iterator IteratorForDirectionBegin(
69 aura::Window* window) {
70 return window->children().rbegin();
73 template <class T>
74 T IteratorForDirectionEnd(aura::Window* window);
76 template <>
77 Window::Windows::const_iterator IteratorForDirectionEnd(aura::Window* window) {
78 return window->children().end();
81 template <>
82 Window::Windows::const_reverse_iterator IteratorForDirectionEnd(
83 aura::Window* window) {
84 return window->children().rend();
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>
90 ui::Layer* FindStackingTargetLayerDown(aura::Window* target,
91 aura::Window* ignore) {
92 if (target == ignore)
93 return NULL;
95 if (target->layer())
96 return target->layer();
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;
104 return NULL;
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>
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;
122 return NULL;
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>
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;
143 return NULL;
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|).
148 void GetLayersToStack(aura::Window* child, std::vector<ui::Layer*>* layers) {
149 if (child->layer()) {
150 layers->push_back(child->layer());
151 return;
153 for (size_t i = 0; i < child->children().size(); ++i)
154 GetLayersToStack(child->children()[i], layers);
157 } // namespace
159 class ScopedCursorHider {
160 public:
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;
175 ~ScopedCursorHider() {
176 if (!window_->IsRootWindow())
177 return;
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();
193 private:
194 Window* window_;
195 bool hid_cursor_;
197 DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider);
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_);
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();
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));
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);
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);
249 // Then destroy the children.
250 RemoveOrDestroyChildren();
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);
257 if (delegate_)
258 delegate_->OnWindowDestroyed(this);
259 ObserverListBase<WindowObserver>::Iterator iter(observers_);
260 for (WindowObserver* observer = iter.GetNext(); observer;
261 observer = iter.GetNext()) {
262 RemoveObserver(observer);
263 observer->OnWindowDestroyed(this);
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);
273 prop_map_.clear();
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();
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_);
292 Env::GetInstance()->NotifyWindowInitialized(this);
295 void Window::SetType(ui::wm::WindowType type) {
296 // Cannot change type after the window is initialized.
297 DCHECK(!layer());
298 type_ = type;
301 void Window::SetName(const std::string& name) {
302 name_ = name;
304 if (layer())
305 UpdateLayerName();
308 void Window::SetTitle(const base::string16& title) {
309 title_ = title;
310 FOR_EACH_OBSERVER(WindowObserver,
311 observers_,
312 OnWindowTitleChanged(this));
315 void Window::SetTransparent(bool transparent) {
316 transparent_ = transparent;
317 if (layer())
318 layer()->SetFillsBoundsOpaquely(!transparent_);
321 void Window::SetFillsBoundsCompletely(bool fills_bounds) {
322 if (layer())
323 layer()->SetFillsBoundsCompletely(fills_bounds);
326 Window* Window::GetRootWindow() {
327 return const_cast<Window*>(
328 static_cast<const Window*>(this)->GetRootWindow());
331 const Window* Window::GetRootWindow() const {
332 return IsRootWindow() ? this : parent_ ? parent_->GetRootWindow() : NULL;
335 WindowTreeHost* Window::GetHost() {
336 return const_cast<WindowTreeHost*>(const_cast<const Window*>(this)->
337 GetHost());
340 const WindowTreeHost* Window::GetHost() const {
341 const Window* root_window = GetRootWindow();
342 return root_window ? root_window->host_ : NULL;
345 void Window::Show() {
346 if (layer()) {
347 DCHECK_EQ(visible_, layer()->GetTargetVisibility());
348 // It is not allowed that a window is visible but the layers alpha is fully
349 // transparent since the window would still be considered to be active but
350 // could not be seen.
351 DCHECK(!(visible_ && layer()->GetTargetOpacity() == 0.0f));
353 SetVisible(true);
356 void Window::Hide() {
357 // RootWindow::OnVisibilityChanged will call ReleaseCapture.
358 SetVisible(false);
361 bool Window::IsVisible() const {
362 // Layer visibility can be inconsistent with window visibility, for example
363 // when a Window is hidden, we want this function to return false immediately
364 // after, even though the client may decide to animate the hide effect (and
365 // so the layer will be visible for some time after Hide() is called).
366 for (const Window* window = this; window; window = window->parent()) {
367 if (!window->visible_)
368 return false;
369 if (window->layer())
370 return window->layer()->IsDrawn();
372 return false;
375 gfx::Rect Window::GetBoundsInRootWindow() const {
376 // TODO(beng): There may be a better way to handle this, and the existing code
377 // is likely wrong anyway in a multi-display world, but this will
378 // do for now.
379 if (!GetRootWindow())
380 return bounds();
381 gfx::Point origin = bounds().origin();
382 ConvertPointToTarget(parent_, GetRootWindow(), &origin);
383 return gfx::Rect(origin, bounds().size());
386 gfx::Rect Window::GetBoundsInScreen() const {
387 gfx::Rect bounds(GetBoundsInRootWindow());
388 const Window* root = GetRootWindow();
389 if (root) {
390 aura::client::ScreenPositionClient* screen_position_client =
391 aura::client::GetScreenPositionClient(root);
392 if (screen_position_client) {
393 gfx::Point origin = bounds.origin();
394 screen_position_client->ConvertPointToScreen(root, &origin);
395 bounds.set_origin(origin);
398 return bounds;
401 void Window::SetTransform(const gfx::Transform& transform) {
402 if (!layer()) {
403 // Transforms aren't supported on layerless windows.
404 NOTREACHED();
405 return;
407 FOR_EACH_OBSERVER(WindowObserver, observers_,
408 OnWindowTransforming(this));
409 layer()->SetTransform(transform);
410 FOR_EACH_OBSERVER(WindowObserver, observers_,
411 OnWindowTransformed(this));
412 NotifyAncestorWindowTransformed(this);
415 void Window::SetLayoutManager(LayoutManager* layout_manager) {
416 if (layout_manager == layout_manager_)
417 return;
418 layout_manager_.reset(layout_manager);
419 if (!layout_manager)
420 return;
421 // If we're changing to a new layout manager, ensure it is aware of all the
422 // existing child windows.
423 for (Windows::const_iterator it = children_.begin();
424 it != children_.end();
425 ++it)
426 layout_manager_->OnWindowAddedToLayout(*it);
429 scoped_ptr<ui::EventTargeter>
430 Window::SetEventTargeter(scoped_ptr<ui::EventTargeter> targeter) {
431 scoped_ptr<ui::EventTargeter> old_targeter = targeter_.Pass();
432 targeter_ = targeter.Pass();
433 return old_targeter.Pass();
436 void Window::SetBounds(const gfx::Rect& new_bounds) {
437 if (parent_ && parent_->layout_manager())
438 parent_->layout_manager()->SetChildBounds(this, new_bounds);
439 else {
440 // Ensure we don't go smaller than our minimum bounds.
441 gfx::Rect final_bounds(new_bounds);
442 if (delegate_) {
443 const gfx::Size& min_size = delegate_->GetMinimumSize();
444 final_bounds.set_width(std::max(min_size.width(), final_bounds.width()));
445 final_bounds.set_height(std::max(min_size.height(),
446 final_bounds.height()));
448 SetBoundsInternal(final_bounds);
452 void Window::SetBoundsInScreen(const gfx::Rect& new_bounds_in_screen,
453 const gfx::Display& dst_display) {
454 Window* root = GetRootWindow();
455 if (root) {
456 gfx::Point origin = new_bounds_in_screen.origin();
457 aura::client::ScreenPositionClient* screen_position_client =
458 aura::client::GetScreenPositionClient(root);
459 screen_position_client->SetBounds(this, new_bounds_in_screen, dst_display);
460 return;
462 SetBounds(new_bounds_in_screen);
465 gfx::Rect Window::GetTargetBounds() const {
466 if (!layer())
467 return bounds();
469 if (!parent_ || parent_->layer())
470 return layer()->GetTargetBounds();
472 // We have a layer but our parent (who is valid) doesn't. This means the
473 // coordinates of the layer are relative to the first ancestor with a layer;
474 // convert to be relative to parent.
475 gfx::Vector2d offset;
476 const aura::Window* ancestor_with_layer =
477 parent_->GetAncestorWithLayer(&offset);
478 if (!ancestor_with_layer)
479 return layer()->GetTargetBounds();
481 gfx::Rect layer_target_bounds = layer()->GetTargetBounds();
482 layer_target_bounds -= offset;
483 return layer_target_bounds;
486 void Window::SchedulePaintInRect(const gfx::Rect& rect) {
487 if (!layer() && parent_) {
488 // Notification of paint scheduled happens for the window with a layer.
489 gfx::Rect parent_rect(bounds().size());
490 parent_rect.Intersect(rect);
491 if (!parent_rect.IsEmpty()) {
492 parent_rect.Offset(bounds().origin().OffsetFromOrigin());
493 parent_->SchedulePaintInRect(parent_rect);
495 } else if (layer()) {
496 layer()->SchedulePaint(rect);
500 void Window::StackChildAtTop(Window* child) {
501 if (children_.size() <= 1 || child == children_.back())
502 return; // In the front already.
503 StackChildAbove(child, children_.back());
506 void Window::StackChildAbove(Window* child, Window* target) {
507 StackChildRelativeTo(child, target, STACK_ABOVE);
510 void Window::StackChildAtBottom(Window* child) {
511 if (children_.size() <= 1 || child == children_.front())
512 return; // At the bottom already.
513 StackChildBelow(child, children_.front());
516 void Window::StackChildBelow(Window* child, Window* target) {
517 StackChildRelativeTo(child, target, STACK_BELOW);
520 void Window::AddChild(Window* child) {
521 WindowObserver::HierarchyChangeParams params;
522 params.target = child;
523 params.new_parent = this;
524 params.old_parent = child->parent();
525 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
526 NotifyWindowHierarchyChange(params);
528 Window* old_root = child->GetRootWindow();
530 DCHECK(std::find(children_.begin(), children_.end(), child) ==
531 children_.end());
532 if (child->parent())
533 child->parent()->RemoveChildImpl(child, this);
535 gfx::Vector2d offset;
536 aura::Window* ancestor_with_layer = GetAncestorWithLayer(&offset);
538 child->parent_ = this;
540 if (ancestor_with_layer) {
541 offset += child->bounds().OffsetFromOrigin();
542 child->ReparentLayers(ancestor_with_layer->layer(), offset);
545 children_.push_back(child);
546 if (layout_manager_)
547 layout_manager_->OnWindowAddedToLayout(child);
548 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child));
549 child->OnParentChanged();
551 Window* root_window = GetRootWindow();
552 if (root_window && old_root != root_window) {
553 root_window->GetHost()->dispatcher()->OnWindowAddedToRootWindow(child);
554 child->NotifyAddedToRootWindow();
557 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
558 NotifyWindowHierarchyChange(params);
561 void Window::RemoveChild(Window* child) {
562 WindowObserver::HierarchyChangeParams params;
563 params.target = child;
564 params.new_parent = NULL;
565 params.old_parent = this;
566 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
567 NotifyWindowHierarchyChange(params);
569 RemoveChildImpl(child, NULL);
571 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
572 NotifyWindowHierarchyChange(params);
575 bool Window::Contains(const Window* other) const {
576 for (const Window* parent = other; parent; parent = parent->parent_) {
577 if (parent == this)
578 return true;
580 return false;
583 Window* Window::GetChildById(int id) {
584 return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id));
587 const Window* Window::GetChildById(int id) const {
588 Windows::const_iterator i;
589 for (i = children_.begin(); i != children_.end(); ++i) {
590 if ((*i)->id() == id)
591 return *i;
592 const Window* result = (*i)->GetChildById(id);
593 if (result)
594 return result;
596 return NULL;
599 // static
600 void Window::ConvertPointToTarget(const Window* source,
601 const Window* target,
602 gfx::Point* point) {
603 if (!source)
604 return;
605 if (source->GetRootWindow() != target->GetRootWindow()) {
606 client::ScreenPositionClient* source_client =
607 client::GetScreenPositionClient(source->GetRootWindow());
608 // |source_client| can be NULL in tests.
609 if (source_client)
610 source_client->ConvertPointToScreen(source, point);
612 client::ScreenPositionClient* target_client =
613 client::GetScreenPositionClient(target->GetRootWindow());
614 // |target_client| can be NULL in tests.
615 if (target_client)
616 target_client->ConvertPointFromScreen(target, point);
617 } else if ((source != target) && (!source->layer() || !target->layer())) {
618 if (!source->layer()) {
619 gfx::Vector2d offset_to_layer;
620 source = source->GetAncestorWithLayer(&offset_to_layer);
621 *point += offset_to_layer;
623 if (!target->layer()) {
624 gfx::Vector2d offset_to_layer;
625 target = target->GetAncestorWithLayer(&offset_to_layer);
626 *point -= offset_to_layer;
628 ui::Layer::ConvertPointToLayer(source->layer(), target->layer(), point);
629 } else {
630 ui::Layer::ConvertPointToLayer(source->layer(), target->layer(), point);
634 // static
635 void Window::ConvertRectToTarget(const Window* source,
636 const Window* target,
637 gfx::Rect* rect) {
638 DCHECK(rect);
639 gfx::Point origin = rect->origin();
640 ConvertPointToTarget(source, target, &origin);
641 rect->set_origin(origin);
644 void Window::MoveCursorTo(const gfx::Point& point_in_window) {
645 Window* root_window = GetRootWindow();
646 DCHECK(root_window);
647 gfx::Point point_in_root(point_in_window);
648 ConvertPointToTarget(this, root_window, &point_in_root);
649 root_window->GetHost()->MoveCursorTo(point_in_root);
652 gfx::NativeCursor Window::GetCursor(const gfx::Point& point) const {
653 return delegate_ ? delegate_->GetCursor(point) : gfx::kNullCursor;
656 void Window::AddObserver(WindowObserver* observer) {
657 observer->OnObservingWindow(this);
658 observers_.AddObserver(observer);
661 void Window::RemoveObserver(WindowObserver* observer) {
662 observer->OnUnobservingWindow(this);
663 observers_.RemoveObserver(observer);
666 bool Window::HasObserver(WindowObserver* observer) {
667 return observers_.HasObserver(observer);
670 bool Window::ContainsPointInRoot(const gfx::Point& point_in_root) const {
671 const Window* root_window = GetRootWindow();
672 if (!root_window)
673 return false;
674 gfx::Point local_point(point_in_root);
675 ConvertPointToTarget(root_window, this, &local_point);
676 return gfx::Rect(GetTargetBounds().size()).Contains(local_point);
679 bool Window::ContainsPoint(const gfx::Point& local_point) const {
680 return gfx::Rect(bounds().size()).Contains(local_point);
683 Window* Window::GetEventHandlerForPoint(const gfx::Point& local_point) {
684 return GetWindowForPoint(local_point, true, true);
687 Window* Window::GetTopWindowContainingPoint(const gfx::Point& local_point) {
688 return GetWindowForPoint(local_point, false, false);
691 Window* Window::GetToplevelWindow() {
692 Window* topmost_window_with_delegate = NULL;
693 for (aura::Window* window = this; window != NULL; window = window->parent()) {
694 if (window->delegate())
695 topmost_window_with_delegate = window;
697 return topmost_window_with_delegate;
700 void Window::Focus() {
701 client::FocusClient* client = client::GetFocusClient(this);
702 DCHECK(client);
703 client->FocusWindow(this);
706 void Window::Blur() {
707 client::FocusClient* client = client::GetFocusClient(this);
708 DCHECK(client);
709 client->FocusWindow(NULL);
712 bool Window::HasFocus() const {
713 client::FocusClient* client = client::GetFocusClient(this);
714 return client && client->GetFocusedWindow() == this;
717 bool Window::CanFocus() const {
718 if (IsRootWindow())
719 return IsVisible();
721 // NOTE: as part of focusing the window the ActivationClient may make the
722 // window visible (by way of making a hidden ancestor visible). For this
723 // reason we can't check visibility here and assume the client is doing it.
724 if (!parent_ || (delegate_ && !delegate_->CanFocus()))
725 return false;
727 // The client may forbid certain windows from receiving focus at a given point
728 // in time.
729 client::EventClient* client = client::GetEventClient(GetRootWindow());
730 if (client && !client->CanProcessEventsWithinSubtree(this))
731 return false;
733 return parent_->CanFocus();
736 bool Window::CanReceiveEvents() const {
737 if (IsRootWindow())
738 return IsVisible();
740 // The client may forbid certain windows from receiving events at a given
741 // point in time.
742 client::EventClient* client = client::GetEventClient(GetRootWindow());
743 if (client && !client->CanProcessEventsWithinSubtree(this))
744 return false;
746 return parent_ && IsVisible() && parent_->CanReceiveEvents();
749 void Window::SetCapture() {
750 if (!IsVisible())
751 return;
753 Window* root_window = GetRootWindow();
754 if (!root_window)
755 return;
756 client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
757 if (!capture_client)
758 return;
759 client::GetCaptureClient(root_window)->SetCapture(this);
762 void Window::ReleaseCapture() {
763 Window* root_window = GetRootWindow();
764 if (!root_window)
765 return;
766 client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
767 if (!capture_client)
768 return;
769 client::GetCaptureClient(root_window)->ReleaseCapture(this);
772 bool Window::HasCapture() {
773 Window* root_window = GetRootWindow();
774 if (!root_window)
775 return false;
776 client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
777 return capture_client && capture_client->GetCaptureWindow() == this;
780 void Window::SuppressPaint() {
781 if (layer())
782 layer()->SuppressPaint();
785 // {Set,Get,Clear}Property are implemented in window_property.h.
787 void Window::SetNativeWindowProperty(const char* key, void* value) {
788 SetPropertyInternal(
789 key, key, NULL, reinterpret_cast<int64>(value), 0);
792 void* Window::GetNativeWindowProperty(const char* key) const {
793 return reinterpret_cast<void*>(GetPropertyInternal(key, 0));
796 void Window::OnDeviceScaleFactorChanged(float device_scale_factor) {
797 ScopedCursorHider hider(this);
798 if (delegate_)
799 delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
802 #if !defined(NDEBUG)
803 std::string Window::GetDebugInfo() const {
804 return base::StringPrintf(
805 "%s<%d> bounds(%d, %d, %d, %d) %s %s opacity=%.1f",
806 name().empty() ? "Unknown" : name().c_str(), id(),
807 bounds().x(), bounds().y(), bounds().width(), bounds().height(),
808 visible_ ? "WindowVisible" : "WindowHidden",
809 layer() ?
810 (layer()->GetTargetVisibility() ? "LayerVisible" : "LayerHidden") :
811 "NoLayer",
812 layer() ? layer()->opacity() : 1.0f);
815 void Window::PrintWindowHierarchy(int depth) const {
816 VLOG(0) << base::StringPrintf(
817 "%*s%s", depth * 2, "", GetDebugInfo().c_str());
818 for (Windows::const_iterator it = children_.begin();
819 it != children_.end(); ++it) {
820 Window* child = *it;
821 child->PrintWindowHierarchy(depth + 1);
824 #endif
826 void Window::RemoveOrDestroyChildren() {
827 while (!children_.empty()) {
828 Window* child = children_[0];
829 if (child->owned_by_parent_) {
830 delete child;
831 // Deleting the child so remove it from out children_ list.
832 DCHECK(std::find(children_.begin(), children_.end(), child) ==
833 children_.end());
834 } else {
835 // Even if we can't delete the child, we still need to remove it from the
836 // parent so that relevant bookkeeping (parent_ back-pointers etc) are
837 // updated.
838 RemoveChild(child);
843 ///////////////////////////////////////////////////////////////////////////////
844 // Window, private:
846 int64 Window::SetPropertyInternal(const void* key,
847 const char* name,
848 PropertyDeallocator deallocator,
849 int64 value,
850 int64 default_value) {
851 int64 old = GetPropertyInternal(key, default_value);
852 if (value == default_value) {
853 prop_map_.erase(key);
854 } else {
855 Value prop_value;
856 prop_value.name = name;
857 prop_value.value = value;
858 prop_value.deallocator = deallocator;
859 prop_map_[key] = prop_value;
861 FOR_EACH_OBSERVER(WindowObserver, observers_,
862 OnWindowPropertyChanged(this, key, old));
863 return old;
866 int64 Window::GetPropertyInternal(const void* key,
867 int64 default_value) const {
868 std::map<const void*, Value>::const_iterator iter = prop_map_.find(key);
869 if (iter == prop_map_.end())
870 return default_value;
871 return iter->second.value;
874 bool Window::HitTest(const gfx::Point& local_point) {
875 gfx::Rect local_bounds(bounds().size());
876 if (!delegate_ || !delegate_->HasHitTestMask())
877 return local_bounds.Contains(local_point);
879 gfx::Path mask;
880 delegate_->GetHitTestMask(&mask);
882 SkRegion clip_region;
883 clip_region.setRect(local_bounds.x(), local_bounds.y(),
884 local_bounds.width(), local_bounds.height());
885 SkRegion mask_region;
886 return mask_region.setPath(mask, clip_region) &&
887 mask_region.contains(local_point.x(), local_point.y());
890 void Window::SetBoundsInternal(const gfx::Rect& new_bounds) {
891 gfx::Rect actual_new_bounds(new_bounds);
892 gfx::Rect old_bounds = GetTargetBounds();
894 // Always need to set the layer's bounds -- even if it is to the same thing.
895 // This may cause important side effects such as stopping animation.
896 if (!layer()) {
897 const gfx::Vector2d origin_delta = new_bounds.OffsetFromOrigin() -
898 bounds_.OffsetFromOrigin();
899 bounds_ = new_bounds;
900 OffsetLayerBounds(origin_delta);
901 } else {
902 if (parent_ && !parent_->layer()) {
903 gfx::Vector2d offset;
904 const aura::Window* ancestor_with_layer =
905 parent_->GetAncestorWithLayer(&offset);
906 if (ancestor_with_layer)
907 actual_new_bounds.Offset(offset);
909 layer()->SetBounds(actual_new_bounds);
912 // If we are currently not the layer's delegate, we will not get bounds
913 // changed notification from the layer (this typically happens after animating
914 // hidden). We must notify ourselves.
915 if (!layer() || layer()->delegate() != this)
916 OnWindowBoundsChanged(old_bounds);
919 void Window::SetVisible(bool visible) {
920 if ((layer() && visible == layer()->GetTargetVisibility()) ||
921 (!layer() && visible == visible_))
922 return; // No change.
924 FOR_EACH_OBSERVER(WindowObserver, observers_,
925 OnWindowVisibilityChanging(this, visible));
927 client::VisibilityClient* visibility_client =
928 client::GetVisibilityClient(this);
929 if (visibility_client)
930 visibility_client->UpdateLayerVisibility(this, visible);
931 else if (layer())
932 layer()->SetVisible(visible);
933 visible_ = visible;
934 SchedulePaint();
935 if (parent_ && parent_->layout_manager_)
936 parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible);
938 if (delegate_)
939 delegate_->OnWindowTargetVisibilityChanged(visible);
941 NotifyWindowVisibilityChanged(this, visible);
944 void Window::SchedulePaint() {
945 SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height()));
948 void Window::Paint(gfx::Canvas* canvas) {
949 if (delegate_)
950 delegate_->OnPaint(canvas);
951 PaintLayerlessChildren(canvas);
954 void Window::PaintLayerlessChildren(gfx::Canvas* canvas) {
955 for (size_t i = 0, count = children_.size(); i < count; ++i) {
956 Window* child = children_[i];
957 if (!child->layer() && child->visible_) {
958 gfx::ScopedCanvas scoped_canvas(canvas);
959 canvas->ClipRect(child->bounds());
960 if (!canvas->IsClipEmpty()) {
961 canvas->Translate(child->bounds().OffsetFromOrigin());
962 child->Paint(canvas);
968 Window* Window::GetWindowForPoint(const gfx::Point& local_point,
969 bool return_tightest,
970 bool for_event_handling) {
971 if (!IsVisible())
972 return NULL;
974 if ((for_event_handling && !HitTest(local_point)) ||
975 (!for_event_handling && !ContainsPoint(local_point)))
976 return NULL;
978 // Check if I should claim this event and not pass it to my children because
979 // the location is inside my hit test override area. For details, see
980 // set_hit_test_bounds_override_inner().
981 if (for_event_handling && !hit_test_bounds_override_inner_.empty()) {
982 gfx::Rect inset_local_bounds(gfx::Point(), bounds().size());
983 inset_local_bounds.Inset(hit_test_bounds_override_inner_);
984 // We know we're inside the normal local bounds, so if we're outside the
985 // inset bounds we must be in the special hit test override area.
986 DCHECK(HitTest(local_point));
987 if (!inset_local_bounds.Contains(local_point))
988 return delegate_ ? this : NULL;
991 if (!return_tightest && delegate_)
992 return this;
994 for (Windows::const_reverse_iterator it = children_.rbegin(),
995 rend = children_.rend();
996 it != rend; ++it) {
997 Window* child = *it;
999 if (for_event_handling) {
1000 if (child->ignore_events_)
1001 continue;
1002 // The client may not allow events to be processed by certain subtrees.
1003 client::EventClient* client = client::GetEventClient(GetRootWindow());
1004 if (client && !client->CanProcessEventsWithinSubtree(child))
1005 continue;
1006 if (delegate_ && !delegate_->ShouldDescendIntoChildForEventHandling(
1007 child, local_point))
1008 continue;
1011 gfx::Point point_in_child_coords(local_point);
1012 ConvertPointToTarget(this, child, &point_in_child_coords);
1013 Window* match = child->GetWindowForPoint(point_in_child_coords,
1014 return_tightest,
1015 for_event_handling);
1016 if (match)
1017 return match;
1020 return delegate_ ? this : NULL;
1023 void Window::RemoveChildImpl(Window* child, Window* new_parent) {
1024 if (layout_manager_)
1025 layout_manager_->OnWillRemoveWindowFromLayout(child);
1026 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child));
1027 Window* root_window = child->GetRootWindow();
1028 Window* new_root_window = new_parent ? new_parent->GetRootWindow() : NULL;
1029 if (root_window && root_window != new_root_window)
1030 child->NotifyRemovingFromRootWindow(new_root_window);
1032 gfx::Vector2d offset;
1033 GetAncestorWithLayer(&offset);
1034 child->UnparentLayers(!layer(), offset);
1035 child->parent_ = NULL;
1036 Windows::iterator i = std::find(children_.begin(), children_.end(), child);
1037 DCHECK(i != children_.end());
1038 children_.erase(i);
1039 child->OnParentChanged();
1040 if (layout_manager_)
1041 layout_manager_->OnWindowRemovedFromLayout(child);
1044 void Window::UnparentLayers(bool has_layerless_ancestor,
1045 const gfx::Vector2d& offset) {
1046 if (!layer()) {
1047 const gfx::Vector2d new_offset = offset + bounds().OffsetFromOrigin();
1048 for (size_t i = 0; i < children_.size(); ++i) {
1049 children_[i]->UnparentLayers(true, new_offset);
1051 } else {
1052 // Only remove the layer if we still own it. Someone else may have acquired
1053 // ownership of it via AcquireLayer() and may expect the hierarchy to go
1054 // unchanged as the Window is destroyed.
1055 if (OwnsLayer()) {
1056 if (layer()->parent())
1057 layer()->parent()->Remove(layer());
1058 if (has_layerless_ancestor) {
1059 const gfx::Rect real_bounds(bounds_);
1060 gfx::Rect layer_bounds(layer()->bounds());
1061 layer_bounds.Offset(-offset);
1062 layer()->SetBounds(layer_bounds);
1063 bounds_ = real_bounds;
1069 void Window::ReparentLayers(ui::Layer* parent_layer,
1070 const gfx::Vector2d& offset) {
1071 if (!layer()) {
1072 for (size_t i = 0; i < children_.size(); ++i) {
1073 children_[i]->ReparentLayers(
1074 parent_layer,
1075 offset + children_[i]->bounds().OffsetFromOrigin());
1077 } else {
1078 const gfx::Rect real_bounds(bounds());
1079 parent_layer->Add(layer());
1080 gfx::Rect layer_bounds(layer()->bounds().size());
1081 layer_bounds += offset;
1082 layer()->SetBounds(layer_bounds);
1083 bounds_ = real_bounds;
1087 void Window::OffsetLayerBounds(const gfx::Vector2d& offset) {
1088 if (!layer()) {
1089 for (size_t i = 0; i < children_.size(); ++i)
1090 children_[i]->OffsetLayerBounds(offset);
1091 } else {
1092 gfx::Rect layer_bounds(layer()->bounds());
1093 layer_bounds += offset;
1094 layer()->SetBounds(layer_bounds);
1098 void Window::OnParentChanged() {
1099 FOR_EACH_OBSERVER(
1100 WindowObserver, observers_, OnWindowParentChanged(this, parent_));
1103 void Window::StackChildRelativeTo(Window* child,
1104 Window* target,
1105 StackDirection direction) {
1106 DCHECK_NE(child, target);
1107 DCHECK(child);
1108 DCHECK(target);
1109 DCHECK_EQ(this, child->parent());
1110 DCHECK_EQ(this, target->parent());
1112 client::WindowStackingClient* stacking_client =
1113 client::GetWindowStackingClient();
1114 if (stacking_client &&
1115 !stacking_client->AdjustStacking(&child, &target, &direction))
1116 return;
1118 const size_t child_i =
1119 std::find(children_.begin(), children_.end(), child) - children_.begin();
1120 const size_t target_i =
1121 std::find(children_.begin(), children_.end(), target) - children_.begin();
1123 // Don't move the child if it is already in the right place.
1124 if ((direction == STACK_ABOVE && child_i == target_i + 1) ||
1125 (direction == STACK_BELOW && child_i + 1 == target_i))
1126 return;
1128 const size_t dest_i =
1129 direction == STACK_ABOVE ?
1130 (child_i < target_i ? target_i : target_i + 1) :
1131 (child_i < target_i ? target_i - 1 : target_i);
1132 children_.erase(children_.begin() + child_i);
1133 children_.insert(children_.begin() + dest_i, child);
1135 StackChildLayerRelativeTo(child, target, direction);
1137 child->OnStackingChanged();
1140 void Window::StackChildLayerRelativeTo(Window* child,
1141 Window* target,
1142 StackDirection direction) {
1143 Window* ancestor_with_layer = GetAncestorWithLayer(NULL);
1144 ui::Layer* ancestor_layer =
1145 ancestor_with_layer ? ancestor_with_layer->layer() : NULL;
1146 if (!ancestor_layer)
1147 return;
1149 if (child->layer() && target->layer()) {
1150 if (direction == STACK_ABOVE)
1151 ancestor_layer->StackAbove(child->layer(), target->layer());
1152 else
1153 ancestor_layer->StackBelow(child->layer(), target->layer());
1154 return;
1156 typedef std::vector<ui::Layer*> Layers;
1157 Layers layers;
1158 GetLayersToStack(child, &layers);
1159 if (layers.empty())
1160 return;
1162 ui::Layer* target_layer;
1163 if (direction == STACK_ABOVE) {
1164 target_layer =
1165 FindStackingTargetLayer<Windows::const_reverse_iterator>(target, child);
1166 } else {
1167 target_layer =
1168 FindStackingTargetLayer<Windows::const_iterator>(target, child);
1171 if (!target_layer) {
1172 if (direction == STACK_ABOVE) {
1173 for (Layers::const_reverse_iterator i = layers.rbegin(),
1174 rend = layers.rend(); i != rend; ++i) {
1175 ancestor_layer->StackAtBottom(*i);
1177 } else {
1178 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1179 ancestor_layer->StackAtTop(*i);
1181 return;
1184 if (direction == STACK_ABOVE) {
1185 for (Layers::const_reverse_iterator i = layers.rbegin(),
1186 rend = layers.rend(); i != rend; ++i) {
1187 ancestor_layer->StackAbove(*i, target_layer);
1189 } else {
1190 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1191 ancestor_layer->StackBelow(*i, target_layer);
1195 void Window::OnStackingChanged() {
1196 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowStackingChanged(this));
1199 void Window::NotifyRemovingFromRootWindow(Window* new_root) {
1200 FOR_EACH_OBSERVER(WindowObserver, observers_,
1201 OnWindowRemovingFromRootWindow(this, new_root));
1202 for (Window::Windows::const_iterator it = children_.begin();
1203 it != children_.end(); ++it) {
1204 (*it)->NotifyRemovingFromRootWindow(new_root);
1208 void Window::NotifyAddedToRootWindow() {
1209 FOR_EACH_OBSERVER(WindowObserver, observers_,
1210 OnWindowAddedToRootWindow(this));
1211 for (Window::Windows::const_iterator it = children_.begin();
1212 it != children_.end(); ++it) {
1213 (*it)->NotifyAddedToRootWindow();
1217 void Window::NotifyWindowHierarchyChange(
1218 const WindowObserver::HierarchyChangeParams& params) {
1219 params.target->NotifyWindowHierarchyChangeDown(params);
1220 switch (params.phase) {
1221 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1222 if (params.old_parent)
1223 params.old_parent->NotifyWindowHierarchyChangeUp(params);
1224 break;
1225 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1226 if (params.new_parent)
1227 params.new_parent->NotifyWindowHierarchyChangeUp(params);
1228 break;
1229 default:
1230 NOTREACHED();
1231 break;
1235 void Window::NotifyWindowHierarchyChangeDown(
1236 const WindowObserver::HierarchyChangeParams& params) {
1237 NotifyWindowHierarchyChangeAtReceiver(params);
1238 for (Window::Windows::const_iterator it = children_.begin();
1239 it != children_.end(); ++it) {
1240 (*it)->NotifyWindowHierarchyChangeDown(params);
1244 void Window::NotifyWindowHierarchyChangeUp(
1245 const WindowObserver::HierarchyChangeParams& params) {
1246 for (Window* window = this; window; window = window->parent())
1247 window->NotifyWindowHierarchyChangeAtReceiver(params);
1250 void Window::NotifyWindowHierarchyChangeAtReceiver(
1251 const WindowObserver::HierarchyChangeParams& params) {
1252 WindowObserver::HierarchyChangeParams local_params = params;
1253 local_params.receiver = this;
1255 switch (params.phase) {
1256 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1257 FOR_EACH_OBSERVER(WindowObserver, observers_,
1258 OnWindowHierarchyChanging(local_params));
1259 break;
1260 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1261 FOR_EACH_OBSERVER(WindowObserver, observers_,
1262 OnWindowHierarchyChanged(local_params));
1263 break;
1264 default:
1265 NOTREACHED();
1266 break;
1270 void Window::NotifyWindowVisibilityChanged(aura::Window* target,
1271 bool visible) {
1272 if (!NotifyWindowVisibilityChangedDown(target, visible)) {
1273 return; // |this| has been deleted.
1275 NotifyWindowVisibilityChangedUp(target, visible);
1278 bool Window::NotifyWindowVisibilityChangedAtReceiver(aura::Window* target,
1279 bool visible) {
1280 // |this| may be deleted during a call to OnWindowVisibilityChanged() on one
1281 // of the observers. We create an local observer for that. In that case we
1282 // exit without further access to any members.
1283 WindowTracker tracker;
1284 tracker.Add(this);
1285 FOR_EACH_OBSERVER(WindowObserver, observers_,
1286 OnWindowVisibilityChanged(target, visible));
1287 return tracker.Contains(this);
1290 bool Window::NotifyWindowVisibilityChangedDown(aura::Window* target,
1291 bool visible) {
1292 if (!NotifyWindowVisibilityChangedAtReceiver(target, visible))
1293 return false; // |this| was deleted.
1294 std::set<const Window*> child_already_processed;
1295 bool child_destroyed = false;
1296 do {
1297 child_destroyed = false;
1298 for (Window::Windows::const_iterator it = children_.begin();
1299 it != children_.end(); ++it) {
1300 if (!child_already_processed.insert(*it).second)
1301 continue;
1302 if (!(*it)->NotifyWindowVisibilityChangedDown(target, visible)) {
1303 // |*it| was deleted, |it| is invalid and |children_| has changed.
1304 // We exit the current for-loop and enter a new one.
1305 child_destroyed = true;
1306 break;
1309 } while (child_destroyed);
1310 return true;
1313 void Window::NotifyWindowVisibilityChangedUp(aura::Window* target,
1314 bool visible) {
1315 for (Window* window = this; window; window = window->parent()) {
1316 bool ret = window->NotifyWindowVisibilityChangedAtReceiver(target, visible);
1317 DCHECK(ret);
1321 void Window::NotifyAncestorWindowTransformed(Window* source) {
1322 FOR_EACH_OBSERVER(WindowObserver, observers_,
1323 OnAncestorWindowTransformed(source, this));
1324 for (Window::Windows::const_iterator it = children_.begin();
1325 it != children_.end(); ++it) {
1326 (*it)->NotifyAncestorWindowTransformed(source);
1330 void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds) {
1331 if (layer()) {
1332 bounds_ = layer()->bounds();
1333 if (parent_ && !parent_->layer()) {
1334 gfx::Vector2d offset;
1335 aura::Window* ancestor_with_layer =
1336 parent_->GetAncestorWithLayer(&offset);
1337 if (ancestor_with_layer)
1338 bounds_.Offset(-offset);
1342 if (layout_manager_)
1343 layout_manager_->OnWindowResized();
1344 if (delegate_)
1345 delegate_->OnBoundsChanged(old_bounds, bounds());
1346 FOR_EACH_OBSERVER(WindowObserver,
1347 observers_,
1348 OnWindowBoundsChanged(this, old_bounds, bounds()));
1351 bool Window::CleanupGestureState() {
1352 bool state_modified = false;
1353 state_modified |= ui::GestureRecognizer::Get()->CancelActiveTouches(this);
1354 state_modified |=
1355 ui::GestureRecognizer::Get()->CleanupStateForConsumer(this);
1356 for (Window::Windows::iterator iter = children_.begin();
1357 iter != children_.end();
1358 ++iter) {
1359 state_modified |= (*iter)->CleanupGestureState();
1361 return state_modified;
1364 void Window::OnPaintLayer(gfx::Canvas* canvas) {
1365 Paint(canvas);
1368 void Window::OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) {
1369 DCHECK(layer());
1370 FOR_EACH_OBSERVER(WindowObserver,
1371 observers_,
1372 OnDelegatedFrameDamage(this, damage_rect_in_dip));
1375 base::Closure Window::PrepareForLayerBoundsChange() {
1376 return base::Bind(&Window::OnWindowBoundsChanged, base::Unretained(this),
1377 bounds());
1380 bool Window::CanAcceptEvent(const ui::Event& event) {
1381 // The client may forbid certain windows from receiving events at a given
1382 // point in time.
1383 client::EventClient* client = client::GetEventClient(GetRootWindow());
1384 if (client && !client->CanProcessEventsWithinSubtree(this))
1385 return false;
1387 // We need to make sure that a touch cancel event and any gesture events it
1388 // creates can always reach the window. This ensures that we receive a valid
1389 // touch / gesture stream.
1390 if (event.IsEndingEvent())
1391 return true;
1393 if (!IsVisible())
1394 return false;
1396 // The top-most window can always process an event.
1397 if (!parent_)
1398 return true;
1400 // For located events (i.e. mouse, touch etc.), an assumption is made that
1401 // windows that don't have a default event-handler cannot process the event
1402 // (see more in GetWindowForPoint()). This assumption is not made for key
1403 // events.
1404 return event.IsKeyEvent() || target_handler();
1407 ui::EventTarget* Window::GetParentTarget() {
1408 if (IsRootWindow()) {
1409 return client::GetEventClient(this) ?
1410 client::GetEventClient(this)->GetToplevelEventTarget() :
1411 Env::GetInstance();
1413 return parent_;
1416 scoped_ptr<ui::EventTargetIterator> Window::GetChildIterator() const {
1417 return scoped_ptr<ui::EventTargetIterator>(
1418 new ui::EventTargetIteratorImpl<Window>(children()));
1421 ui::EventTargeter* Window::GetEventTargeter() {
1422 return targeter_.get();
1425 void Window::ConvertEventToTarget(ui::EventTarget* target,
1426 ui::LocatedEvent* event) {
1427 event->ConvertLocationToTarget(this,
1428 static_cast<Window*>(target));
1431 void Window::UpdateLayerName() {
1432 #if !defined(NDEBUG)
1433 DCHECK(layer());
1435 std::string layer_name(name_);
1436 if (layer_name.empty())
1437 layer_name = "Unnamed Window";
1439 if (id_ != -1)
1440 layer_name += " " + base::IntToString(id_);
1442 layer()->set_name(layer_name);
1443 #endif
1446 bool Window::ContainsMouse() {
1447 bool contains_mouse = false;
1448 if (IsVisible()) {
1449 WindowTreeHost* host = GetHost();
1450 contains_mouse = host &&
1451 ContainsPointInRoot(host->dispatcher()->GetLastMouseLocationInRoot());
1453 return contains_mouse;
1456 const Window* Window::GetAncestorWithLayer(gfx::Vector2d* offset) const {
1457 for (const aura::Window* window = this; window; window = window->parent()) {
1458 if (window->layer())
1459 return window;
1460 if (offset)
1461 *offset += window->bounds().OffsetFromOrigin();
1463 if (offset)
1464 *offset = gfx::Vector2d();
1465 return NULL;
1468 } // namespace aura