Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / ui / aura / window.cc
blobba7f0cc6859238eb40e4b8d6b28378d66f1ff08d
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/events/event_target_iterator.h"
34 #include "ui/gfx/canvas.h"
35 #include "ui/gfx/path.h"
36 #include "ui/gfx/scoped_canvas.h"
37 #include "ui/gfx/screen.h"
39 namespace aura {
41 namespace {
43 // Used when searching for a Window to stack relative to.
44 template <class T>
45 T IteratorForDirectionBegin(aura::Window* window);
47 template <>
48 Window::Windows::const_iterator IteratorForDirectionBegin(
49 aura::Window* window) {
50 return window->children().begin();
53 template <>
54 Window::Windows::const_reverse_iterator IteratorForDirectionBegin(
55 aura::Window* window) {
56 return window->children().rbegin();
59 template <class T>
60 T IteratorForDirectionEnd(aura::Window* window);
62 template <>
63 Window::Windows::const_iterator IteratorForDirectionEnd(aura::Window* window) {
64 return window->children().end();
67 template <>
68 Window::Windows::const_reverse_iterator IteratorForDirectionEnd(
69 aura::Window* window) {
70 return window->children().rend();
73 // Depth first search for the first Window with a layer to stack relative
74 // to. Starts at target. Does not descend into |ignore|.
75 template <class T>
76 ui::Layer* FindStackingTargetLayerDown(aura::Window* target,
77 aura::Window* ignore) {
78 if (target == ignore)
79 return NULL;
81 if (target->layer())
82 return target->layer();
84 for (T i = IteratorForDirectionBegin<T>(target);
85 i != IteratorForDirectionEnd<T>(target); ++i) {
86 ui::Layer* layer = FindStackingTargetLayerDown<T>(*i, ignore);
87 if (layer)
88 return layer;
90 return NULL;
93 // Depth first search through the siblings of |target||. This does not search
94 // all the siblings, only those before/after |target| (depening upon the
95 // template type) and ignoring |ignore|. Returns the Layer of the first Window
96 // encountered with a Layer.
97 template <class T>
98 ui::Layer* FindStackingLayerInSiblings(aura::Window* target,
99 aura::Window* ignore) {
100 aura::Window* parent = target->parent();
101 for (T i = std::find(IteratorForDirectionBegin<T>(parent),
102 IteratorForDirectionEnd<T>(parent), target);
103 i != IteratorForDirectionEnd<T>(parent); ++i) {
104 ui::Layer* layer = FindStackingTargetLayerDown<T>(*i, ignore);
105 if (layer)
106 return layer;
108 return NULL;
111 // Returns the first Window that has a Layer. This does a depth first search
112 // through the descendants of |target| first, then ascends up doing a depth
113 // first search through siblings of all ancestors until a Layer is found or an
114 // ancestor with a layer is found. This is intended to locate a layer to stack
115 // other layers relative to.
116 template <class T>
117 ui::Layer* FindStackingTargetLayer(aura::Window* target, aura::Window* ignore) {
118 ui::Layer* result = FindStackingTargetLayerDown<T>(target, ignore);
119 if (result)
120 return result;
121 while (target->parent()) {
122 ui::Layer* result = FindStackingLayerInSiblings<T>(target, ignore);
123 if (result)
124 return result;
125 target = target->parent();
126 if (target->layer())
127 return NULL;
129 return NULL;
132 // Does a depth first search for all descendants of |child| that have layers.
133 // This stops at any descendants that have layers (and adds them to |layers|).
134 void GetLayersToStack(aura::Window* child, std::vector<ui::Layer*>* layers) {
135 if (child->layer()) {
136 layers->push_back(child->layer());
137 return;
139 for (size_t i = 0; i < child->children().size(); ++i)
140 GetLayersToStack(child->children()[i], layers);
143 } // namespace
145 class ScopedCursorHider {
146 public:
147 explicit ScopedCursorHider(Window* window)
148 : window_(window),
149 hid_cursor_(false) {
150 if (!window_->IsRootWindow())
151 return;
152 const bool cursor_is_in_bounds = window_->GetBoundsInScreen().Contains(
153 Env::GetInstance()->last_mouse_location());
154 client::CursorClient* cursor_client = client::GetCursorClient(window_);
155 if (cursor_is_in_bounds && cursor_client &&
156 cursor_client->IsCursorVisible()) {
157 cursor_client->HideCursor();
158 hid_cursor_ = true;
161 ~ScopedCursorHider() {
162 if (!window_->IsRootWindow())
163 return;
165 // Update the device scale factor of the cursor client only when the last
166 // mouse location is on this root window.
167 if (hid_cursor_) {
168 client::CursorClient* cursor_client = client::GetCursorClient(window_);
169 if (cursor_client) {
170 const gfx::Display& display =
171 gfx::Screen::GetScreenFor(window_)->GetDisplayNearestWindow(
172 window_);
173 cursor_client->SetDisplay(display);
174 cursor_client->ShowCursor();
179 private:
180 Window* window_;
181 bool hid_cursor_;
183 DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider);
186 Window::Window(WindowDelegate* delegate)
187 : host_(NULL),
188 type_(ui::wm::WINDOW_TYPE_UNKNOWN),
189 owned_by_parent_(true),
190 delegate_(delegate),
191 parent_(NULL),
192 visible_(false),
193 id_(-1),
194 transparent_(false),
195 user_data_(NULL),
196 ignore_events_(false),
197 // Don't notify newly added observers during notification. This causes
198 // problems for code that adds an observer as part of an observer
199 // notification (such as the workspace code).
200 observers_(ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY) {
201 set_target_handler(delegate_);
204 Window::~Window() {
205 if (layer()->owner() == this)
206 layer()->CompleteAllAnimations();
207 layer()->SuppressPaint();
209 // Let the delegate know we're in the processing of destroying.
210 if (delegate_)
211 delegate_->OnWindowDestroying(this);
212 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this));
214 // While we are being destroyed, our target handler may also be in the
215 // process of destruction or already destroyed, so do not forward any
216 // input events at the ui::EP_TARGET phase.
217 set_target_handler(nullptr);
219 // TODO(beng): See comment in window_event_dispatcher.h. This shouldn't be
220 // necessary but unfortunately is right now due to ordering
221 // peculiarities. WED must be notified _after_ other observers
222 // are notified of pending teardown but before the hierarchy
223 // is actually torn down.
224 WindowTreeHost* host = GetHost();
225 if (host)
226 host->dispatcher()->OnPostNotifiedWindowDestroying(this);
228 // The window should have already had its state cleaned up in
229 // WindowEventDispatcher::OnWindowHidden(), but there have been some crashes
230 // involving windows being destroyed without being hidden first. See
231 // crbug.com/342040. This should help us debug the issue. TODO(tdresser):
232 // remove this once we determine why we have windows that are destroyed
233 // without being hidden.
234 bool window_incorrectly_cleaned_up = CleanupGestureState();
235 CHECK(!window_incorrectly_cleaned_up);
237 // Then destroy the children.
238 RemoveOrDestroyChildren();
240 // The window needs to be removed from the parent before calling the
241 // WindowDestroyed callbacks of delegate and the observers.
242 if (parent_)
243 parent_->RemoveChild(this);
245 if (delegate_)
246 delegate_->OnWindowDestroyed(this);
247 ObserverListBase<WindowObserver>::Iterator iter(&observers_);
248 for (WindowObserver* observer = iter.GetNext(); observer;
249 observer = iter.GetNext()) {
250 RemoveObserver(observer);
251 observer->OnWindowDestroyed(this);
254 // Clear properties.
255 for (std::map<const void*, Value>::const_iterator iter = prop_map_.begin();
256 iter != prop_map_.end();
257 ++iter) {
258 if (iter->second.deallocator)
259 (*iter->second.deallocator)(iter->second.value);
261 prop_map_.clear();
263 // The layer will either be destroyed by |layer_owner_|'s dtor, or by whoever
264 // acquired it.
265 layer()->set_delegate(NULL);
266 DestroyLayer();
269 void Window::Init(ui::LayerType layer_type) {
270 SetLayer(new ui::Layer(layer_type));
271 layer()->SetVisible(false);
272 layer()->set_delegate(this);
273 UpdateLayerName();
274 layer()->SetFillsBoundsOpaquely(!transparent_);
275 Env::GetInstance()->NotifyWindowInitialized(this);
278 void Window::SetType(ui::wm::WindowType type) {
279 // Cannot change type after the window is initialized.
280 DCHECK(!layer());
281 type_ = type;
284 void Window::SetName(const std::string& name) {
285 name_ = name;
286 if (layer())
287 UpdateLayerName();
290 void Window::SetTitle(const base::string16& title) {
291 title_ = title;
292 FOR_EACH_OBSERVER(WindowObserver,
293 observers_,
294 OnWindowTitleChanged(this));
297 void Window::SetTransparent(bool transparent) {
298 transparent_ = transparent;
299 if (layer())
300 layer()->SetFillsBoundsOpaquely(!transparent_);
303 void Window::SetFillsBoundsCompletely(bool fills_bounds) {
304 layer()->SetFillsBoundsCompletely(fills_bounds);
307 Window* Window::GetRootWindow() {
308 return const_cast<Window*>(
309 static_cast<const Window*>(this)->GetRootWindow());
312 const Window* Window::GetRootWindow() const {
313 return IsRootWindow() ? this : parent_ ? parent_->GetRootWindow() : NULL;
316 WindowTreeHost* Window::GetHost() {
317 return const_cast<WindowTreeHost*>(const_cast<const Window*>(this)->
318 GetHost());
321 const WindowTreeHost* Window::GetHost() const {
322 const Window* root_window = GetRootWindow();
323 return root_window ? root_window->host_ : NULL;
326 void Window::Show() {
327 DCHECK_EQ(visible_, layer()->GetTargetVisibility());
328 // It is not allowed that a window is visible but the layers alpha is fully
329 // transparent since the window would still be considered to be active but
330 // could not be seen.
331 DCHECK_IMPLIES(visible_, layer()->GetTargetOpacity() > 0.0f);
332 SetVisible(true);
335 void Window::Hide() {
336 // RootWindow::OnVisibilityChanged will call ReleaseCapture.
337 SetVisible(false);
340 bool Window::IsVisible() const {
341 // Layer visibility can be inconsistent with window visibility, for example
342 // when a Window is hidden, we want this function to return false immediately
343 // after, even though the client may decide to animate the hide effect (and
344 // so the layer will be visible for some time after Hide() is called).
345 for (const Window* window = this; window; window = window->parent()) {
346 if (!window->visible_)
347 return false;
348 if (window->layer())
349 return window->layer()->IsDrawn();
351 return false;
354 gfx::Rect Window::GetBoundsInRootWindow() const {
355 // TODO(beng): There may be a better way to handle this, and the existing code
356 // is likely wrong anyway in a multi-display world, but this will
357 // do for now.
358 if (!GetRootWindow())
359 return bounds();
360 gfx::Rect bounds_in_root(bounds().size());
361 ConvertRectToTarget(this, GetRootWindow(), &bounds_in_root);
362 return bounds_in_root;
365 gfx::Rect Window::GetBoundsInScreen() const {
366 gfx::Rect bounds(GetBoundsInRootWindow());
367 const Window* root = GetRootWindow();
368 if (root) {
369 aura::client::ScreenPositionClient* screen_position_client =
370 aura::client::GetScreenPositionClient(root);
371 if (screen_position_client) {
372 gfx::Point origin = bounds.origin();
373 screen_position_client->ConvertPointToScreen(root, &origin);
374 bounds.set_origin(origin);
377 return bounds;
380 void Window::SetTransform(const gfx::Transform& transform) {
381 if (!layer()) {
382 // Transforms aren't supported on layerless windows.
383 NOTREACHED();
384 return;
386 FOR_EACH_OBSERVER(WindowObserver, observers_,
387 OnWindowTransforming(this));
388 layer()->SetTransform(transform);
389 FOR_EACH_OBSERVER(WindowObserver, observers_,
390 OnWindowTransformed(this));
391 NotifyAncestorWindowTransformed(this);
394 void Window::SetLayoutManager(LayoutManager* layout_manager) {
395 if (layout_manager == layout_manager_)
396 return;
397 layout_manager_.reset(layout_manager);
398 if (!layout_manager)
399 return;
400 // If we're changing to a new layout manager, ensure it is aware of all the
401 // existing child windows.
402 for (Windows::const_iterator it = children_.begin();
403 it != children_.end();
404 ++it)
405 layout_manager_->OnWindowAddedToLayout(*it);
408 scoped_ptr<ui::EventTargeter>
409 Window::SetEventTargeter(scoped_ptr<ui::EventTargeter> targeter) {
410 scoped_ptr<ui::EventTargeter> old_targeter = targeter_.Pass();
411 targeter_ = targeter.Pass();
412 return old_targeter.Pass();
415 void Window::SetBounds(const gfx::Rect& new_bounds) {
416 if (parent_ && parent_->layout_manager())
417 parent_->layout_manager()->SetChildBounds(this, new_bounds);
418 else {
419 // Ensure we don't go smaller than our minimum bounds.
420 gfx::Rect final_bounds(new_bounds);
421 if (delegate_) {
422 const gfx::Size& min_size = delegate_->GetMinimumSize();
423 final_bounds.set_width(std::max(min_size.width(), final_bounds.width()));
424 final_bounds.set_height(std::max(min_size.height(),
425 final_bounds.height()));
427 SetBoundsInternal(final_bounds);
431 void Window::SetBoundsInScreen(const gfx::Rect& new_bounds_in_screen,
432 const gfx::Display& dst_display) {
433 Window* root = GetRootWindow();
434 if (root) {
435 gfx::Point origin = new_bounds_in_screen.origin();
436 aura::client::ScreenPositionClient* screen_position_client =
437 aura::client::GetScreenPositionClient(root);
438 screen_position_client->SetBounds(this, new_bounds_in_screen, dst_display);
439 return;
441 SetBounds(new_bounds_in_screen);
444 gfx::Rect Window::GetTargetBounds() const {
445 if (!layer())
446 return bounds();
448 if (!parent_ || parent_->layer())
449 return layer()->GetTargetBounds();
451 // We have a layer but our parent (who is valid) doesn't. This means the
452 // coordinates of the layer are relative to the first ancestor with a layer;
453 // convert to be relative to parent.
454 gfx::Vector2d offset;
455 const aura::Window* ancestor_with_layer =
456 parent_->GetAncestorWithLayer(&offset);
457 if (!ancestor_with_layer)
458 return layer()->GetTargetBounds();
460 gfx::Rect layer_target_bounds = layer()->GetTargetBounds();
461 layer_target_bounds -= offset;
462 return layer_target_bounds;
465 void Window::SchedulePaintInRect(const gfx::Rect& rect) {
466 layer()->SchedulePaint(rect);
469 void Window::StackChildAtTop(Window* child) {
470 if (children_.size() <= 1 || child == children_.back())
471 return; // In the front already.
472 StackChildAbove(child, children_.back());
475 void Window::StackChildAbove(Window* child, Window* target) {
476 StackChildRelativeTo(child, target, STACK_ABOVE);
479 void Window::StackChildAtBottom(Window* child) {
480 if (children_.size() <= 1 || child == children_.front())
481 return; // At the bottom already.
482 StackChildBelow(child, children_.front());
485 void Window::StackChildBelow(Window* child, Window* target) {
486 StackChildRelativeTo(child, target, STACK_BELOW);
489 void Window::AddChild(Window* child) {
490 WindowObserver::HierarchyChangeParams params;
491 params.target = child;
492 params.new_parent = this;
493 params.old_parent = child->parent();
494 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
495 NotifyWindowHierarchyChange(params);
497 Window* old_root = child->GetRootWindow();
499 DCHECK(std::find(children_.begin(), children_.end(), child) ==
500 children_.end());
501 if (child->parent())
502 child->parent()->RemoveChildImpl(child, this);
504 gfx::Vector2d offset;
505 aura::Window* ancestor_with_layer = GetAncestorWithLayer(&offset);
507 child->parent_ = this;
509 if (ancestor_with_layer) {
510 offset += child->bounds().OffsetFromOrigin();
511 child->ReparentLayers(ancestor_with_layer->layer(), offset);
514 children_.push_back(child);
515 if (layout_manager_)
516 layout_manager_->OnWindowAddedToLayout(child);
517 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child));
518 child->OnParentChanged();
520 Window* root_window = GetRootWindow();
521 if (root_window && old_root != root_window) {
522 root_window->GetHost()->dispatcher()->OnWindowAddedToRootWindow(child);
523 child->NotifyAddedToRootWindow();
526 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
527 NotifyWindowHierarchyChange(params);
530 void Window::RemoveChild(Window* child) {
531 WindowObserver::HierarchyChangeParams params;
532 params.target = child;
533 params.new_parent = NULL;
534 params.old_parent = this;
535 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
536 NotifyWindowHierarchyChange(params);
538 RemoveChildImpl(child, NULL);
540 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
541 NotifyWindowHierarchyChange(params);
544 bool Window::Contains(const Window* other) const {
545 for (const Window* parent = other; parent; parent = parent->parent_) {
546 if (parent == this)
547 return true;
549 return false;
552 Window* Window::GetChildById(int id) {
553 return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id));
556 const Window* Window::GetChildById(int id) const {
557 Windows::const_iterator i;
558 for (i = children_.begin(); i != children_.end(); ++i) {
559 if ((*i)->id() == id)
560 return *i;
561 const Window* result = (*i)->GetChildById(id);
562 if (result)
563 return result;
565 return NULL;
568 // static
569 void Window::ConvertPointToTarget(const Window* source,
570 const Window* target,
571 gfx::Point* point) {
572 if (!source)
573 return;
574 if (source->GetRootWindow() != target->GetRootWindow()) {
575 client::ScreenPositionClient* source_client =
576 client::GetScreenPositionClient(source->GetRootWindow());
577 // |source_client| can be NULL in tests.
578 if (source_client)
579 source_client->ConvertPointToScreen(source, point);
581 client::ScreenPositionClient* target_client =
582 client::GetScreenPositionClient(target->GetRootWindow());
583 // |target_client| can be NULL in tests.
584 if (target_client)
585 target_client->ConvertPointFromScreen(target, point);
586 } else if ((source != target) && (!source->layer() || !target->layer())) {
587 if (!source->layer()) {
588 gfx::Vector2d offset_to_layer;
589 source = source->GetAncestorWithLayer(&offset_to_layer);
590 *point += offset_to_layer;
592 if (!target->layer()) {
593 gfx::Vector2d offset_to_layer;
594 target = target->GetAncestorWithLayer(&offset_to_layer);
595 *point -= offset_to_layer;
597 ui::Layer::ConvertPointToLayer(source->layer(), target->layer(), point);
598 } else {
599 ui::Layer::ConvertPointToLayer(source->layer(), target->layer(), point);
603 // static
604 void Window::ConvertRectToTarget(const Window* source,
605 const Window* target,
606 gfx::Rect* rect) {
607 DCHECK(rect);
608 gfx::Point origin = rect->origin();
609 ConvertPointToTarget(source, target, &origin);
610 rect->set_origin(origin);
613 ui::TextInputClient* Window::GetFocusedTextInputClient() {
614 return delegate_ ? delegate_->GetFocusedTextInputClient() : nullptr;
617 void Window::MoveCursorTo(const gfx::Point& point_in_window) {
618 Window* root_window = GetRootWindow();
619 DCHECK(root_window);
620 gfx::Point point_in_root(point_in_window);
621 ConvertPointToTarget(this, root_window, &point_in_root);
622 root_window->GetHost()->MoveCursorTo(point_in_root);
625 gfx::NativeCursor Window::GetCursor(const gfx::Point& point) const {
626 return delegate_ ? delegate_->GetCursor(point) : gfx::kNullCursor;
629 void Window::AddObserver(WindowObserver* observer) {
630 observer->OnObservingWindow(this);
631 observers_.AddObserver(observer);
634 void Window::RemoveObserver(WindowObserver* observer) {
635 observer->OnUnobservingWindow(this);
636 observers_.RemoveObserver(observer);
639 bool Window::HasObserver(const WindowObserver* observer) const {
640 return observers_.HasObserver(observer);
643 bool Window::ContainsPointInRoot(const gfx::Point& point_in_root) const {
644 const Window* root_window = GetRootWindow();
645 if (!root_window)
646 return false;
647 gfx::Point local_point(point_in_root);
648 ConvertPointToTarget(root_window, this, &local_point);
649 return gfx::Rect(GetTargetBounds().size()).Contains(local_point);
652 bool Window::ContainsPoint(const gfx::Point& local_point) const {
653 return gfx::Rect(bounds().size()).Contains(local_point);
656 Window* Window::GetEventHandlerForPoint(const gfx::Point& local_point) {
657 return GetWindowForPoint(local_point, true, true);
660 Window* Window::GetTopWindowContainingPoint(const gfx::Point& local_point) {
661 return GetWindowForPoint(local_point, false, false);
664 Window* Window::GetToplevelWindow() {
665 Window* topmost_window_with_delegate = NULL;
666 for (aura::Window* window = this; window != NULL; window = window->parent()) {
667 if (window->delegate())
668 topmost_window_with_delegate = window;
670 return topmost_window_with_delegate;
673 void Window::Focus() {
674 client::FocusClient* client = client::GetFocusClient(this);
675 DCHECK(client);
676 client->FocusWindow(this);
679 void Window::Blur() {
680 client::FocusClient* client = client::GetFocusClient(this);
681 DCHECK(client);
682 client->FocusWindow(NULL);
685 bool Window::HasFocus() const {
686 client::FocusClient* client = client::GetFocusClient(this);
687 return client && client->GetFocusedWindow() == this;
690 bool Window::CanFocus() const {
691 if (IsRootWindow())
692 return IsVisible();
694 // NOTE: as part of focusing the window the ActivationClient may make the
695 // window visible (by way of making a hidden ancestor visible). For this
696 // reason we can't check visibility here and assume the client is doing it.
697 if (!parent_ || (delegate_ && !delegate_->CanFocus()))
698 return false;
700 // The client may forbid certain windows from receiving focus at a given point
701 // in time.
702 client::EventClient* client = client::GetEventClient(GetRootWindow());
703 if (client && !client->CanProcessEventsWithinSubtree(this))
704 return false;
706 return parent_->CanFocus();
709 bool Window::CanReceiveEvents() const {
710 if (IsRootWindow())
711 return IsVisible();
713 // The client may forbid certain windows from receiving events at a given
714 // point in time.
715 client::EventClient* client = client::GetEventClient(GetRootWindow());
716 if (client && !client->CanProcessEventsWithinSubtree(this))
717 return false;
719 return parent_ && IsVisible() && parent_->CanReceiveEvents();
722 void Window::SetCapture() {
723 if (!IsVisible())
724 return;
726 Window* root_window = GetRootWindow();
727 if (!root_window)
728 return;
729 client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
730 if (!capture_client)
731 return;
732 client::GetCaptureClient(root_window)->SetCapture(this);
735 void Window::ReleaseCapture() {
736 Window* root_window = GetRootWindow();
737 if (!root_window)
738 return;
739 client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
740 if (!capture_client)
741 return;
742 client::GetCaptureClient(root_window)->ReleaseCapture(this);
745 bool Window::HasCapture() {
746 Window* root_window = GetRootWindow();
747 if (!root_window)
748 return false;
749 client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
750 return capture_client && capture_client->GetCaptureWindow() == this;
753 void Window::SuppressPaint() {
754 layer()->SuppressPaint();
757 // {Set,Get,Clear}Property are implemented in window_property.h.
759 void Window::SetNativeWindowProperty(const char* key, void* value) {
760 SetPropertyInternal(
761 key, key, NULL, reinterpret_cast<int64>(value), 0);
764 void* Window::GetNativeWindowProperty(const char* key) const {
765 return reinterpret_cast<void*>(GetPropertyInternal(key, 0));
768 void Window::OnDeviceScaleFactorChanged(float device_scale_factor) {
769 ScopedCursorHider hider(this);
770 if (delegate_)
771 delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
774 #if !defined(NDEBUG)
775 std::string Window::GetDebugInfo() const {
776 return base::StringPrintf(
777 "%s<%d> bounds(%d, %d, %d, %d) %s %s opacity=%.1f",
778 name().empty() ? "Unknown" : name().c_str(), id(),
779 bounds().x(), bounds().y(), bounds().width(), bounds().height(),
780 visible_ ? "WindowVisible" : "WindowHidden",
781 layer() ?
782 (layer()->GetTargetVisibility() ? "LayerVisible" : "LayerHidden") :
783 "NoLayer",
784 layer() ? layer()->opacity() : 1.0f);
787 void Window::PrintWindowHierarchy(int depth) const {
788 VLOG(0) << base::StringPrintf(
789 "%*s%s", depth * 2, "", GetDebugInfo().c_str());
790 for (Windows::const_iterator it = children_.begin();
791 it != children_.end(); ++it) {
792 Window* child = *it;
793 child->PrintWindowHierarchy(depth + 1);
796 #endif
798 void Window::RemoveOrDestroyChildren() {
799 while (!children_.empty()) {
800 Window* child = children_[0];
801 if (child->owned_by_parent_) {
802 delete child;
803 // Deleting the child so remove it from out children_ list.
804 DCHECK(std::find(children_.begin(), children_.end(), child) ==
805 children_.end());
806 } else {
807 // Even if we can't delete the child, we still need to remove it from the
808 // parent so that relevant bookkeeping (parent_ back-pointers etc) are
809 // updated.
810 RemoveChild(child);
815 ///////////////////////////////////////////////////////////////////////////////
816 // Window, private:
818 int64 Window::SetPropertyInternal(const void* key,
819 const char* name,
820 PropertyDeallocator deallocator,
821 int64 value,
822 int64 default_value) {
823 int64 old = GetPropertyInternal(key, default_value);
824 if (value == default_value) {
825 prop_map_.erase(key);
826 } else {
827 Value prop_value;
828 prop_value.name = name;
829 prop_value.value = value;
830 prop_value.deallocator = deallocator;
831 prop_map_[key] = prop_value;
833 FOR_EACH_OBSERVER(WindowObserver, observers_,
834 OnWindowPropertyChanged(this, key, old));
835 return old;
838 int64 Window::GetPropertyInternal(const void* key,
839 int64 default_value) const {
840 std::map<const void*, Value>::const_iterator iter = prop_map_.find(key);
841 if (iter == prop_map_.end())
842 return default_value;
843 return iter->second.value;
846 bool Window::HitTest(const gfx::Point& local_point) {
847 gfx::Rect local_bounds(bounds().size());
848 if (!delegate_ || !delegate_->HasHitTestMask())
849 return local_bounds.Contains(local_point);
851 gfx::Path mask;
852 delegate_->GetHitTestMask(&mask);
854 SkRegion clip_region;
855 clip_region.setRect(local_bounds.x(), local_bounds.y(),
856 local_bounds.width(), local_bounds.height());
857 SkRegion mask_region;
858 return mask_region.setPath(mask, clip_region) &&
859 mask_region.contains(local_point.x(), local_point.y());
862 void Window::SetBoundsInternal(const gfx::Rect& new_bounds) {
863 gfx::Rect actual_new_bounds(new_bounds);
864 gfx::Rect old_bounds = GetTargetBounds();
866 // Always need to set the layer's bounds -- even if it is to the same thing.
867 // This may cause important side effects such as stopping animation.
868 if (!layer()) {
869 const gfx::Vector2d origin_delta = new_bounds.OffsetFromOrigin() -
870 bounds_.OffsetFromOrigin();
871 bounds_ = new_bounds;
872 OffsetLayerBounds(origin_delta);
873 } else {
874 if (parent_ && !parent_->layer()) {
875 gfx::Vector2d offset;
876 const aura::Window* ancestor_with_layer =
877 parent_->GetAncestorWithLayer(&offset);
878 if (ancestor_with_layer)
879 actual_new_bounds.Offset(offset);
881 layer()->SetBounds(actual_new_bounds);
884 // If we are currently not the layer's delegate, we will not get bounds
885 // changed notification from the layer (this typically happens after animating
886 // hidden). We must notify ourselves.
887 if (!layer() || layer()->delegate() != this)
888 OnWindowBoundsChanged(old_bounds);
891 void Window::SetVisible(bool visible) {
892 // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed.
893 tracked_objects::ScopedTracker tracking_profile(
894 FROM_HERE_WITH_EXPLICIT_FUNCTION("440919 Window::SetVisible"));
896 if ((layer() && visible == layer()->GetTargetVisibility()) ||
897 (!layer() && visible == visible_))
898 return; // No change.
900 FOR_EACH_OBSERVER(WindowObserver, observers_,
901 OnWindowVisibilityChanging(this, visible));
903 client::VisibilityClient* visibility_client =
904 client::GetVisibilityClient(this);
905 if (visibility_client)
906 visibility_client->UpdateLayerVisibility(this, visible);
907 else
908 layer()->SetVisible(visible);
909 visible_ = visible;
910 SchedulePaint();
911 if (parent_ && parent_->layout_manager_)
912 parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible);
914 if (delegate_)
915 delegate_->OnWindowTargetVisibilityChanged(visible);
917 NotifyWindowVisibilityChanged(this, visible);
920 void Window::SchedulePaint() {
921 SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height()));
924 void Window::Paint(const ui::PaintContext& context) {
925 if (delegate_)
926 delegate_->OnPaint(context);
929 Window* Window::GetWindowForPoint(const gfx::Point& local_point,
930 bool return_tightest,
931 bool for_event_handling) {
932 if (!IsVisible())
933 return NULL;
935 if ((for_event_handling && !HitTest(local_point)) ||
936 (!for_event_handling && !ContainsPoint(local_point)))
937 return NULL;
939 // Check if I should claim this event and not pass it to my children because
940 // the location is inside my hit test override area. For details, see
941 // set_hit_test_bounds_override_inner().
942 if (for_event_handling && !hit_test_bounds_override_inner_.empty()) {
943 gfx::Rect inset_local_bounds(gfx::Point(), bounds().size());
944 inset_local_bounds.Inset(hit_test_bounds_override_inner_);
945 // We know we're inside the normal local bounds, so if we're outside the
946 // inset bounds we must be in the special hit test override area.
947 DCHECK(HitTest(local_point));
948 if (!inset_local_bounds.Contains(local_point))
949 return delegate_ ? this : NULL;
952 if (!return_tightest && delegate_)
953 return this;
955 for (Windows::const_reverse_iterator it = children_.rbegin(),
956 rend = children_.rend();
957 it != rend; ++it) {
958 Window* child = *it;
960 if (for_event_handling) {
961 if (child->ignore_events_)
962 continue;
963 // The client may not allow events to be processed by certain subtrees.
964 client::EventClient* client = client::GetEventClient(GetRootWindow());
965 if (client && !client->CanProcessEventsWithinSubtree(child))
966 continue;
967 if (delegate_ && !delegate_->ShouldDescendIntoChildForEventHandling(
968 child, local_point))
969 continue;
972 gfx::Point point_in_child_coords(local_point);
973 ConvertPointToTarget(this, child, &point_in_child_coords);
974 Window* match = child->GetWindowForPoint(point_in_child_coords,
975 return_tightest,
976 for_event_handling);
977 if (match)
978 return match;
981 return delegate_ ? this : NULL;
984 void Window::RemoveChildImpl(Window* child, Window* new_parent) {
985 if (layout_manager_)
986 layout_manager_->OnWillRemoveWindowFromLayout(child);
987 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child));
988 Window* root_window = child->GetRootWindow();
989 Window* new_root_window = new_parent ? new_parent->GetRootWindow() : NULL;
990 if (root_window && root_window != new_root_window)
991 child->NotifyRemovingFromRootWindow(new_root_window);
993 gfx::Vector2d offset;
994 GetAncestorWithLayer(&offset);
995 child->UnparentLayers(!layer(), offset);
996 child->parent_ = NULL;
997 Windows::iterator i = std::find(children_.begin(), children_.end(), child);
998 DCHECK(i != children_.end());
999 children_.erase(i);
1000 child->OnParentChanged();
1001 if (layout_manager_)
1002 layout_manager_->OnWindowRemovedFromLayout(child);
1005 void Window::UnparentLayers(bool has_layerless_ancestor,
1006 const gfx::Vector2d& offset) {
1007 if (!layer()) {
1008 const gfx::Vector2d new_offset = offset + bounds().OffsetFromOrigin();
1009 for (size_t i = 0; i < children_.size(); ++i) {
1010 children_[i]->UnparentLayers(true, new_offset);
1012 } else {
1013 // Only remove the layer if we still own it. Someone else may have acquired
1014 // ownership of it via AcquireLayer() and may expect the hierarchy to go
1015 // unchanged as the Window is destroyed.
1016 if (OwnsLayer()) {
1017 if (layer()->parent())
1018 layer()->parent()->Remove(layer());
1019 if (has_layerless_ancestor) {
1020 const gfx::Rect real_bounds(bounds_);
1021 gfx::Rect layer_bounds(layer()->bounds());
1022 layer_bounds.Offset(-offset);
1023 layer()->SetBounds(layer_bounds);
1024 bounds_ = real_bounds;
1030 void Window::ReparentLayers(ui::Layer* parent_layer,
1031 const gfx::Vector2d& offset) {
1032 if (!layer()) {
1033 for (size_t i = 0; i < children_.size(); ++i) {
1034 children_[i]->ReparentLayers(
1035 parent_layer,
1036 offset + children_[i]->bounds().OffsetFromOrigin());
1038 } else {
1039 const gfx::Rect real_bounds(bounds());
1040 parent_layer->Add(layer());
1041 gfx::Rect layer_bounds(layer()->bounds().size());
1042 layer_bounds += offset;
1043 layer()->SetBounds(layer_bounds);
1044 bounds_ = real_bounds;
1048 void Window::OffsetLayerBounds(const gfx::Vector2d& offset) {
1049 if (!layer()) {
1050 for (size_t i = 0; i < children_.size(); ++i)
1051 children_[i]->OffsetLayerBounds(offset);
1052 } else {
1053 gfx::Rect layer_bounds(layer()->bounds());
1054 layer_bounds += offset;
1055 layer()->SetBounds(layer_bounds);
1059 void Window::OnParentChanged() {
1060 FOR_EACH_OBSERVER(
1061 WindowObserver, observers_, OnWindowParentChanged(this, parent_));
1064 void Window::StackChildRelativeTo(Window* child,
1065 Window* target,
1066 StackDirection direction) {
1067 DCHECK_NE(child, target);
1068 DCHECK(child);
1069 DCHECK(target);
1070 DCHECK_EQ(this, child->parent());
1071 DCHECK_EQ(this, target->parent());
1073 client::WindowStackingClient* stacking_client =
1074 client::GetWindowStackingClient();
1075 if (stacking_client &&
1076 !stacking_client->AdjustStacking(&child, &target, &direction))
1077 return;
1079 const size_t child_i =
1080 std::find(children_.begin(), children_.end(), child) - children_.begin();
1081 const size_t target_i =
1082 std::find(children_.begin(), children_.end(), target) - children_.begin();
1084 // Don't move the child if it is already in the right place.
1085 if ((direction == STACK_ABOVE && child_i == target_i + 1) ||
1086 (direction == STACK_BELOW && child_i + 1 == target_i))
1087 return;
1089 const size_t dest_i =
1090 direction == STACK_ABOVE ?
1091 (child_i < target_i ? target_i : target_i + 1) :
1092 (child_i < target_i ? target_i - 1 : target_i);
1093 children_.erase(children_.begin() + child_i);
1094 children_.insert(children_.begin() + dest_i, child);
1096 StackChildLayerRelativeTo(child, target, direction);
1098 child->OnStackingChanged();
1101 void Window::StackChildLayerRelativeTo(Window* child,
1102 Window* target,
1103 StackDirection direction) {
1104 Window* ancestor_with_layer = GetAncestorWithLayer(NULL);
1105 ui::Layer* ancestor_layer =
1106 ancestor_with_layer ? ancestor_with_layer->layer() : NULL;
1107 if (!ancestor_layer)
1108 return;
1110 if (child->layer() && target->layer()) {
1111 if (direction == STACK_ABOVE)
1112 ancestor_layer->StackAbove(child->layer(), target->layer());
1113 else
1114 ancestor_layer->StackBelow(child->layer(), target->layer());
1115 return;
1117 typedef std::vector<ui::Layer*> Layers;
1118 Layers layers;
1119 GetLayersToStack(child, &layers);
1120 if (layers.empty())
1121 return;
1123 ui::Layer* target_layer;
1124 if (direction == STACK_ABOVE) {
1125 target_layer =
1126 FindStackingTargetLayer<Windows::const_reverse_iterator>(target, child);
1127 } else {
1128 target_layer =
1129 FindStackingTargetLayer<Windows::const_iterator>(target, child);
1132 if (!target_layer) {
1133 if (direction == STACK_ABOVE) {
1134 for (Layers::const_reverse_iterator i = layers.rbegin(),
1135 rend = layers.rend(); i != rend; ++i) {
1136 ancestor_layer->StackAtBottom(*i);
1138 } else {
1139 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1140 ancestor_layer->StackAtTop(*i);
1142 return;
1145 if (direction == STACK_ABOVE) {
1146 for (Layers::const_reverse_iterator i = layers.rbegin(),
1147 rend = layers.rend(); i != rend; ++i) {
1148 ancestor_layer->StackAbove(*i, target_layer);
1150 } else {
1151 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1152 ancestor_layer->StackBelow(*i, target_layer);
1156 void Window::OnStackingChanged() {
1157 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowStackingChanged(this));
1160 void Window::NotifyRemovingFromRootWindow(Window* new_root) {
1161 FOR_EACH_OBSERVER(WindowObserver, observers_,
1162 OnWindowRemovingFromRootWindow(this, new_root));
1163 for (Window::Windows::const_iterator it = children_.begin();
1164 it != children_.end(); ++it) {
1165 (*it)->NotifyRemovingFromRootWindow(new_root);
1169 void Window::NotifyAddedToRootWindow() {
1170 FOR_EACH_OBSERVER(WindowObserver, observers_,
1171 OnWindowAddedToRootWindow(this));
1172 for (Window::Windows::const_iterator it = children_.begin();
1173 it != children_.end(); ++it) {
1174 (*it)->NotifyAddedToRootWindow();
1178 void Window::NotifyWindowHierarchyChange(
1179 const WindowObserver::HierarchyChangeParams& params) {
1180 params.target->NotifyWindowHierarchyChangeDown(params);
1181 switch (params.phase) {
1182 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1183 if (params.old_parent)
1184 params.old_parent->NotifyWindowHierarchyChangeUp(params);
1185 break;
1186 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1187 if (params.new_parent)
1188 params.new_parent->NotifyWindowHierarchyChangeUp(params);
1189 break;
1190 default:
1191 NOTREACHED();
1192 break;
1196 void Window::NotifyWindowHierarchyChangeDown(
1197 const WindowObserver::HierarchyChangeParams& params) {
1198 NotifyWindowHierarchyChangeAtReceiver(params);
1199 for (Window::Windows::const_iterator it = children_.begin();
1200 it != children_.end(); ++it) {
1201 (*it)->NotifyWindowHierarchyChangeDown(params);
1205 void Window::NotifyWindowHierarchyChangeUp(
1206 const WindowObserver::HierarchyChangeParams& params) {
1207 for (Window* window = this; window; window = window->parent())
1208 window->NotifyWindowHierarchyChangeAtReceiver(params);
1211 void Window::NotifyWindowHierarchyChangeAtReceiver(
1212 const WindowObserver::HierarchyChangeParams& params) {
1213 WindowObserver::HierarchyChangeParams local_params = params;
1214 local_params.receiver = this;
1216 switch (params.phase) {
1217 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1218 FOR_EACH_OBSERVER(WindowObserver, observers_,
1219 OnWindowHierarchyChanging(local_params));
1220 break;
1221 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1222 FOR_EACH_OBSERVER(WindowObserver, observers_,
1223 OnWindowHierarchyChanged(local_params));
1224 break;
1225 default:
1226 NOTREACHED();
1227 break;
1231 void Window::NotifyWindowVisibilityChanged(aura::Window* target,
1232 bool visible) {
1233 if (!NotifyWindowVisibilityChangedDown(target, visible)) {
1234 return; // |this| has been deleted.
1236 NotifyWindowVisibilityChangedUp(target, visible);
1239 bool Window::NotifyWindowVisibilityChangedAtReceiver(aura::Window* target,
1240 bool visible) {
1241 // |this| may be deleted during a call to OnWindowVisibilityChanged() on one
1242 // of the observers. We create an local observer for that. In that case we
1243 // exit without further access to any members.
1244 WindowTracker tracker;
1245 tracker.Add(this);
1246 FOR_EACH_OBSERVER(WindowObserver, observers_,
1247 OnWindowVisibilityChanged(target, visible));
1248 return tracker.Contains(this);
1251 bool Window::NotifyWindowVisibilityChangedDown(aura::Window* target,
1252 bool visible) {
1253 if (!NotifyWindowVisibilityChangedAtReceiver(target, visible))
1254 return false; // |this| was deleted.
1255 std::set<const Window*> child_already_processed;
1256 bool child_destroyed = false;
1257 do {
1258 child_destroyed = false;
1259 for (Window::Windows::const_iterator it = children_.begin();
1260 it != children_.end(); ++it) {
1261 if (!child_already_processed.insert(*it).second)
1262 continue;
1263 if (!(*it)->NotifyWindowVisibilityChangedDown(target, visible)) {
1264 // |*it| was deleted, |it| is invalid and |children_| has changed.
1265 // We exit the current for-loop and enter a new one.
1266 child_destroyed = true;
1267 break;
1270 } while (child_destroyed);
1271 return true;
1274 void Window::NotifyWindowVisibilityChangedUp(aura::Window* target,
1275 bool visible) {
1276 // Start with the parent as we already notified |this|
1277 // in NotifyWindowVisibilityChangedDown.
1278 for (Window* window = parent(); window; window = window->parent()) {
1279 bool ret = window->NotifyWindowVisibilityChangedAtReceiver(target, visible);
1280 DCHECK(ret);
1284 void Window::NotifyAncestorWindowTransformed(Window* source) {
1285 FOR_EACH_OBSERVER(WindowObserver, observers_,
1286 OnAncestorWindowTransformed(source, this));
1287 for (Window::Windows::const_iterator it = children_.begin();
1288 it != children_.end(); ++it) {
1289 (*it)->NotifyAncestorWindowTransformed(source);
1293 void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds) {
1294 bounds_ = layer()->bounds();
1295 if (parent_ && !parent_->layer()) {
1296 gfx::Vector2d offset;
1297 aura::Window* ancestor_with_layer = parent_->GetAncestorWithLayer(&offset);
1298 if (ancestor_with_layer)
1299 bounds_.Offset(-offset);
1302 if (layout_manager_)
1303 layout_manager_->OnWindowResized();
1304 if (delegate_)
1305 delegate_->OnBoundsChanged(old_bounds, bounds());
1306 FOR_EACH_OBSERVER(WindowObserver,
1307 observers_,
1308 OnWindowBoundsChanged(this, old_bounds, bounds()));
1311 bool Window::CleanupGestureState() {
1312 bool state_modified = false;
1313 state_modified |= ui::GestureRecognizer::Get()->CancelActiveTouches(this);
1314 state_modified |=
1315 ui::GestureRecognizer::Get()->CleanupStateForConsumer(this);
1316 for (Window::Windows::iterator iter = children_.begin();
1317 iter != children_.end();
1318 ++iter) {
1319 state_modified |= (*iter)->CleanupGestureState();
1321 return state_modified;
1324 void Window::OnPaintLayer(const ui::PaintContext& context) {
1325 Paint(context);
1328 void Window::OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) {
1329 DCHECK(layer());
1330 FOR_EACH_OBSERVER(WindowObserver,
1331 observers_,
1332 OnDelegatedFrameDamage(this, damage_rect_in_dip));
1335 base::Closure Window::PrepareForLayerBoundsChange() {
1336 return base::Bind(&Window::OnWindowBoundsChanged, base::Unretained(this),
1337 bounds());
1340 bool Window::CanAcceptEvent(const ui::Event& event) {
1341 // The client may forbid certain windows from receiving events at a given
1342 // point in time.
1343 client::EventClient* client = client::GetEventClient(GetRootWindow());
1344 if (client && !client->CanProcessEventsWithinSubtree(this))
1345 return false;
1347 // We need to make sure that a touch cancel event and any gesture events it
1348 // creates can always reach the window. This ensures that we receive a valid
1349 // touch / gesture stream.
1350 if (event.IsEndingEvent())
1351 return true;
1353 if (!IsVisible())
1354 return false;
1356 // The top-most window can always process an event.
1357 if (!parent_)
1358 return true;
1360 // For located events (i.e. mouse, touch etc.), an assumption is made that
1361 // windows that don't have a default event-handler cannot process the event
1362 // (see more in GetWindowForPoint()). This assumption is not made for key
1363 // events.
1364 return event.IsKeyEvent() || target_handler();
1367 ui::EventTarget* Window::GetParentTarget() {
1368 if (IsRootWindow()) {
1369 return client::GetEventClient(this) ?
1370 client::GetEventClient(this)->GetToplevelEventTarget() :
1371 Env::GetInstance();
1373 return parent_;
1376 scoped_ptr<ui::EventTargetIterator> Window::GetChildIterator() const {
1377 return make_scoped_ptr(new ui::EventTargetIteratorImpl<Window>(children()));
1380 ui::EventTargeter* Window::GetEventTargeter() {
1381 return targeter_.get();
1384 void Window::ConvertEventToTarget(ui::EventTarget* target,
1385 ui::LocatedEvent* event) {
1386 event->ConvertLocationToTarget(this,
1387 static_cast<Window*>(target));
1390 void Window::UpdateLayerName() {
1391 #if !defined(NDEBUG)
1392 DCHECK(layer());
1394 std::string layer_name(name_);
1395 if (layer_name.empty())
1396 layer_name = "Unnamed Window";
1398 if (id_ != -1)
1399 layer_name += " " + base::IntToString(id_);
1401 layer()->set_name(layer_name);
1402 #endif
1405 const Window* Window::GetAncestorWithLayer(gfx::Vector2d* offset) const {
1406 for (const aura::Window* window = this; window; window = window->parent()) {
1407 if (window->layer())
1408 return window;
1409 if (offset)
1410 *offset += window->bounds().OffsetFromOrigin();
1412 if (offset)
1413 *offset = gfx::Vector2d();
1414 return NULL;
1417 } // namespace aura