Requiem for client_screen.js
[chromium-blink-merge.git] / ui / aura / window.cc
blobab1a2da85fca8ff6911f10333006355627a5c03e
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 ui::LayerType WindowLayerTypeToUILayerType(WindowLayerType window_layer_type) {
44 switch (window_layer_type) {
45 case WINDOW_LAYER_NONE:
46 break;
47 case WINDOW_LAYER_NOT_DRAWN:
48 return ui::LAYER_NOT_DRAWN;
49 case WINDOW_LAYER_TEXTURED:
50 return ui::LAYER_TEXTURED;
51 case WINDOW_LAYER_SOLID_COLOR:
52 return ui::LAYER_SOLID_COLOR;
54 NOTREACHED();
55 return ui::LAYER_NOT_DRAWN;
58 // Used when searching for a Window to stack relative to.
59 template <class T>
60 T IteratorForDirectionBegin(aura::Window* window);
62 template <>
63 Window::Windows::const_iterator IteratorForDirectionBegin(
64 aura::Window* window) {
65 return window->children().begin();
68 template <>
69 Window::Windows::const_reverse_iterator IteratorForDirectionBegin(
70 aura::Window* window) {
71 return window->children().rbegin();
74 template <class T>
75 T IteratorForDirectionEnd(aura::Window* window);
77 template <>
78 Window::Windows::const_iterator IteratorForDirectionEnd(aura::Window* window) {
79 return window->children().end();
82 template <>
83 Window::Windows::const_reverse_iterator IteratorForDirectionEnd(
84 aura::Window* window) {
85 return window->children().rend();
88 // Depth first search for the first Window with a layer to stack relative
89 // to. Starts at target. Does not descend into |ignore|.
90 template <class T>
91 ui::Layer* FindStackingTargetLayerDown(aura::Window* target,
92 aura::Window* ignore) {
93 if (target == ignore)
94 return NULL;
96 if (target->layer())
97 return target->layer();
99 for (T i = IteratorForDirectionBegin<T>(target);
100 i != IteratorForDirectionEnd<T>(target); ++i) {
101 ui::Layer* layer = FindStackingTargetLayerDown<T>(*i, ignore);
102 if (layer)
103 return layer;
105 return NULL;
108 // Depth first search through the siblings of |target||. This does not search
109 // all the siblings, only those before/after |target| (depening upon the
110 // template type) and ignoring |ignore|. Returns the Layer of the first Window
111 // encountered with a Layer.
112 template <class T>
113 ui::Layer* FindStackingLayerInSiblings(aura::Window* target,
114 aura::Window* ignore) {
115 aura::Window* parent = target->parent();
116 for (T i = std::find(IteratorForDirectionBegin<T>(parent),
117 IteratorForDirectionEnd<T>(parent), target);
118 i != IteratorForDirectionEnd<T>(parent); ++i) {
119 ui::Layer* layer = FindStackingTargetLayerDown<T>(*i, ignore);
120 if (layer)
121 return layer;
123 return NULL;
126 // Returns the first Window that has a Layer. This does a depth first search
127 // through the descendants of |target| first, then ascends up doing a depth
128 // first search through siblings of all ancestors until a Layer is found or an
129 // ancestor with a layer is found. This is intended to locate a layer to stack
130 // other layers relative to.
131 template <class T>
132 ui::Layer* FindStackingTargetLayer(aura::Window* target, aura::Window* ignore) {
133 ui::Layer* result = FindStackingTargetLayerDown<T>(target, ignore);
134 if (result)
135 return result;
136 while (target->parent()) {
137 ui::Layer* result = FindStackingLayerInSiblings<T>(target, ignore);
138 if (result)
139 return result;
140 target = target->parent();
141 if (target->layer())
142 return NULL;
144 return NULL;
147 // Does a depth first search for all descendants of |child| that have layers.
148 // This stops at any descendants that have layers (and adds them to |layers|).
149 void GetLayersToStack(aura::Window* child, std::vector<ui::Layer*>* layers) {
150 if (child->layer()) {
151 layers->push_back(child->layer());
152 return;
154 for (size_t i = 0; i < child->children().size(); ++i)
155 GetLayersToStack(child->children()[i], layers);
158 } // namespace
160 class ScopedCursorHider {
161 public:
162 explicit ScopedCursorHider(Window* window)
163 : window_(window),
164 hid_cursor_(false) {
165 if (!window_->IsRootWindow())
166 return;
167 const bool cursor_is_in_bounds = window_->GetBoundsInScreen().Contains(
168 Env::GetInstance()->last_mouse_location());
169 client::CursorClient* cursor_client = client::GetCursorClient(window_);
170 if (cursor_is_in_bounds && cursor_client &&
171 cursor_client->IsCursorVisible()) {
172 cursor_client->HideCursor();
173 hid_cursor_ = true;
176 ~ScopedCursorHider() {
177 if (!window_->IsRootWindow())
178 return;
180 // Update the device scale factor of the cursor client only when the last
181 // mouse location is on this root window.
182 if (hid_cursor_) {
183 client::CursorClient* cursor_client = client::GetCursorClient(window_);
184 if (cursor_client) {
185 const gfx::Display& display =
186 gfx::Screen::GetScreenFor(window_)->GetDisplayNearestWindow(
187 window_);
188 cursor_client->SetDisplay(display);
189 cursor_client->ShowCursor();
194 private:
195 Window* window_;
196 bool hid_cursor_;
198 DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider);
201 Window::Window(WindowDelegate* delegate)
202 : host_(NULL),
203 type_(ui::wm::WINDOW_TYPE_UNKNOWN),
204 owned_by_parent_(true),
205 delegate_(delegate),
206 parent_(NULL),
207 visible_(false),
208 id_(-1),
209 transparent_(false),
210 user_data_(NULL),
211 ignore_events_(false),
212 // Don't notify newly added observers during notification. This causes
213 // problems for code that adds an observer as part of an observer
214 // notification (such as the workspace code).
215 observers_(ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY) {
216 set_target_handler(delegate_);
219 Window::~Window() {
220 // |layer()| can be NULL during tests, or if this Window is layerless.
221 if (layer()) {
222 if (layer()->owner() == this)
223 layer()->CompleteAllAnimations();
224 layer()->SuppressPaint();
227 // Let the delegate know we're in the processing of destroying.
228 if (delegate_)
229 delegate_->OnWindowDestroying(this);
230 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this));
232 // While we are being destroyed, our target handler may also be in the
233 // process of destruction or already destroyed, so do not forward any
234 // input events at the ui::EP_TARGET phase.
235 set_target_handler(nullptr);
237 // TODO(beng): See comment in window_event_dispatcher.h. This shouldn't be
238 // necessary but unfortunately is right now due to ordering
239 // peculiarities. WED must be notified _after_ other observers
240 // are notified of pending teardown but before the hierarchy
241 // is actually torn down.
242 WindowTreeHost* host = GetHost();
243 if (host)
244 host->dispatcher()->OnPostNotifiedWindowDestroying(this);
246 // The window should have already had its state cleaned up in
247 // WindowEventDispatcher::OnWindowHidden(), but there have been some crashes
248 // involving windows being destroyed without being hidden first. See
249 // crbug.com/342040. This should help us debug the issue. TODO(tdresser):
250 // remove this once we determine why we have windows that are destroyed
251 // without being hidden.
252 bool window_incorrectly_cleaned_up = CleanupGestureState();
253 CHECK(!window_incorrectly_cleaned_up);
255 // Then destroy the children.
256 RemoveOrDestroyChildren();
258 // The window needs to be removed from the parent before calling the
259 // WindowDestroyed callbacks of delegate and the observers.
260 if (parent_)
261 parent_->RemoveChild(this);
263 if (delegate_)
264 delegate_->OnWindowDestroyed(this);
265 ObserverListBase<WindowObserver>::Iterator iter(observers_);
266 for (WindowObserver* observer = iter.GetNext(); observer;
267 observer = iter.GetNext()) {
268 RemoveObserver(observer);
269 observer->OnWindowDestroyed(this);
272 // Clear properties.
273 for (std::map<const void*, Value>::const_iterator iter = prop_map_.begin();
274 iter != prop_map_.end();
275 ++iter) {
276 if (iter->second.deallocator)
277 (*iter->second.deallocator)(iter->second.value);
279 prop_map_.clear();
281 // If we have layer it will either be destroyed by |layer_owner_|'s dtor, or
282 // by whoever acquired it. We don't have a layer if Init() wasn't invoked or
283 // we are layerless.
284 if (layer())
285 layer()->set_delegate(NULL);
286 DestroyLayer();
289 void Window::Init(WindowLayerType window_layer_type) {
290 if (window_layer_type != WINDOW_LAYER_NONE) {
291 SetLayer(new ui::Layer(WindowLayerTypeToUILayerType(window_layer_type)));
292 layer()->SetVisible(false);
293 layer()->set_delegate(this);
294 UpdateLayerName();
295 layer()->SetFillsBoundsOpaquely(!transparent_);
298 Env::GetInstance()->NotifyWindowInitialized(this);
301 void Window::SetType(ui::wm::WindowType type) {
302 // Cannot change type after the window is initialized.
303 DCHECK(!layer());
304 type_ = type;
307 void Window::SetName(const std::string& name) {
308 name_ = name;
310 if (layer())
311 UpdateLayerName();
314 void Window::SetTitle(const base::string16& title) {
315 title_ = title;
316 FOR_EACH_OBSERVER(WindowObserver,
317 observers_,
318 OnWindowTitleChanged(this));
321 void Window::SetTransparent(bool transparent) {
322 transparent_ = transparent;
323 if (layer())
324 layer()->SetFillsBoundsOpaquely(!transparent_);
327 void Window::SetFillsBoundsCompletely(bool fills_bounds) {
328 if (layer())
329 layer()->SetFillsBoundsCompletely(fills_bounds);
332 Window* Window::GetRootWindow() {
333 return const_cast<Window*>(
334 static_cast<const Window*>(this)->GetRootWindow());
337 const Window* Window::GetRootWindow() const {
338 return IsRootWindow() ? this : parent_ ? parent_->GetRootWindow() : NULL;
341 WindowTreeHost* Window::GetHost() {
342 return const_cast<WindowTreeHost*>(const_cast<const Window*>(this)->
343 GetHost());
346 const WindowTreeHost* Window::GetHost() const {
347 const Window* root_window = GetRootWindow();
348 return root_window ? root_window->host_ : NULL;
351 void Window::Show() {
352 if (layer()) {
353 DCHECK_EQ(visible_, layer()->GetTargetVisibility());
354 // It is not allowed that a window is visible but the layers alpha is fully
355 // transparent since the window would still be considered to be active but
356 // could not be seen.
357 DCHECK(!(visible_ && layer()->GetTargetOpacity() == 0.0f));
359 SetVisible(true);
362 void Window::Hide() {
363 // RootWindow::OnVisibilityChanged will call ReleaseCapture.
364 SetVisible(false);
367 bool Window::IsVisible() const {
368 // Layer visibility can be inconsistent with window visibility, for example
369 // when a Window is hidden, we want this function to return false immediately
370 // after, even though the client may decide to animate the hide effect (and
371 // so the layer will be visible for some time after Hide() is called).
372 for (const Window* window = this; window; window = window->parent()) {
373 if (!window->visible_)
374 return false;
375 if (window->layer())
376 return window->layer()->IsDrawn();
378 return false;
381 gfx::Rect Window::GetBoundsInRootWindow() const {
382 // TODO(beng): There may be a better way to handle this, and the existing code
383 // is likely wrong anyway in a multi-display world, but this will
384 // do for now.
385 if (!GetRootWindow())
386 return bounds();
387 gfx::Rect bounds_in_root(bounds().size());
388 ConvertRectToTarget(this, GetRootWindow(), &bounds_in_root);
389 return bounds_in_root;
392 gfx::Rect Window::GetBoundsInScreen() const {
393 gfx::Rect bounds(GetBoundsInRootWindow());
394 const Window* root = GetRootWindow();
395 if (root) {
396 aura::client::ScreenPositionClient* screen_position_client =
397 aura::client::GetScreenPositionClient(root);
398 if (screen_position_client) {
399 gfx::Point origin = bounds.origin();
400 screen_position_client->ConvertPointToScreen(root, &origin);
401 bounds.set_origin(origin);
404 return bounds;
407 void Window::SetTransform(const gfx::Transform& transform) {
408 if (!layer()) {
409 // Transforms aren't supported on layerless windows.
410 NOTREACHED();
411 return;
413 FOR_EACH_OBSERVER(WindowObserver, observers_,
414 OnWindowTransforming(this));
415 layer()->SetTransform(transform);
416 FOR_EACH_OBSERVER(WindowObserver, observers_,
417 OnWindowTransformed(this));
418 NotifyAncestorWindowTransformed(this);
421 void Window::SetLayoutManager(LayoutManager* layout_manager) {
422 if (layout_manager == layout_manager_)
423 return;
424 layout_manager_.reset(layout_manager);
425 if (!layout_manager)
426 return;
427 // If we're changing to a new layout manager, ensure it is aware of all the
428 // existing child windows.
429 for (Windows::const_iterator it = children_.begin();
430 it != children_.end();
431 ++it)
432 layout_manager_->OnWindowAddedToLayout(*it);
435 scoped_ptr<ui::EventTargeter>
436 Window::SetEventTargeter(scoped_ptr<ui::EventTargeter> targeter) {
437 scoped_ptr<ui::EventTargeter> old_targeter = targeter_.Pass();
438 targeter_ = targeter.Pass();
439 return old_targeter.Pass();
442 void Window::SetBounds(const gfx::Rect& new_bounds) {
443 if (parent_ && parent_->layout_manager())
444 parent_->layout_manager()->SetChildBounds(this, new_bounds);
445 else {
446 // Ensure we don't go smaller than our minimum bounds.
447 gfx::Rect final_bounds(new_bounds);
448 if (delegate_) {
449 const gfx::Size& min_size = delegate_->GetMinimumSize();
450 final_bounds.set_width(std::max(min_size.width(), final_bounds.width()));
451 final_bounds.set_height(std::max(min_size.height(),
452 final_bounds.height()));
454 SetBoundsInternal(final_bounds);
458 void Window::SetBoundsInScreen(const gfx::Rect& new_bounds_in_screen,
459 const gfx::Display& dst_display) {
460 Window* root = GetRootWindow();
461 if (root) {
462 gfx::Point origin = new_bounds_in_screen.origin();
463 aura::client::ScreenPositionClient* screen_position_client =
464 aura::client::GetScreenPositionClient(root);
465 screen_position_client->SetBounds(this, new_bounds_in_screen, dst_display);
466 return;
468 SetBounds(new_bounds_in_screen);
471 gfx::Rect Window::GetTargetBounds() const {
472 if (!layer())
473 return bounds();
475 if (!parent_ || parent_->layer())
476 return layer()->GetTargetBounds();
478 // We have a layer but our parent (who is valid) doesn't. This means the
479 // coordinates of the layer are relative to the first ancestor with a layer;
480 // convert to be relative to parent.
481 gfx::Vector2d offset;
482 const aura::Window* ancestor_with_layer =
483 parent_->GetAncestorWithLayer(&offset);
484 if (!ancestor_with_layer)
485 return layer()->GetTargetBounds();
487 gfx::Rect layer_target_bounds = layer()->GetTargetBounds();
488 layer_target_bounds -= offset;
489 return layer_target_bounds;
492 void Window::SchedulePaintInRect(const gfx::Rect& rect) {
493 if (!layer() && parent_) {
494 // Notification of paint scheduled happens for the window with a layer.
495 gfx::Rect parent_rect(bounds().size());
496 parent_rect.Intersect(rect);
497 if (!parent_rect.IsEmpty()) {
498 parent_rect.Offset(bounds().origin().OffsetFromOrigin());
499 parent_->SchedulePaintInRect(parent_rect);
501 } else if (layer()) {
502 layer()->SchedulePaint(rect);
506 void Window::StackChildAtTop(Window* child) {
507 if (children_.size() <= 1 || child == children_.back())
508 return; // In the front already.
509 StackChildAbove(child, children_.back());
512 void Window::StackChildAbove(Window* child, Window* target) {
513 StackChildRelativeTo(child, target, STACK_ABOVE);
516 void Window::StackChildAtBottom(Window* child) {
517 if (children_.size() <= 1 || child == children_.front())
518 return; // At the bottom already.
519 StackChildBelow(child, children_.front());
522 void Window::StackChildBelow(Window* child, Window* target) {
523 StackChildRelativeTo(child, target, STACK_BELOW);
526 void Window::AddChild(Window* child) {
527 WindowObserver::HierarchyChangeParams params;
528 params.target = child;
529 params.new_parent = this;
530 params.old_parent = child->parent();
531 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
532 NotifyWindowHierarchyChange(params);
534 Window* old_root = child->GetRootWindow();
536 DCHECK(std::find(children_.begin(), children_.end(), child) ==
537 children_.end());
538 if (child->parent())
539 child->parent()->RemoveChildImpl(child, this);
541 gfx::Vector2d offset;
542 aura::Window* ancestor_with_layer = GetAncestorWithLayer(&offset);
544 child->parent_ = this;
546 if (ancestor_with_layer) {
547 offset += child->bounds().OffsetFromOrigin();
548 child->ReparentLayers(ancestor_with_layer->layer(), offset);
551 children_.push_back(child);
552 if (layout_manager_)
553 layout_manager_->OnWindowAddedToLayout(child);
554 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child));
555 child->OnParentChanged();
557 Window* root_window = GetRootWindow();
558 if (root_window && old_root != root_window) {
559 root_window->GetHost()->dispatcher()->OnWindowAddedToRootWindow(child);
560 child->NotifyAddedToRootWindow();
563 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
564 NotifyWindowHierarchyChange(params);
567 void Window::RemoveChild(Window* child) {
568 WindowObserver::HierarchyChangeParams params;
569 params.target = child;
570 params.new_parent = NULL;
571 params.old_parent = this;
572 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
573 NotifyWindowHierarchyChange(params);
575 RemoveChildImpl(child, NULL);
577 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
578 NotifyWindowHierarchyChange(params);
581 bool Window::Contains(const Window* other) const {
582 for (const Window* parent = other; parent; parent = parent->parent_) {
583 if (parent == this)
584 return true;
586 return false;
589 Window* Window::GetChildById(int id) {
590 return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id));
593 const Window* Window::GetChildById(int id) const {
594 Windows::const_iterator i;
595 for (i = children_.begin(); i != children_.end(); ++i) {
596 if ((*i)->id() == id)
597 return *i;
598 const Window* result = (*i)->GetChildById(id);
599 if (result)
600 return result;
602 return NULL;
605 // static
606 void Window::ConvertPointToTarget(const Window* source,
607 const Window* target,
608 gfx::Point* point) {
609 if (!source)
610 return;
611 if (source->GetRootWindow() != target->GetRootWindow()) {
612 client::ScreenPositionClient* source_client =
613 client::GetScreenPositionClient(source->GetRootWindow());
614 // |source_client| can be NULL in tests.
615 if (source_client)
616 source_client->ConvertPointToScreen(source, point);
618 client::ScreenPositionClient* target_client =
619 client::GetScreenPositionClient(target->GetRootWindow());
620 // |target_client| can be NULL in tests.
621 if (target_client)
622 target_client->ConvertPointFromScreen(target, point);
623 } else if ((source != target) && (!source->layer() || !target->layer())) {
624 if (!source->layer()) {
625 gfx::Vector2d offset_to_layer;
626 source = source->GetAncestorWithLayer(&offset_to_layer);
627 *point += offset_to_layer;
629 if (!target->layer()) {
630 gfx::Vector2d offset_to_layer;
631 target = target->GetAncestorWithLayer(&offset_to_layer);
632 *point -= offset_to_layer;
634 ui::Layer::ConvertPointToLayer(source->layer(), target->layer(), point);
635 } else {
636 ui::Layer::ConvertPointToLayer(source->layer(), target->layer(), point);
640 // static
641 void Window::ConvertRectToTarget(const Window* source,
642 const Window* target,
643 gfx::Rect* rect) {
644 DCHECK(rect);
645 gfx::Point origin = rect->origin();
646 ConvertPointToTarget(source, target, &origin);
647 rect->set_origin(origin);
650 ui::TextInputClient* Window::GetFocusedTextInputClient() {
651 return delegate_ ? delegate_->GetFocusedTextInputClient() : nullptr;
654 void Window::MoveCursorTo(const gfx::Point& point_in_window) {
655 Window* root_window = GetRootWindow();
656 DCHECK(root_window);
657 gfx::Point point_in_root(point_in_window);
658 ConvertPointToTarget(this, root_window, &point_in_root);
659 root_window->GetHost()->MoveCursorTo(point_in_root);
662 gfx::NativeCursor Window::GetCursor(const gfx::Point& point) const {
663 return delegate_ ? delegate_->GetCursor(point) : gfx::kNullCursor;
666 void Window::AddObserver(WindowObserver* observer) {
667 observer->OnObservingWindow(this);
668 observers_.AddObserver(observer);
671 void Window::RemoveObserver(WindowObserver* observer) {
672 observer->OnUnobservingWindow(this);
673 observers_.RemoveObserver(observer);
676 bool Window::HasObserver(const WindowObserver* observer) const {
677 return observers_.HasObserver(observer);
680 bool Window::ContainsPointInRoot(const gfx::Point& point_in_root) const {
681 const Window* root_window = GetRootWindow();
682 if (!root_window)
683 return false;
684 gfx::Point local_point(point_in_root);
685 ConvertPointToTarget(root_window, this, &local_point);
686 return gfx::Rect(GetTargetBounds().size()).Contains(local_point);
689 bool Window::ContainsPoint(const gfx::Point& local_point) const {
690 return gfx::Rect(bounds().size()).Contains(local_point);
693 Window* Window::GetEventHandlerForPoint(const gfx::Point& local_point) {
694 return GetWindowForPoint(local_point, true, true);
697 Window* Window::GetTopWindowContainingPoint(const gfx::Point& local_point) {
698 return GetWindowForPoint(local_point, false, false);
701 Window* Window::GetToplevelWindow() {
702 Window* topmost_window_with_delegate = NULL;
703 for (aura::Window* window = this; window != NULL; window = window->parent()) {
704 if (window->delegate())
705 topmost_window_with_delegate = window;
707 return topmost_window_with_delegate;
710 void Window::Focus() {
711 client::FocusClient* client = client::GetFocusClient(this);
712 DCHECK(client);
713 client->FocusWindow(this);
716 void Window::Blur() {
717 client::FocusClient* client = client::GetFocusClient(this);
718 DCHECK(client);
719 client->FocusWindow(NULL);
722 bool Window::HasFocus() const {
723 client::FocusClient* client = client::GetFocusClient(this);
724 return client && client->GetFocusedWindow() == this;
727 bool Window::CanFocus() const {
728 if (IsRootWindow())
729 return IsVisible();
731 // NOTE: as part of focusing the window the ActivationClient may make the
732 // window visible (by way of making a hidden ancestor visible). For this
733 // reason we can't check visibility here and assume the client is doing it.
734 if (!parent_ || (delegate_ && !delegate_->CanFocus()))
735 return false;
737 // The client may forbid certain windows from receiving focus at a given point
738 // in time.
739 client::EventClient* client = client::GetEventClient(GetRootWindow());
740 if (client && !client->CanProcessEventsWithinSubtree(this))
741 return false;
743 return parent_->CanFocus();
746 bool Window::CanReceiveEvents() const {
747 if (IsRootWindow())
748 return IsVisible();
750 // The client may forbid certain windows from receiving events at a given
751 // point in time.
752 client::EventClient* client = client::GetEventClient(GetRootWindow());
753 if (client && !client->CanProcessEventsWithinSubtree(this))
754 return false;
756 return parent_ && IsVisible() && parent_->CanReceiveEvents();
759 void Window::SetCapture() {
760 if (!IsVisible())
761 return;
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)->SetCapture(this);
772 void Window::ReleaseCapture() {
773 Window* root_window = GetRootWindow();
774 if (!root_window)
775 return;
776 client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
777 if (!capture_client)
778 return;
779 client::GetCaptureClient(root_window)->ReleaseCapture(this);
782 bool Window::HasCapture() {
783 Window* root_window = GetRootWindow();
784 if (!root_window)
785 return false;
786 client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
787 return capture_client && capture_client->GetCaptureWindow() == this;
790 void Window::SuppressPaint() {
791 if (layer())
792 layer()->SuppressPaint();
795 // {Set,Get,Clear}Property are implemented in window_property.h.
797 void Window::SetNativeWindowProperty(const char* key, void* value) {
798 SetPropertyInternal(
799 key, key, NULL, reinterpret_cast<int64>(value), 0);
802 void* Window::GetNativeWindowProperty(const char* key) const {
803 return reinterpret_cast<void*>(GetPropertyInternal(key, 0));
806 void Window::OnDeviceScaleFactorChanged(float device_scale_factor) {
807 ScopedCursorHider hider(this);
808 if (delegate_)
809 delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
812 #if !defined(NDEBUG)
813 std::string Window::GetDebugInfo() const {
814 return base::StringPrintf(
815 "%s<%d> bounds(%d, %d, %d, %d) %s %s opacity=%.1f",
816 name().empty() ? "Unknown" : name().c_str(), id(),
817 bounds().x(), bounds().y(), bounds().width(), bounds().height(),
818 visible_ ? "WindowVisible" : "WindowHidden",
819 layer() ?
820 (layer()->GetTargetVisibility() ? "LayerVisible" : "LayerHidden") :
821 "NoLayer",
822 layer() ? layer()->opacity() : 1.0f);
825 void Window::PrintWindowHierarchy(int depth) const {
826 VLOG(0) << base::StringPrintf(
827 "%*s%s", depth * 2, "", GetDebugInfo().c_str());
828 for (Windows::const_iterator it = children_.begin();
829 it != children_.end(); ++it) {
830 Window* child = *it;
831 child->PrintWindowHierarchy(depth + 1);
834 #endif
836 void Window::RemoveOrDestroyChildren() {
837 while (!children_.empty()) {
838 Window* child = children_[0];
839 if (child->owned_by_parent_) {
840 delete child;
841 // Deleting the child so remove it from out children_ list.
842 DCHECK(std::find(children_.begin(), children_.end(), child) ==
843 children_.end());
844 } else {
845 // Even if we can't delete the child, we still need to remove it from the
846 // parent so that relevant bookkeeping (parent_ back-pointers etc) are
847 // updated.
848 RemoveChild(child);
853 ///////////////////////////////////////////////////////////////////////////////
854 // Window, private:
856 int64 Window::SetPropertyInternal(const void* key,
857 const char* name,
858 PropertyDeallocator deallocator,
859 int64 value,
860 int64 default_value) {
861 int64 old = GetPropertyInternal(key, default_value);
862 if (value == default_value) {
863 prop_map_.erase(key);
864 } else {
865 Value prop_value;
866 prop_value.name = name;
867 prop_value.value = value;
868 prop_value.deallocator = deallocator;
869 prop_map_[key] = prop_value;
871 FOR_EACH_OBSERVER(WindowObserver, observers_,
872 OnWindowPropertyChanged(this, key, old));
873 return old;
876 int64 Window::GetPropertyInternal(const void* key,
877 int64 default_value) const {
878 std::map<const void*, Value>::const_iterator iter = prop_map_.find(key);
879 if (iter == prop_map_.end())
880 return default_value;
881 return iter->second.value;
884 bool Window::HitTest(const gfx::Point& local_point) {
885 gfx::Rect local_bounds(bounds().size());
886 if (!delegate_ || !delegate_->HasHitTestMask())
887 return local_bounds.Contains(local_point);
889 gfx::Path mask;
890 delegate_->GetHitTestMask(&mask);
892 SkRegion clip_region;
893 clip_region.setRect(local_bounds.x(), local_bounds.y(),
894 local_bounds.width(), local_bounds.height());
895 SkRegion mask_region;
896 return mask_region.setPath(mask, clip_region) &&
897 mask_region.contains(local_point.x(), local_point.y());
900 void Window::SetBoundsInternal(const gfx::Rect& new_bounds) {
901 gfx::Rect actual_new_bounds(new_bounds);
902 gfx::Rect old_bounds = GetTargetBounds();
904 // Always need to set the layer's bounds -- even if it is to the same thing.
905 // This may cause important side effects such as stopping animation.
906 if (!layer()) {
907 const gfx::Vector2d origin_delta = new_bounds.OffsetFromOrigin() -
908 bounds_.OffsetFromOrigin();
909 bounds_ = new_bounds;
910 OffsetLayerBounds(origin_delta);
911 } else {
912 if (parent_ && !parent_->layer()) {
913 gfx::Vector2d offset;
914 const aura::Window* ancestor_with_layer =
915 parent_->GetAncestorWithLayer(&offset);
916 if (ancestor_with_layer)
917 actual_new_bounds.Offset(offset);
919 layer()->SetBounds(actual_new_bounds);
922 // If we are currently not the layer's delegate, we will not get bounds
923 // changed notification from the layer (this typically happens after animating
924 // hidden). We must notify ourselves.
925 if (!layer() || layer()->delegate() != this)
926 OnWindowBoundsChanged(old_bounds);
929 void Window::SetVisible(bool visible) {
930 // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed.
931 tracked_objects::ScopedTracker tracking_profile(
932 FROM_HERE_WITH_EXPLICIT_FUNCTION("440919 Window::SetVisible"));
934 if ((layer() && visible == layer()->GetTargetVisibility()) ||
935 (!layer() && visible == visible_))
936 return; // No change.
938 FOR_EACH_OBSERVER(WindowObserver, observers_,
939 OnWindowVisibilityChanging(this, visible));
941 client::VisibilityClient* visibility_client =
942 client::GetVisibilityClient(this);
943 if (visibility_client)
944 visibility_client->UpdateLayerVisibility(this, visible);
945 else if (layer())
946 layer()->SetVisible(visible);
947 visible_ = visible;
948 SchedulePaint();
949 if (parent_ && parent_->layout_manager_)
950 parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible);
952 if (delegate_)
953 delegate_->OnWindowTargetVisibilityChanged(visible);
955 NotifyWindowVisibilityChanged(this, visible);
958 void Window::SchedulePaint() {
959 SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height()));
962 void Window::Paint(gfx::Canvas* canvas) {
963 if (delegate_)
964 delegate_->OnPaint(canvas);
965 PaintLayerlessChildren(canvas);
968 void Window::PaintLayerlessChildren(gfx::Canvas* canvas) {
969 for (size_t i = 0, count = children_.size(); i < count; ++i) {
970 Window* child = children_[i];
971 if (!child->layer() && child->visible_) {
972 gfx::ScopedCanvas scoped_canvas(canvas);
973 canvas->ClipRect(child->bounds());
974 if (!canvas->IsClipEmpty()) {
975 canvas->Translate(child->bounds().OffsetFromOrigin());
976 child->Paint(canvas);
982 Window* Window::GetWindowForPoint(const gfx::Point& local_point,
983 bool return_tightest,
984 bool for_event_handling) {
985 if (!IsVisible())
986 return NULL;
988 if ((for_event_handling && !HitTest(local_point)) ||
989 (!for_event_handling && !ContainsPoint(local_point)))
990 return NULL;
992 // Check if I should claim this event and not pass it to my children because
993 // the location is inside my hit test override area. For details, see
994 // set_hit_test_bounds_override_inner().
995 if (for_event_handling && !hit_test_bounds_override_inner_.empty()) {
996 gfx::Rect inset_local_bounds(gfx::Point(), bounds().size());
997 inset_local_bounds.Inset(hit_test_bounds_override_inner_);
998 // We know we're inside the normal local bounds, so if we're outside the
999 // inset bounds we must be in the special hit test override area.
1000 DCHECK(HitTest(local_point));
1001 if (!inset_local_bounds.Contains(local_point))
1002 return delegate_ ? this : NULL;
1005 if (!return_tightest && delegate_)
1006 return this;
1008 for (Windows::const_reverse_iterator it = children_.rbegin(),
1009 rend = children_.rend();
1010 it != rend; ++it) {
1011 Window* child = *it;
1013 if (for_event_handling) {
1014 if (child->ignore_events_)
1015 continue;
1016 // The client may not allow events to be processed by certain subtrees.
1017 client::EventClient* client = client::GetEventClient(GetRootWindow());
1018 if (client && !client->CanProcessEventsWithinSubtree(child))
1019 continue;
1020 if (delegate_ && !delegate_->ShouldDescendIntoChildForEventHandling(
1021 child, local_point))
1022 continue;
1025 gfx::Point point_in_child_coords(local_point);
1026 ConvertPointToTarget(this, child, &point_in_child_coords);
1027 Window* match = child->GetWindowForPoint(point_in_child_coords,
1028 return_tightest,
1029 for_event_handling);
1030 if (match)
1031 return match;
1034 return delegate_ ? this : NULL;
1037 void Window::RemoveChildImpl(Window* child, Window* new_parent) {
1038 if (layout_manager_)
1039 layout_manager_->OnWillRemoveWindowFromLayout(child);
1040 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child));
1041 Window* root_window = child->GetRootWindow();
1042 Window* new_root_window = new_parent ? new_parent->GetRootWindow() : NULL;
1043 if (root_window && root_window != new_root_window)
1044 child->NotifyRemovingFromRootWindow(new_root_window);
1046 gfx::Vector2d offset;
1047 GetAncestorWithLayer(&offset);
1048 child->UnparentLayers(!layer(), offset);
1049 child->parent_ = NULL;
1050 Windows::iterator i = std::find(children_.begin(), children_.end(), child);
1051 DCHECK(i != children_.end());
1052 children_.erase(i);
1053 child->OnParentChanged();
1054 if (layout_manager_)
1055 layout_manager_->OnWindowRemovedFromLayout(child);
1058 void Window::UnparentLayers(bool has_layerless_ancestor,
1059 const gfx::Vector2d& offset) {
1060 if (!layer()) {
1061 const gfx::Vector2d new_offset = offset + bounds().OffsetFromOrigin();
1062 for (size_t i = 0; i < children_.size(); ++i) {
1063 children_[i]->UnparentLayers(true, new_offset);
1065 } else {
1066 // Only remove the layer if we still own it. Someone else may have acquired
1067 // ownership of it via AcquireLayer() and may expect the hierarchy to go
1068 // unchanged as the Window is destroyed.
1069 if (OwnsLayer()) {
1070 if (layer()->parent())
1071 layer()->parent()->Remove(layer());
1072 if (has_layerless_ancestor) {
1073 const gfx::Rect real_bounds(bounds_);
1074 gfx::Rect layer_bounds(layer()->bounds());
1075 layer_bounds.Offset(-offset);
1076 layer()->SetBounds(layer_bounds);
1077 bounds_ = real_bounds;
1083 void Window::ReparentLayers(ui::Layer* parent_layer,
1084 const gfx::Vector2d& offset) {
1085 if (!layer()) {
1086 for (size_t i = 0; i < children_.size(); ++i) {
1087 children_[i]->ReparentLayers(
1088 parent_layer,
1089 offset + children_[i]->bounds().OffsetFromOrigin());
1091 } else {
1092 const gfx::Rect real_bounds(bounds());
1093 parent_layer->Add(layer());
1094 gfx::Rect layer_bounds(layer()->bounds().size());
1095 layer_bounds += offset;
1096 layer()->SetBounds(layer_bounds);
1097 bounds_ = real_bounds;
1101 void Window::OffsetLayerBounds(const gfx::Vector2d& offset) {
1102 if (!layer()) {
1103 for (size_t i = 0; i < children_.size(); ++i)
1104 children_[i]->OffsetLayerBounds(offset);
1105 } else {
1106 gfx::Rect layer_bounds(layer()->bounds());
1107 layer_bounds += offset;
1108 layer()->SetBounds(layer_bounds);
1112 void Window::OnParentChanged() {
1113 FOR_EACH_OBSERVER(
1114 WindowObserver, observers_, OnWindowParentChanged(this, parent_));
1117 void Window::StackChildRelativeTo(Window* child,
1118 Window* target,
1119 StackDirection direction) {
1120 DCHECK_NE(child, target);
1121 DCHECK(child);
1122 DCHECK(target);
1123 DCHECK_EQ(this, child->parent());
1124 DCHECK_EQ(this, target->parent());
1126 client::WindowStackingClient* stacking_client =
1127 client::GetWindowStackingClient();
1128 if (stacking_client &&
1129 !stacking_client->AdjustStacking(&child, &target, &direction))
1130 return;
1132 const size_t child_i =
1133 std::find(children_.begin(), children_.end(), child) - children_.begin();
1134 const size_t target_i =
1135 std::find(children_.begin(), children_.end(), target) - children_.begin();
1137 // Don't move the child if it is already in the right place.
1138 if ((direction == STACK_ABOVE && child_i == target_i + 1) ||
1139 (direction == STACK_BELOW && child_i + 1 == target_i))
1140 return;
1142 const size_t dest_i =
1143 direction == STACK_ABOVE ?
1144 (child_i < target_i ? target_i : target_i + 1) :
1145 (child_i < target_i ? target_i - 1 : target_i);
1146 children_.erase(children_.begin() + child_i);
1147 children_.insert(children_.begin() + dest_i, child);
1149 StackChildLayerRelativeTo(child, target, direction);
1151 child->OnStackingChanged();
1154 void Window::StackChildLayerRelativeTo(Window* child,
1155 Window* target,
1156 StackDirection direction) {
1157 Window* ancestor_with_layer = GetAncestorWithLayer(NULL);
1158 ui::Layer* ancestor_layer =
1159 ancestor_with_layer ? ancestor_with_layer->layer() : NULL;
1160 if (!ancestor_layer)
1161 return;
1163 if (child->layer() && target->layer()) {
1164 if (direction == STACK_ABOVE)
1165 ancestor_layer->StackAbove(child->layer(), target->layer());
1166 else
1167 ancestor_layer->StackBelow(child->layer(), target->layer());
1168 return;
1170 typedef std::vector<ui::Layer*> Layers;
1171 Layers layers;
1172 GetLayersToStack(child, &layers);
1173 if (layers.empty())
1174 return;
1176 ui::Layer* target_layer;
1177 if (direction == STACK_ABOVE) {
1178 target_layer =
1179 FindStackingTargetLayer<Windows::const_reverse_iterator>(target, child);
1180 } else {
1181 target_layer =
1182 FindStackingTargetLayer<Windows::const_iterator>(target, child);
1185 if (!target_layer) {
1186 if (direction == STACK_ABOVE) {
1187 for (Layers::const_reverse_iterator i = layers.rbegin(),
1188 rend = layers.rend(); i != rend; ++i) {
1189 ancestor_layer->StackAtBottom(*i);
1191 } else {
1192 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1193 ancestor_layer->StackAtTop(*i);
1195 return;
1198 if (direction == STACK_ABOVE) {
1199 for (Layers::const_reverse_iterator i = layers.rbegin(),
1200 rend = layers.rend(); i != rend; ++i) {
1201 ancestor_layer->StackAbove(*i, target_layer);
1203 } else {
1204 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1205 ancestor_layer->StackBelow(*i, target_layer);
1209 void Window::OnStackingChanged() {
1210 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowStackingChanged(this));
1213 void Window::NotifyRemovingFromRootWindow(Window* new_root) {
1214 FOR_EACH_OBSERVER(WindowObserver, observers_,
1215 OnWindowRemovingFromRootWindow(this, new_root));
1216 for (Window::Windows::const_iterator it = children_.begin();
1217 it != children_.end(); ++it) {
1218 (*it)->NotifyRemovingFromRootWindow(new_root);
1222 void Window::NotifyAddedToRootWindow() {
1223 FOR_EACH_OBSERVER(WindowObserver, observers_,
1224 OnWindowAddedToRootWindow(this));
1225 for (Window::Windows::const_iterator it = children_.begin();
1226 it != children_.end(); ++it) {
1227 (*it)->NotifyAddedToRootWindow();
1231 void Window::NotifyWindowHierarchyChange(
1232 const WindowObserver::HierarchyChangeParams& params) {
1233 params.target->NotifyWindowHierarchyChangeDown(params);
1234 switch (params.phase) {
1235 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1236 if (params.old_parent)
1237 params.old_parent->NotifyWindowHierarchyChangeUp(params);
1238 break;
1239 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1240 if (params.new_parent)
1241 params.new_parent->NotifyWindowHierarchyChangeUp(params);
1242 break;
1243 default:
1244 NOTREACHED();
1245 break;
1249 void Window::NotifyWindowHierarchyChangeDown(
1250 const WindowObserver::HierarchyChangeParams& params) {
1251 NotifyWindowHierarchyChangeAtReceiver(params);
1252 for (Window::Windows::const_iterator it = children_.begin();
1253 it != children_.end(); ++it) {
1254 (*it)->NotifyWindowHierarchyChangeDown(params);
1258 void Window::NotifyWindowHierarchyChangeUp(
1259 const WindowObserver::HierarchyChangeParams& params) {
1260 for (Window* window = this; window; window = window->parent())
1261 window->NotifyWindowHierarchyChangeAtReceiver(params);
1264 void Window::NotifyWindowHierarchyChangeAtReceiver(
1265 const WindowObserver::HierarchyChangeParams& params) {
1266 WindowObserver::HierarchyChangeParams local_params = params;
1267 local_params.receiver = this;
1269 switch (params.phase) {
1270 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1271 FOR_EACH_OBSERVER(WindowObserver, observers_,
1272 OnWindowHierarchyChanging(local_params));
1273 break;
1274 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1275 FOR_EACH_OBSERVER(WindowObserver, observers_,
1276 OnWindowHierarchyChanged(local_params));
1277 break;
1278 default:
1279 NOTREACHED();
1280 break;
1284 void Window::NotifyWindowVisibilityChanged(aura::Window* target,
1285 bool visible) {
1286 if (!NotifyWindowVisibilityChangedDown(target, visible)) {
1287 return; // |this| has been deleted.
1289 NotifyWindowVisibilityChangedUp(target, visible);
1292 bool Window::NotifyWindowVisibilityChangedAtReceiver(aura::Window* target,
1293 bool visible) {
1294 // |this| may be deleted during a call to OnWindowVisibilityChanged() on one
1295 // of the observers. We create an local observer for that. In that case we
1296 // exit without further access to any members.
1297 WindowTracker tracker;
1298 tracker.Add(this);
1299 FOR_EACH_OBSERVER(WindowObserver, observers_,
1300 OnWindowVisibilityChanged(target, visible));
1301 return tracker.Contains(this);
1304 bool Window::NotifyWindowVisibilityChangedDown(aura::Window* target,
1305 bool visible) {
1306 if (!NotifyWindowVisibilityChangedAtReceiver(target, visible))
1307 return false; // |this| was deleted.
1308 std::set<const Window*> child_already_processed;
1309 bool child_destroyed = false;
1310 do {
1311 child_destroyed = false;
1312 for (Window::Windows::const_iterator it = children_.begin();
1313 it != children_.end(); ++it) {
1314 if (!child_already_processed.insert(*it).second)
1315 continue;
1316 if (!(*it)->NotifyWindowVisibilityChangedDown(target, visible)) {
1317 // |*it| was deleted, |it| is invalid and |children_| has changed.
1318 // We exit the current for-loop and enter a new one.
1319 child_destroyed = true;
1320 break;
1323 } while (child_destroyed);
1324 return true;
1327 void Window::NotifyWindowVisibilityChangedUp(aura::Window* target,
1328 bool visible) {
1329 // Start with the parent as we already notified |this|
1330 // in NotifyWindowVisibilityChangedDown.
1331 for (Window* window = parent(); window; window = window->parent()) {
1332 bool ret = window->NotifyWindowVisibilityChangedAtReceiver(target, visible);
1333 DCHECK(ret);
1337 void Window::NotifyAncestorWindowTransformed(Window* source) {
1338 FOR_EACH_OBSERVER(WindowObserver, observers_,
1339 OnAncestorWindowTransformed(source, this));
1340 for (Window::Windows::const_iterator it = children_.begin();
1341 it != children_.end(); ++it) {
1342 (*it)->NotifyAncestorWindowTransformed(source);
1346 void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds) {
1347 if (layer()) {
1348 bounds_ = layer()->bounds();
1349 if (parent_ && !parent_->layer()) {
1350 gfx::Vector2d offset;
1351 aura::Window* ancestor_with_layer =
1352 parent_->GetAncestorWithLayer(&offset);
1353 if (ancestor_with_layer)
1354 bounds_.Offset(-offset);
1358 if (layout_manager_)
1359 layout_manager_->OnWindowResized();
1360 if (delegate_)
1361 delegate_->OnBoundsChanged(old_bounds, bounds());
1362 FOR_EACH_OBSERVER(WindowObserver,
1363 observers_,
1364 OnWindowBoundsChanged(this, old_bounds, bounds()));
1367 bool Window::CleanupGestureState() {
1368 bool state_modified = false;
1369 state_modified |= ui::GestureRecognizer::Get()->CancelActiveTouches(this);
1370 state_modified |=
1371 ui::GestureRecognizer::Get()->CleanupStateForConsumer(this);
1372 for (Window::Windows::iterator iter = children_.begin();
1373 iter != children_.end();
1374 ++iter) {
1375 state_modified |= (*iter)->CleanupGestureState();
1377 return state_modified;
1380 void Window::OnPaintLayer(gfx::Canvas* canvas) {
1381 Paint(canvas);
1384 void Window::OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) {
1385 DCHECK(layer());
1386 FOR_EACH_OBSERVER(WindowObserver,
1387 observers_,
1388 OnDelegatedFrameDamage(this, damage_rect_in_dip));
1391 base::Closure Window::PrepareForLayerBoundsChange() {
1392 return base::Bind(&Window::OnWindowBoundsChanged, base::Unretained(this),
1393 bounds());
1396 bool Window::CanAcceptEvent(const ui::Event& event) {
1397 // The client may forbid certain windows from receiving events at a given
1398 // point in time.
1399 client::EventClient* client = client::GetEventClient(GetRootWindow());
1400 if (client && !client->CanProcessEventsWithinSubtree(this))
1401 return false;
1403 // We need to make sure that a touch cancel event and any gesture events it
1404 // creates can always reach the window. This ensures that we receive a valid
1405 // touch / gesture stream.
1406 if (event.IsEndingEvent())
1407 return true;
1409 if (!IsVisible())
1410 return false;
1412 // The top-most window can always process an event.
1413 if (!parent_)
1414 return true;
1416 // For located events (i.e. mouse, touch etc.), an assumption is made that
1417 // windows that don't have a default event-handler cannot process the event
1418 // (see more in GetWindowForPoint()). This assumption is not made for key
1419 // events.
1420 return event.IsKeyEvent() || target_handler();
1423 ui::EventTarget* Window::GetParentTarget() {
1424 if (IsRootWindow()) {
1425 return client::GetEventClient(this) ?
1426 client::GetEventClient(this)->GetToplevelEventTarget() :
1427 Env::GetInstance();
1429 return parent_;
1432 scoped_ptr<ui::EventTargetIterator> Window::GetChildIterator() const {
1433 return make_scoped_ptr(new ui::EventTargetIteratorImpl<Window>(children()));
1436 ui::EventTargeter* Window::GetEventTargeter() {
1437 return targeter_.get();
1440 void Window::ConvertEventToTarget(ui::EventTarget* target,
1441 ui::LocatedEvent* event) {
1442 event->ConvertLocationToTarget(this,
1443 static_cast<Window*>(target));
1446 void Window::UpdateLayerName() {
1447 #if !defined(NDEBUG)
1448 DCHECK(layer());
1450 std::string layer_name(name_);
1451 if (layer_name.empty())
1452 layer_name = "Unnamed Window";
1454 if (id_ != -1)
1455 layer_name += " " + base::IntToString(id_);
1457 layer()->set_name(layer_name);
1458 #endif
1461 const Window* Window::GetAncestorWithLayer(gfx::Vector2d* offset) const {
1462 for (const aura::Window* window = this; window; window = window->parent()) {
1463 if (window->layer())
1464 return window;
1465 if (offset)
1466 *offset += window->bounds().OffsetFromOrigin();
1468 if (offset)
1469 *offset = gfx::Vector2d();
1470 return NULL;
1473 } // namespace aura