Remove unused parameter.
[chromium-blink-merge.git] / ui / aura / window.cc
blob6327dabe0721cb2043bf28d6ba3235f4b9a7ac35
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/profiler/scoped_tracker.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/stringprintf.h"
17 #include "ui/aura/client/capture_client.h"
18 #include "ui/aura/client/cursor_client.h"
19 #include "ui/aura/client/event_client.h"
20 #include "ui/aura/client/focus_client.h"
21 #include "ui/aura/client/screen_position_client.h"
22 #include "ui/aura/client/visibility_client.h"
23 #include "ui/aura/client/window_stacking_client.h"
24 #include "ui/aura/env.h"
25 #include "ui/aura/layout_manager.h"
26 #include "ui/aura/window_delegate.h"
27 #include "ui/aura/window_event_dispatcher.h"
28 #include "ui/aura/window_observer.h"
29 #include "ui/aura/window_tracker.h"
30 #include "ui/aura/window_tree_host.h"
31 #include "ui/compositor/compositor.h"
32 #include "ui/compositor/layer.h"
33 #include "ui/compositor/paint_context.h"
34 #include "ui/events/event_target_iterator.h"
35 #include "ui/gfx/canvas.h"
36 #include "ui/gfx/path.h"
37 #include "ui/gfx/scoped_canvas.h"
38 #include "ui/gfx/screen.h"
40 namespace aura {
42 namespace {
44 // Used when searching for a Window to stack relative to.
45 template <class T>
46 T IteratorForDirectionBegin(aura::Window* window);
48 template <>
49 Window::Windows::const_iterator IteratorForDirectionBegin(
50 aura::Window* window) {
51 return window->children().begin();
54 template <>
55 Window::Windows::const_reverse_iterator IteratorForDirectionBegin(
56 aura::Window* window) {
57 return window->children().rbegin();
60 template <class T>
61 T IteratorForDirectionEnd(aura::Window* window);
63 template <>
64 Window::Windows::const_iterator IteratorForDirectionEnd(aura::Window* window) {
65 return window->children().end();
68 template <>
69 Window::Windows::const_reverse_iterator IteratorForDirectionEnd(
70 aura::Window* window) {
71 return window->children().rend();
74 // Depth first search for the first Window with a layer to stack relative
75 // to. Starts at target. Does not descend into |ignore|.
76 template <class T>
77 ui::Layer* FindStackingTargetLayerDown(aura::Window* target,
78 aura::Window* ignore) {
79 if (target == ignore)
80 return NULL;
82 if (target->layer())
83 return target->layer();
85 for (T i = IteratorForDirectionBegin<T>(target);
86 i != IteratorForDirectionEnd<T>(target); ++i) {
87 ui::Layer* layer = FindStackingTargetLayerDown<T>(*i, ignore);
88 if (layer)
89 return layer;
91 return NULL;
94 // Depth first search through the siblings of |target||. This does not search
95 // all the siblings, only those before/after |target| (depening upon the
96 // template type) and ignoring |ignore|. Returns the Layer of the first Window
97 // encountered with a Layer.
98 template <class T>
99 ui::Layer* FindStackingLayerInSiblings(aura::Window* target,
100 aura::Window* ignore) {
101 aura::Window* parent = target->parent();
102 for (T i = std::find(IteratorForDirectionBegin<T>(parent),
103 IteratorForDirectionEnd<T>(parent), target);
104 i != IteratorForDirectionEnd<T>(parent); ++i) {
105 ui::Layer* layer = FindStackingTargetLayerDown<T>(*i, ignore);
106 if (layer)
107 return layer;
109 return NULL;
112 // Returns the first Window that has a Layer. This does a depth first search
113 // through the descendants of |target| first, then ascends up doing a depth
114 // first search through siblings of all ancestors until a Layer is found or an
115 // ancestor with a layer is found. This is intended to locate a layer to stack
116 // other layers relative to.
117 template <class T>
118 ui::Layer* FindStackingTargetLayer(aura::Window* target, aura::Window* ignore) {
119 ui::Layer* result = FindStackingTargetLayerDown<T>(target, ignore);
120 if (result)
121 return result;
122 while (target->parent()) {
123 ui::Layer* result = FindStackingLayerInSiblings<T>(target, ignore);
124 if (result)
125 return result;
126 target = target->parent();
127 if (target->layer())
128 return NULL;
130 return NULL;
133 // Does a depth first search for all descendants of |child| that have layers.
134 // This stops at any descendants that have layers (and adds them to |layers|).
135 void GetLayersToStack(aura::Window* child, std::vector<ui::Layer*>* layers) {
136 if (child->layer()) {
137 layers->push_back(child->layer());
138 return;
140 for (size_t i = 0; i < child->children().size(); ++i)
141 GetLayersToStack(child->children()[i], layers);
144 } // namespace
146 class ScopedCursorHider {
147 public:
148 explicit ScopedCursorHider(Window* window)
149 : window_(window),
150 hid_cursor_(false) {
151 if (!window_->IsRootWindow())
152 return;
153 const bool cursor_is_in_bounds = window_->GetBoundsInScreen().Contains(
154 Env::GetInstance()->last_mouse_location());
155 client::CursorClient* cursor_client = client::GetCursorClient(window_);
156 if (cursor_is_in_bounds && cursor_client &&
157 cursor_client->IsCursorVisible()) {
158 cursor_client->HideCursor();
159 hid_cursor_ = true;
162 ~ScopedCursorHider() {
163 if (!window_->IsRootWindow())
164 return;
166 // Update the device scale factor of the cursor client only when the last
167 // mouse location is on this root window.
168 if (hid_cursor_) {
169 client::CursorClient* cursor_client = client::GetCursorClient(window_);
170 if (cursor_client) {
171 const gfx::Display& display =
172 gfx::Screen::GetScreenFor(window_)->GetDisplayNearestWindow(
173 window_);
174 cursor_client->SetDisplay(display);
175 cursor_client->ShowCursor();
180 private:
181 Window* window_;
182 bool hid_cursor_;
184 DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider);
187 Window::Window(WindowDelegate* delegate)
188 : host_(NULL),
189 type_(ui::wm::WINDOW_TYPE_UNKNOWN),
190 owned_by_parent_(true),
191 delegate_(delegate),
192 parent_(NULL),
193 visible_(false),
194 id_(-1),
195 transparent_(false),
196 user_data_(NULL),
197 ignore_events_(false),
198 // Don't notify newly added observers during notification. This causes
199 // problems for code that adds an observer as part of an observer
200 // notification (such as the workspace code).
201 observers_(ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY) {
202 set_target_handler(delegate_);
205 Window::~Window() {
206 if (layer()->owner() == this)
207 layer()->CompleteAllAnimations();
208 layer()->SuppressPaint();
210 // Let the delegate know we're in the processing of destroying.
211 if (delegate_)
212 delegate_->OnWindowDestroying(this);
213 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this));
215 // While we are being destroyed, our target handler may also be in the
216 // process of destruction or already destroyed, so do not forward any
217 // input events at the ui::EP_TARGET phase.
218 set_target_handler(nullptr);
220 // TODO(beng): See comment in window_event_dispatcher.h. This shouldn't be
221 // necessary but unfortunately is right now due to ordering
222 // peculiarities. WED must be notified _after_ other observers
223 // are notified of pending teardown but before the hierarchy
224 // is actually torn down.
225 WindowTreeHost* host = GetHost();
226 if (host)
227 host->dispatcher()->OnPostNotifiedWindowDestroying(this);
229 // The window should have already had its state cleaned up in
230 // WindowEventDispatcher::OnWindowHidden(), but there have been some crashes
231 // involving windows being destroyed without being hidden first. See
232 // crbug.com/342040. This should help us debug the issue. TODO(tdresser):
233 // remove this once we determine why we have windows that are destroyed
234 // without being hidden.
235 bool window_incorrectly_cleaned_up = CleanupGestureState();
236 CHECK(!window_incorrectly_cleaned_up);
238 // Then destroy the children.
239 RemoveOrDestroyChildren();
241 // The window needs to be removed from the parent before calling the
242 // WindowDestroyed callbacks of delegate and the observers.
243 if (parent_)
244 parent_->RemoveChild(this);
246 if (delegate_)
247 delegate_->OnWindowDestroyed(this);
248 ObserverListBase<WindowObserver>::Iterator iter(&observers_);
249 for (WindowObserver* observer = iter.GetNext(); observer;
250 observer = iter.GetNext()) {
251 RemoveObserver(observer);
252 observer->OnWindowDestroyed(this);
255 // Clear properties.
256 for (std::map<const void*, Value>::const_iterator iter = prop_map_.begin();
257 iter != prop_map_.end();
258 ++iter) {
259 if (iter->second.deallocator)
260 (*iter->second.deallocator)(iter->second.value);
262 prop_map_.clear();
264 // The layer will either be destroyed by |layer_owner_|'s dtor, or by whoever
265 // acquired it.
266 layer()->set_delegate(NULL);
267 DestroyLayer();
270 void Window::Init(ui::LayerType layer_type) {
271 SetLayer(new ui::Layer(layer_type));
272 layer()->SetVisible(false);
273 layer()->set_delegate(this);
274 UpdateLayerName();
275 layer()->SetFillsBoundsOpaquely(!transparent_);
276 Env::GetInstance()->NotifyWindowInitialized(this);
279 void Window::SetType(ui::wm::WindowType type) {
280 // Cannot change type after the window is initialized.
281 DCHECK(!layer());
282 type_ = type;
285 void Window::SetName(const std::string& name) {
286 name_ = name;
287 if (layer())
288 UpdateLayerName();
291 void Window::SetTitle(const base::string16& title) {
292 title_ = title;
293 FOR_EACH_OBSERVER(WindowObserver,
294 observers_,
295 OnWindowTitleChanged(this));
298 void Window::SetTransparent(bool transparent) {
299 transparent_ = transparent;
300 if (layer())
301 layer()->SetFillsBoundsOpaquely(!transparent_);
304 void Window::SetFillsBoundsCompletely(bool fills_bounds) {
305 layer()->SetFillsBoundsCompletely(fills_bounds);
308 Window* Window::GetRootWindow() {
309 return const_cast<Window*>(
310 static_cast<const Window*>(this)->GetRootWindow());
313 const Window* Window::GetRootWindow() const {
314 return IsRootWindow() ? this : parent_ ? parent_->GetRootWindow() : NULL;
317 WindowTreeHost* Window::GetHost() {
318 return const_cast<WindowTreeHost*>(const_cast<const Window*>(this)->
319 GetHost());
322 const WindowTreeHost* Window::GetHost() const {
323 const Window* root_window = GetRootWindow();
324 return root_window ? root_window->host_ : NULL;
327 void Window::Show() {
328 DCHECK_EQ(visible_, layer()->GetTargetVisibility());
329 // It is not allowed that a window is visible but the layers alpha is fully
330 // transparent since the window would still be considered to be active but
331 // could not be seen.
332 DCHECK_IMPLIES(visible_, layer()->GetTargetOpacity() > 0.0f);
333 SetVisible(true);
336 void Window::Hide() {
337 // RootWindow::OnVisibilityChanged will call ReleaseCapture.
338 SetVisible(false);
341 bool Window::IsVisible() const {
342 // Layer visibility can be inconsistent with window visibility, for example
343 // when a Window is hidden, we want this function to return false immediately
344 // after, even though the client may decide to animate the hide effect (and
345 // so the layer will be visible for some time after Hide() is called).
346 for (const Window* window = this; window; window = window->parent()) {
347 if (!window->visible_)
348 return false;
349 if (window->layer())
350 return window->layer()->IsDrawn();
352 return false;
355 gfx::Rect Window::GetBoundsInRootWindow() const {
356 // TODO(beng): There may be a better way to handle this, and the existing code
357 // is likely wrong anyway in a multi-display world, but this will
358 // do for now.
359 if (!GetRootWindow())
360 return bounds();
361 gfx::Rect bounds_in_root(bounds().size());
362 ConvertRectToTarget(this, GetRootWindow(), &bounds_in_root);
363 return bounds_in_root;
366 gfx::Rect Window::GetBoundsInScreen() const {
367 gfx::Rect bounds(GetBoundsInRootWindow());
368 const Window* root = GetRootWindow();
369 if (root) {
370 aura::client::ScreenPositionClient* screen_position_client =
371 aura::client::GetScreenPositionClient(root);
372 if (screen_position_client) {
373 gfx::Point origin = bounds.origin();
374 screen_position_client->ConvertPointToScreen(root, &origin);
375 bounds.set_origin(origin);
378 return bounds;
381 void Window::SetTransform(const gfx::Transform& transform) {
382 if (!layer()) {
383 // Transforms aren't supported on layerless windows.
384 NOTREACHED();
385 return;
387 FOR_EACH_OBSERVER(WindowObserver, observers_,
388 OnWindowTransforming(this));
389 layer()->SetTransform(transform);
390 FOR_EACH_OBSERVER(WindowObserver, observers_,
391 OnWindowTransformed(this));
392 NotifyAncestorWindowTransformed(this);
395 void Window::SetLayoutManager(LayoutManager* layout_manager) {
396 if (layout_manager == layout_manager_)
397 return;
398 layout_manager_.reset(layout_manager);
399 if (!layout_manager)
400 return;
401 // If we're changing to a new layout manager, ensure it is aware of all the
402 // existing child windows.
403 for (Windows::const_iterator it = children_.begin();
404 it != children_.end();
405 ++it)
406 layout_manager_->OnWindowAddedToLayout(*it);
409 scoped_ptr<ui::EventTargeter>
410 Window::SetEventTargeter(scoped_ptr<ui::EventTargeter> targeter) {
411 scoped_ptr<ui::EventTargeter> old_targeter = targeter_.Pass();
412 targeter_ = targeter.Pass();
413 return old_targeter.Pass();
416 void Window::SetBounds(const gfx::Rect& new_bounds) {
417 if (parent_ && parent_->layout_manager())
418 parent_->layout_manager()->SetChildBounds(this, new_bounds);
419 else {
420 // Ensure we don't go smaller than our minimum bounds.
421 gfx::Rect final_bounds(new_bounds);
422 if (delegate_) {
423 const gfx::Size& min_size = delegate_->GetMinimumSize();
424 final_bounds.set_width(std::max(min_size.width(), final_bounds.width()));
425 final_bounds.set_height(std::max(min_size.height(),
426 final_bounds.height()));
428 SetBoundsInternal(final_bounds);
432 void Window::SetBoundsInScreen(const gfx::Rect& new_bounds_in_screen,
433 const gfx::Display& dst_display) {
434 Window* root = GetRootWindow();
435 if (root) {
436 gfx::Point origin = new_bounds_in_screen.origin();
437 aura::client::ScreenPositionClient* screen_position_client =
438 aura::client::GetScreenPositionClient(root);
439 screen_position_client->SetBounds(this, new_bounds_in_screen, dst_display);
440 return;
442 SetBounds(new_bounds_in_screen);
445 gfx::Rect Window::GetTargetBounds() const {
446 if (!layer())
447 return bounds();
449 if (!parent_ || parent_->layer())
450 return layer()->GetTargetBounds();
452 // We have a layer but our parent (who is valid) doesn't. This means the
453 // coordinates of the layer are relative to the first ancestor with a layer;
454 // convert to be relative to parent.
455 gfx::Vector2d offset;
456 const aura::Window* ancestor_with_layer =
457 parent_->GetAncestorWithLayer(&offset);
458 if (!ancestor_with_layer)
459 return layer()->GetTargetBounds();
461 gfx::Rect layer_target_bounds = layer()->GetTargetBounds();
462 layer_target_bounds -= offset;
463 return layer_target_bounds;
466 void Window::SchedulePaintInRect(const gfx::Rect& rect) {
467 layer()->SchedulePaint(rect);
470 void Window::StackChildAtTop(Window* child) {
471 if (children_.size() <= 1 || child == children_.back())
472 return; // In the front already.
473 StackChildAbove(child, children_.back());
476 void Window::StackChildAbove(Window* child, Window* target) {
477 StackChildRelativeTo(child, target, STACK_ABOVE);
480 void Window::StackChildAtBottom(Window* child) {
481 if (children_.size() <= 1 || child == children_.front())
482 return; // At the bottom already.
483 StackChildBelow(child, children_.front());
486 void Window::StackChildBelow(Window* child, Window* target) {
487 StackChildRelativeTo(child, target, STACK_BELOW);
490 void Window::AddChild(Window* child) {
491 WindowObserver::HierarchyChangeParams params;
492 params.target = child;
493 params.new_parent = this;
494 params.old_parent = child->parent();
495 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
496 NotifyWindowHierarchyChange(params);
498 Window* old_root = child->GetRootWindow();
500 DCHECK(std::find(children_.begin(), children_.end(), child) ==
501 children_.end());
502 if (child->parent())
503 child->parent()->RemoveChildImpl(child, this);
505 gfx::Vector2d offset;
506 aura::Window* ancestor_with_layer = GetAncestorWithLayer(&offset);
508 child->parent_ = this;
510 if (ancestor_with_layer) {
511 offset += child->bounds().OffsetFromOrigin();
512 child->ReparentLayers(ancestor_with_layer->layer(), offset);
515 children_.push_back(child);
516 if (layout_manager_)
517 layout_manager_->OnWindowAddedToLayout(child);
518 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child));
519 child->OnParentChanged();
521 Window* root_window = GetRootWindow();
522 if (root_window && old_root != root_window) {
523 root_window->GetHost()->dispatcher()->OnWindowAddedToRootWindow(child);
524 child->NotifyAddedToRootWindow();
527 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
528 NotifyWindowHierarchyChange(params);
531 void Window::RemoveChild(Window* child) {
532 WindowObserver::HierarchyChangeParams params;
533 params.target = child;
534 params.new_parent = NULL;
535 params.old_parent = this;
536 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
537 NotifyWindowHierarchyChange(params);
539 RemoveChildImpl(child, NULL);
541 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
542 NotifyWindowHierarchyChange(params);
545 bool Window::Contains(const Window* other) const {
546 for (const Window* parent = other; parent; parent = parent->parent_) {
547 if (parent == this)
548 return true;
550 return false;
553 Window* Window::GetChildById(int id) {
554 return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id));
557 const Window* Window::GetChildById(int id) const {
558 Windows::const_iterator i;
559 for (i = children_.begin(); i != children_.end(); ++i) {
560 if ((*i)->id() == id)
561 return *i;
562 const Window* result = (*i)->GetChildById(id);
563 if (result)
564 return result;
566 return NULL;
569 // static
570 void Window::ConvertPointToTarget(const Window* source,
571 const Window* target,
572 gfx::Point* point) {
573 if (!source)
574 return;
575 if (source->GetRootWindow() != target->GetRootWindow()) {
576 client::ScreenPositionClient* source_client =
577 client::GetScreenPositionClient(source->GetRootWindow());
578 // |source_client| can be NULL in tests.
579 if (source_client)
580 source_client->ConvertPointToScreen(source, point);
582 client::ScreenPositionClient* target_client =
583 client::GetScreenPositionClient(target->GetRootWindow());
584 // |target_client| can be NULL in tests.
585 if (target_client)
586 target_client->ConvertPointFromScreen(target, point);
587 } else if ((source != target) && (!source->layer() || !target->layer())) {
588 if (!source->layer()) {
589 gfx::Vector2d offset_to_layer;
590 source = source->GetAncestorWithLayer(&offset_to_layer);
591 *point += offset_to_layer;
593 if (!target->layer()) {
594 gfx::Vector2d offset_to_layer;
595 target = target->GetAncestorWithLayer(&offset_to_layer);
596 *point -= offset_to_layer;
598 ui::Layer::ConvertPointToLayer(source->layer(), target->layer(), point);
599 } else {
600 ui::Layer::ConvertPointToLayer(source->layer(), target->layer(), point);
604 // static
605 void Window::ConvertRectToTarget(const Window* source,
606 const Window* target,
607 gfx::Rect* rect) {
608 DCHECK(rect);
609 gfx::Point origin = rect->origin();
610 ConvertPointToTarget(source, target, &origin);
611 rect->set_origin(origin);
614 ui::TextInputClient* Window::GetFocusedTextInputClient() {
615 return delegate_ ? delegate_->GetFocusedTextInputClient() : nullptr;
618 void Window::MoveCursorTo(const gfx::Point& point_in_window) {
619 Window* root_window = GetRootWindow();
620 DCHECK(root_window);
621 gfx::Point point_in_root(point_in_window);
622 ConvertPointToTarget(this, root_window, &point_in_root);
623 root_window->GetHost()->MoveCursorTo(point_in_root);
626 gfx::NativeCursor Window::GetCursor(const gfx::Point& point) const {
627 return delegate_ ? delegate_->GetCursor(point) : gfx::kNullCursor;
630 void Window::AddObserver(WindowObserver* observer) {
631 observer->OnObservingWindow(this);
632 observers_.AddObserver(observer);
635 void Window::RemoveObserver(WindowObserver* observer) {
636 observer->OnUnobservingWindow(this);
637 observers_.RemoveObserver(observer);
640 bool Window::HasObserver(const WindowObserver* observer) const {
641 return observers_.HasObserver(observer);
644 bool Window::ContainsPointInRoot(const gfx::Point& point_in_root) const {
645 const Window* root_window = GetRootWindow();
646 if (!root_window)
647 return false;
648 gfx::Point local_point(point_in_root);
649 ConvertPointToTarget(root_window, this, &local_point);
650 return gfx::Rect(GetTargetBounds().size()).Contains(local_point);
653 bool Window::ContainsPoint(const gfx::Point& local_point) const {
654 return gfx::Rect(bounds().size()).Contains(local_point);
657 Window* Window::GetEventHandlerForPoint(const gfx::Point& local_point) {
658 return GetWindowForPoint(local_point, true, true);
661 Window* Window::GetTopWindowContainingPoint(const gfx::Point& local_point) {
662 return GetWindowForPoint(local_point, false, false);
665 Window* Window::GetToplevelWindow() {
666 Window* topmost_window_with_delegate = NULL;
667 for (aura::Window* window = this; window != NULL; window = window->parent()) {
668 if (window->delegate())
669 topmost_window_with_delegate = window;
671 return topmost_window_with_delegate;
674 void Window::Focus() {
675 client::FocusClient* client = client::GetFocusClient(this);
676 DCHECK(client);
677 client->FocusWindow(this);
680 void Window::Blur() {
681 client::FocusClient* client = client::GetFocusClient(this);
682 DCHECK(client);
683 client->FocusWindow(NULL);
686 bool Window::HasFocus() const {
687 client::FocusClient* client = client::GetFocusClient(this);
688 return client && client->GetFocusedWindow() == this;
691 bool Window::CanFocus() const {
692 if (IsRootWindow())
693 return IsVisible();
695 // NOTE: as part of focusing the window the ActivationClient may make the
696 // window visible (by way of making a hidden ancestor visible). For this
697 // reason we can't check visibility here and assume the client is doing it.
698 if (!parent_ || (delegate_ && !delegate_->CanFocus()))
699 return false;
701 // The client may forbid certain windows from receiving focus at a given point
702 // in time.
703 client::EventClient* client = client::GetEventClient(GetRootWindow());
704 if (client && !client->CanProcessEventsWithinSubtree(this))
705 return false;
707 return parent_->CanFocus();
710 bool Window::CanReceiveEvents() const {
711 if (IsRootWindow())
712 return IsVisible();
714 // The client may forbid certain windows from receiving events at a given
715 // point in time.
716 client::EventClient* client = client::GetEventClient(GetRootWindow());
717 if (client && !client->CanProcessEventsWithinSubtree(this))
718 return false;
720 return parent_ && IsVisible() && parent_->CanReceiveEvents();
723 void Window::SetCapture() {
724 if (!IsVisible())
725 return;
727 Window* root_window = GetRootWindow();
728 if (!root_window)
729 return;
730 client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
731 if (!capture_client)
732 return;
733 client::GetCaptureClient(root_window)->SetCapture(this);
736 void Window::ReleaseCapture() {
737 Window* root_window = GetRootWindow();
738 if (!root_window)
739 return;
740 client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
741 if (!capture_client)
742 return;
743 client::GetCaptureClient(root_window)->ReleaseCapture(this);
746 bool Window::HasCapture() {
747 Window* root_window = GetRootWindow();
748 if (!root_window)
749 return false;
750 client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
751 return capture_client && capture_client->GetCaptureWindow() == this;
754 void Window::SuppressPaint() {
755 layer()->SuppressPaint();
758 // {Set,Get,Clear}Property are implemented in window_property.h.
760 void Window::SetNativeWindowProperty(const char* key, void* value) {
761 SetPropertyInternal(
762 key, key, NULL, reinterpret_cast<int64>(value), 0);
765 void* Window::GetNativeWindowProperty(const char* key) const {
766 return reinterpret_cast<void*>(GetPropertyInternal(key, 0));
769 void Window::OnDeviceScaleFactorChanged(float device_scale_factor) {
770 ScopedCursorHider hider(this);
771 if (delegate_)
772 delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
775 #if !defined(NDEBUG)
776 std::string Window::GetDebugInfo() const {
777 return base::StringPrintf(
778 "%s<%d> bounds(%d, %d, %d, %d) %s %s opacity=%.1f",
779 name().empty() ? "Unknown" : name().c_str(), id(),
780 bounds().x(), bounds().y(), bounds().width(), bounds().height(),
781 visible_ ? "WindowVisible" : "WindowHidden",
782 layer() ?
783 (layer()->GetTargetVisibility() ? "LayerVisible" : "LayerHidden") :
784 "NoLayer",
785 layer() ? layer()->opacity() : 1.0f);
788 void Window::PrintWindowHierarchy(int depth) const {
789 VLOG(0) << base::StringPrintf(
790 "%*s%s", depth * 2, "", GetDebugInfo().c_str());
791 for (Windows::const_iterator it = children_.begin();
792 it != children_.end(); ++it) {
793 Window* child = *it;
794 child->PrintWindowHierarchy(depth + 1);
797 #endif
799 void Window::RemoveOrDestroyChildren() {
800 while (!children_.empty()) {
801 Window* child = children_[0];
802 if (child->owned_by_parent_) {
803 delete child;
804 // Deleting the child so remove it from out children_ list.
805 DCHECK(std::find(children_.begin(), children_.end(), child) ==
806 children_.end());
807 } else {
808 // Even if we can't delete the child, we still need to remove it from the
809 // parent so that relevant bookkeeping (parent_ back-pointers etc) are
810 // updated.
811 RemoveChild(child);
816 ///////////////////////////////////////////////////////////////////////////////
817 // Window, private:
819 int64 Window::SetPropertyInternal(const void* key,
820 const char* name,
821 PropertyDeallocator deallocator,
822 int64 value,
823 int64 default_value) {
824 int64 old = GetPropertyInternal(key, default_value);
825 if (value == default_value) {
826 prop_map_.erase(key);
827 } else {
828 Value prop_value;
829 prop_value.name = name;
830 prop_value.value = value;
831 prop_value.deallocator = deallocator;
832 prop_map_[key] = prop_value;
834 FOR_EACH_OBSERVER(WindowObserver, observers_,
835 OnWindowPropertyChanged(this, key, old));
836 return old;
839 int64 Window::GetPropertyInternal(const void* key,
840 int64 default_value) const {
841 std::map<const void*, Value>::const_iterator iter = prop_map_.find(key);
842 if (iter == prop_map_.end())
843 return default_value;
844 return iter->second.value;
847 bool Window::HitTest(const gfx::Point& local_point) {
848 gfx::Rect local_bounds(bounds().size());
849 if (!delegate_ || !delegate_->HasHitTestMask())
850 return local_bounds.Contains(local_point);
852 gfx::Path mask;
853 delegate_->GetHitTestMask(&mask);
855 SkRegion clip_region;
856 clip_region.setRect(local_bounds.x(), local_bounds.y(),
857 local_bounds.width(), local_bounds.height());
858 SkRegion mask_region;
859 return mask_region.setPath(mask, clip_region) &&
860 mask_region.contains(local_point.x(), local_point.y());
863 void Window::SetBoundsInternal(const gfx::Rect& new_bounds) {
864 gfx::Rect actual_new_bounds(new_bounds);
865 gfx::Rect old_bounds = GetTargetBounds();
867 // Always need to set the layer's bounds -- even if it is to the same thing.
868 // This may cause important side effects such as stopping animation.
869 if (!layer()) {
870 const gfx::Vector2d origin_delta = new_bounds.OffsetFromOrigin() -
871 bounds_.OffsetFromOrigin();
872 bounds_ = new_bounds;
873 OffsetLayerBounds(origin_delta);
874 } else {
875 if (parent_ && !parent_->layer()) {
876 gfx::Vector2d offset;
877 const aura::Window* ancestor_with_layer =
878 parent_->GetAncestorWithLayer(&offset);
879 if (ancestor_with_layer)
880 actual_new_bounds.Offset(offset);
882 layer()->SetBounds(actual_new_bounds);
885 // If we are currently not the layer's delegate, we will not get bounds
886 // changed notification from the layer (this typically happens after animating
887 // hidden). We must notify ourselves.
888 if (!layer() || layer()->delegate() != this)
889 OnWindowBoundsChanged(old_bounds);
892 void Window::SetVisible(bool visible) {
893 // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed.
894 tracked_objects::ScopedTracker tracking_profile(
895 FROM_HERE_WITH_EXPLICIT_FUNCTION("440919 Window::SetVisible"));
897 if ((layer() && visible == layer()->GetTargetVisibility()) ||
898 (!layer() && visible == visible_))
899 return; // No change.
901 FOR_EACH_OBSERVER(WindowObserver, observers_,
902 OnWindowVisibilityChanging(this, visible));
904 client::VisibilityClient* visibility_client =
905 client::GetVisibilityClient(this);
906 if (visibility_client)
907 visibility_client->UpdateLayerVisibility(this, visible);
908 else
909 layer()->SetVisible(visible);
910 visible_ = visible;
911 SchedulePaint();
912 if (parent_ && parent_->layout_manager_)
913 parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible);
915 if (delegate_)
916 delegate_->OnWindowTargetVisibilityChanged(visible);
918 NotifyWindowVisibilityChanged(this, visible);
921 void Window::SchedulePaint() {
922 SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height()));
925 void Window::Paint(const ui::PaintContext& context) {
926 if (delegate_)
927 delegate_->OnPaint(context);
930 Window* Window::GetWindowForPoint(const gfx::Point& local_point,
931 bool return_tightest,
932 bool for_event_handling) {
933 if (!IsVisible())
934 return NULL;
936 if ((for_event_handling && !HitTest(local_point)) ||
937 (!for_event_handling && !ContainsPoint(local_point)))
938 return NULL;
940 // Check if I should claim this event and not pass it to my children because
941 // the location is inside my hit test override area. For details, see
942 // set_hit_test_bounds_override_inner().
943 if (for_event_handling && !hit_test_bounds_override_inner_.empty()) {
944 gfx::Rect inset_local_bounds(gfx::Point(), bounds().size());
945 inset_local_bounds.Inset(hit_test_bounds_override_inner_);
946 // We know we're inside the normal local bounds, so if we're outside the
947 // inset bounds we must be in the special hit test override area.
948 DCHECK(HitTest(local_point));
949 if (!inset_local_bounds.Contains(local_point))
950 return delegate_ ? this : NULL;
953 if (!return_tightest && delegate_)
954 return this;
956 for (Windows::const_reverse_iterator it = children_.rbegin(),
957 rend = children_.rend();
958 it != rend; ++it) {
959 Window* child = *it;
961 if (for_event_handling) {
962 if (child->ignore_events_)
963 continue;
964 // The client may not allow events to be processed by certain subtrees.
965 client::EventClient* client = client::GetEventClient(GetRootWindow());
966 if (client && !client->CanProcessEventsWithinSubtree(child))
967 continue;
968 if (delegate_ && !delegate_->ShouldDescendIntoChildForEventHandling(
969 child, local_point))
970 continue;
973 gfx::Point point_in_child_coords(local_point);
974 ConvertPointToTarget(this, child, &point_in_child_coords);
975 Window* match = child->GetWindowForPoint(point_in_child_coords,
976 return_tightest,
977 for_event_handling);
978 if (match)
979 return match;
982 return delegate_ ? this : NULL;
985 void Window::RemoveChildImpl(Window* child, Window* new_parent) {
986 if (layout_manager_)
987 layout_manager_->OnWillRemoveWindowFromLayout(child);
988 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child));
989 Window* root_window = child->GetRootWindow();
990 Window* new_root_window = new_parent ? new_parent->GetRootWindow() : NULL;
991 if (root_window && root_window != new_root_window)
992 child->NotifyRemovingFromRootWindow(new_root_window);
994 gfx::Vector2d offset;
995 GetAncestorWithLayer(&offset);
996 child->UnparentLayers(!layer(), offset);
997 child->parent_ = NULL;
998 Windows::iterator i = std::find(children_.begin(), children_.end(), child);
999 DCHECK(i != children_.end());
1000 children_.erase(i);
1001 child->OnParentChanged();
1002 if (layout_manager_)
1003 layout_manager_->OnWindowRemovedFromLayout(child);
1006 void Window::UnparentLayers(bool has_layerless_ancestor,
1007 const gfx::Vector2d& offset) {
1008 if (!layer()) {
1009 const gfx::Vector2d new_offset = offset + bounds().OffsetFromOrigin();
1010 for (size_t i = 0; i < children_.size(); ++i) {
1011 children_[i]->UnparentLayers(true, new_offset);
1013 } else {
1014 // Only remove the layer if we still own it. Someone else may have acquired
1015 // ownership of it via AcquireLayer() and may expect the hierarchy to go
1016 // unchanged as the Window is destroyed.
1017 if (OwnsLayer()) {
1018 if (layer()->parent())
1019 layer()->parent()->Remove(layer());
1020 if (has_layerless_ancestor) {
1021 const gfx::Rect real_bounds(bounds_);
1022 gfx::Rect layer_bounds(layer()->bounds());
1023 layer_bounds.Offset(-offset);
1024 layer()->SetBounds(layer_bounds);
1025 bounds_ = real_bounds;
1031 void Window::ReparentLayers(ui::Layer* parent_layer,
1032 const gfx::Vector2d& offset) {
1033 if (!layer()) {
1034 for (size_t i = 0; i < children_.size(); ++i) {
1035 children_[i]->ReparentLayers(
1036 parent_layer,
1037 offset + children_[i]->bounds().OffsetFromOrigin());
1039 } else {
1040 const gfx::Rect real_bounds(bounds());
1041 parent_layer->Add(layer());
1042 gfx::Rect layer_bounds(layer()->bounds().size());
1043 layer_bounds += offset;
1044 layer()->SetBounds(layer_bounds);
1045 bounds_ = real_bounds;
1049 void Window::OffsetLayerBounds(const gfx::Vector2d& offset) {
1050 if (!layer()) {
1051 for (size_t i = 0; i < children_.size(); ++i)
1052 children_[i]->OffsetLayerBounds(offset);
1053 } else {
1054 gfx::Rect layer_bounds(layer()->bounds());
1055 layer_bounds += offset;
1056 layer()->SetBounds(layer_bounds);
1060 void Window::OnParentChanged() {
1061 FOR_EACH_OBSERVER(
1062 WindowObserver, observers_, OnWindowParentChanged(this, parent_));
1065 void Window::StackChildRelativeTo(Window* child,
1066 Window* target,
1067 StackDirection direction) {
1068 DCHECK_NE(child, target);
1069 DCHECK(child);
1070 DCHECK(target);
1071 DCHECK_EQ(this, child->parent());
1072 DCHECK_EQ(this, target->parent());
1074 client::WindowStackingClient* stacking_client =
1075 client::GetWindowStackingClient();
1076 if (stacking_client &&
1077 !stacking_client->AdjustStacking(&child, &target, &direction))
1078 return;
1080 const size_t child_i =
1081 std::find(children_.begin(), children_.end(), child) - children_.begin();
1082 const size_t target_i =
1083 std::find(children_.begin(), children_.end(), target) - children_.begin();
1085 // Don't move the child if it is already in the right place.
1086 if ((direction == STACK_ABOVE && child_i == target_i + 1) ||
1087 (direction == STACK_BELOW && child_i + 1 == target_i))
1088 return;
1090 const size_t dest_i =
1091 direction == STACK_ABOVE ?
1092 (child_i < target_i ? target_i : target_i + 1) :
1093 (child_i < target_i ? target_i - 1 : target_i);
1094 children_.erase(children_.begin() + child_i);
1095 children_.insert(children_.begin() + dest_i, child);
1097 StackChildLayerRelativeTo(child, target, direction);
1099 child->OnStackingChanged();
1102 void Window::StackChildLayerRelativeTo(Window* child,
1103 Window* target,
1104 StackDirection direction) {
1105 Window* ancestor_with_layer = GetAncestorWithLayer(NULL);
1106 ui::Layer* ancestor_layer =
1107 ancestor_with_layer ? ancestor_with_layer->layer() : NULL;
1108 if (!ancestor_layer)
1109 return;
1111 if (child->layer() && target->layer()) {
1112 if (direction == STACK_ABOVE)
1113 ancestor_layer->StackAbove(child->layer(), target->layer());
1114 else
1115 ancestor_layer->StackBelow(child->layer(), target->layer());
1116 return;
1118 typedef std::vector<ui::Layer*> Layers;
1119 Layers layers;
1120 GetLayersToStack(child, &layers);
1121 if (layers.empty())
1122 return;
1124 ui::Layer* target_layer;
1125 if (direction == STACK_ABOVE) {
1126 target_layer =
1127 FindStackingTargetLayer<Windows::const_reverse_iterator>(target, child);
1128 } else {
1129 target_layer =
1130 FindStackingTargetLayer<Windows::const_iterator>(target, child);
1133 if (!target_layer) {
1134 if (direction == STACK_ABOVE) {
1135 for (Layers::const_reverse_iterator i = layers.rbegin(),
1136 rend = layers.rend(); i != rend; ++i) {
1137 ancestor_layer->StackAtBottom(*i);
1139 } else {
1140 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1141 ancestor_layer->StackAtTop(*i);
1143 return;
1146 if (direction == STACK_ABOVE) {
1147 for (Layers::const_reverse_iterator i = layers.rbegin(),
1148 rend = layers.rend(); i != rend; ++i) {
1149 ancestor_layer->StackAbove(*i, target_layer);
1151 } else {
1152 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1153 ancestor_layer->StackBelow(*i, target_layer);
1157 void Window::OnStackingChanged() {
1158 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowStackingChanged(this));
1161 void Window::NotifyRemovingFromRootWindow(Window* new_root) {
1162 FOR_EACH_OBSERVER(WindowObserver, observers_,
1163 OnWindowRemovingFromRootWindow(this, new_root));
1164 for (Window::Windows::const_iterator it = children_.begin();
1165 it != children_.end(); ++it) {
1166 (*it)->NotifyRemovingFromRootWindow(new_root);
1170 void Window::NotifyAddedToRootWindow() {
1171 FOR_EACH_OBSERVER(WindowObserver, observers_,
1172 OnWindowAddedToRootWindow(this));
1173 for (Window::Windows::const_iterator it = children_.begin();
1174 it != children_.end(); ++it) {
1175 (*it)->NotifyAddedToRootWindow();
1179 void Window::NotifyWindowHierarchyChange(
1180 const WindowObserver::HierarchyChangeParams& params) {
1181 params.target->NotifyWindowHierarchyChangeDown(params);
1182 switch (params.phase) {
1183 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1184 if (params.old_parent)
1185 params.old_parent->NotifyWindowHierarchyChangeUp(params);
1186 break;
1187 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1188 if (params.new_parent)
1189 params.new_parent->NotifyWindowHierarchyChangeUp(params);
1190 break;
1191 default:
1192 NOTREACHED();
1193 break;
1197 void Window::NotifyWindowHierarchyChangeDown(
1198 const WindowObserver::HierarchyChangeParams& params) {
1199 NotifyWindowHierarchyChangeAtReceiver(params);
1200 for (Window::Windows::const_iterator it = children_.begin();
1201 it != children_.end(); ++it) {
1202 (*it)->NotifyWindowHierarchyChangeDown(params);
1206 void Window::NotifyWindowHierarchyChangeUp(
1207 const WindowObserver::HierarchyChangeParams& params) {
1208 for (Window* window = this; window; window = window->parent())
1209 window->NotifyWindowHierarchyChangeAtReceiver(params);
1212 void Window::NotifyWindowHierarchyChangeAtReceiver(
1213 const WindowObserver::HierarchyChangeParams& params) {
1214 WindowObserver::HierarchyChangeParams local_params = params;
1215 local_params.receiver = this;
1217 switch (params.phase) {
1218 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1219 FOR_EACH_OBSERVER(WindowObserver, observers_,
1220 OnWindowHierarchyChanging(local_params));
1221 break;
1222 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1223 FOR_EACH_OBSERVER(WindowObserver, observers_,
1224 OnWindowHierarchyChanged(local_params));
1225 break;
1226 default:
1227 NOTREACHED();
1228 break;
1232 void Window::NotifyWindowVisibilityChanged(aura::Window* target,
1233 bool visible) {
1234 if (!NotifyWindowVisibilityChangedDown(target, visible)) {
1235 return; // |this| has been deleted.
1237 NotifyWindowVisibilityChangedUp(target, visible);
1240 bool Window::NotifyWindowVisibilityChangedAtReceiver(aura::Window* target,
1241 bool visible) {
1242 // |this| may be deleted during a call to OnWindowVisibilityChanged() on one
1243 // of the observers. We create an local observer for that. In that case we
1244 // exit without further access to any members.
1245 WindowTracker tracker;
1246 tracker.Add(this);
1247 FOR_EACH_OBSERVER(WindowObserver, observers_,
1248 OnWindowVisibilityChanged(target, visible));
1249 return tracker.Contains(this);
1252 bool Window::NotifyWindowVisibilityChangedDown(aura::Window* target,
1253 bool visible) {
1254 if (!NotifyWindowVisibilityChangedAtReceiver(target, visible))
1255 return false; // |this| was deleted.
1256 std::set<const Window*> child_already_processed;
1257 bool child_destroyed = false;
1258 do {
1259 child_destroyed = false;
1260 for (Window::Windows::const_iterator it = children_.begin();
1261 it != children_.end(); ++it) {
1262 if (!child_already_processed.insert(*it).second)
1263 continue;
1264 if (!(*it)->NotifyWindowVisibilityChangedDown(target, visible)) {
1265 // |*it| was deleted, |it| is invalid and |children_| has changed.
1266 // We exit the current for-loop and enter a new one.
1267 child_destroyed = true;
1268 break;
1271 } while (child_destroyed);
1272 return true;
1275 void Window::NotifyWindowVisibilityChangedUp(aura::Window* target,
1276 bool visible) {
1277 // Start with the parent as we already notified |this|
1278 // in NotifyWindowVisibilityChangedDown.
1279 for (Window* window = parent(); window; window = window->parent()) {
1280 bool ret = window->NotifyWindowVisibilityChangedAtReceiver(target, visible);
1281 DCHECK(ret);
1285 void Window::NotifyAncestorWindowTransformed(Window* source) {
1286 FOR_EACH_OBSERVER(WindowObserver, observers_,
1287 OnAncestorWindowTransformed(source, this));
1288 for (Window::Windows::const_iterator it = children_.begin();
1289 it != children_.end(); ++it) {
1290 (*it)->NotifyAncestorWindowTransformed(source);
1294 void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds) {
1295 bounds_ = layer()->bounds();
1296 if (parent_ && !parent_->layer()) {
1297 gfx::Vector2d offset;
1298 aura::Window* ancestor_with_layer = parent_->GetAncestorWithLayer(&offset);
1299 if (ancestor_with_layer)
1300 bounds_.Offset(-offset);
1303 if (layout_manager_)
1304 layout_manager_->OnWindowResized();
1305 if (delegate_)
1306 delegate_->OnBoundsChanged(old_bounds, bounds());
1307 FOR_EACH_OBSERVER(WindowObserver,
1308 observers_,
1309 OnWindowBoundsChanged(this, old_bounds, bounds()));
1312 bool Window::CleanupGestureState() {
1313 bool state_modified = false;
1314 state_modified |= ui::GestureRecognizer::Get()->CancelActiveTouches(this);
1315 state_modified |=
1316 ui::GestureRecognizer::Get()->CleanupStateForConsumer(this);
1317 for (Window::Windows::iterator iter = children_.begin();
1318 iter != children_.end();
1319 ++iter) {
1320 state_modified |= (*iter)->CleanupGestureState();
1322 return state_modified;
1325 void Window::OnPaintLayer(const ui::PaintContext& context) {
1326 Paint(context);
1329 void Window::OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) {
1330 DCHECK(layer());
1331 FOR_EACH_OBSERVER(WindowObserver,
1332 observers_,
1333 OnDelegatedFrameDamage(this, damage_rect_in_dip));
1336 base::Closure Window::PrepareForLayerBoundsChange() {
1337 return base::Bind(&Window::OnWindowBoundsChanged, base::Unretained(this),
1338 bounds());
1341 bool Window::CanAcceptEvent(const ui::Event& event) {
1342 // The client may forbid certain windows from receiving events at a given
1343 // point in time.
1344 client::EventClient* client = client::GetEventClient(GetRootWindow());
1345 if (client && !client->CanProcessEventsWithinSubtree(this))
1346 return false;
1348 // We need to make sure that a touch cancel event and any gesture events it
1349 // creates can always reach the window. This ensures that we receive a valid
1350 // touch / gesture stream.
1351 if (event.IsEndingEvent())
1352 return true;
1354 if (!IsVisible())
1355 return false;
1357 // The top-most window can always process an event.
1358 if (!parent_)
1359 return true;
1361 // For located events (i.e. mouse, touch etc.), an assumption is made that
1362 // windows that don't have a default event-handler cannot process the event
1363 // (see more in GetWindowForPoint()). This assumption is not made for key
1364 // events.
1365 return event.IsKeyEvent() || target_handler();
1368 ui::EventTarget* Window::GetParentTarget() {
1369 if (IsRootWindow()) {
1370 return client::GetEventClient(this) ?
1371 client::GetEventClient(this)->GetToplevelEventTarget() :
1372 Env::GetInstance();
1374 return parent_;
1377 scoped_ptr<ui::EventTargetIterator> Window::GetChildIterator() const {
1378 return make_scoped_ptr(new ui::EventTargetIteratorImpl<Window>(children()));
1381 ui::EventTargeter* Window::GetEventTargeter() {
1382 return targeter_.get();
1385 void Window::ConvertEventToTarget(ui::EventTarget* target,
1386 ui::LocatedEvent* event) {
1387 event->ConvertLocationToTarget(this,
1388 static_cast<Window*>(target));
1391 void Window::UpdateLayerName() {
1392 #if !defined(NDEBUG)
1393 DCHECK(layer());
1395 std::string layer_name(name_);
1396 if (layer_name.empty())
1397 layer_name = "Unnamed Window";
1399 if (id_ != -1)
1400 layer_name += " " + base::IntToString(id_);
1402 layer()->set_name(layer_name);
1403 #endif
1406 const Window* Window::GetAncestorWithLayer(gfx::Vector2d* offset) const {
1407 for (const aura::Window* window = this; window; window = window->parent()) {
1408 if (window->layer())
1409 return window;
1410 if (offset)
1411 *offset += window->bounds().OffsetFromOrigin();
1413 if (offset)
1414 *offset = gfx::Vector2d();
1415 return NULL;
1418 } // namespace aura