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"
10 #include "base/bind_helpers.h"
11 #include "base/callback.h"
12 #include "base/logging.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "ui/aura/client/capture_client.h"
17 #include "ui/aura/client/cursor_client.h"
18 #include "ui/aura/client/event_client.h"
19 #include "ui/aura/client/focus_client.h"
20 #include "ui/aura/client/screen_position_client.h"
21 #include "ui/aura/client/visibility_client.h"
22 #include "ui/aura/client/window_stacking_client.h"
23 #include "ui/aura/env.h"
24 #include "ui/aura/layout_manager.h"
25 #include "ui/aura/root_window.h"
26 #include "ui/aura/window_delegate.h"
27 #include "ui/aura/window_observer.h"
28 #include "ui/aura/window_tracker.h"
29 #include "ui/aura/window_tree_host.h"
30 #include "ui/compositor/compositor.h"
31 #include "ui/compositor/layer.h"
32 #include "ui/events/event_target_iterator.h"
33 #include "ui/gfx/animation/multi_animation.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"
43 ui::LayerType WindowLayerTypeToUILayerType(WindowLayerType window_layer_type) {
44 switch (window_layer_type) {
45 case WINDOW_LAYER_NONE:
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;
55 return ui::LAYER_NOT_DRAWN;
58 // Used when searching for a Window to stack relative to.
60 T IteratorForDirectionBegin(aura::Window* window);
63 Window::Windows::const_iterator IteratorForDirectionBegin(
64 aura::Window* window) {
65 return window->children().begin();
69 Window::Windows::const_reverse_iterator IteratorForDirectionBegin(
70 aura::Window* window) {
71 return window->children().rbegin();
75 T IteratorForDirectionEnd(aura::Window* window);
78 Window::Windows::const_iterator IteratorForDirectionEnd(aura::Window* window) {
79 return window->children().end();
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|.
91 ui::Layer* FindStackingTargetLayerDown(aura::Window* target,
92 aura::Window* ignore) {
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);
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.
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);
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.
132 ui::Layer* FindStackingTargetLayer(aura::Window* target, aura::Window* ignore) {
133 ui::Layer* result = FindStackingTargetLayerDown<T>(target, ignore);
136 while (target->parent()) {
137 ui::Layer* result = FindStackingLayerInSiblings<T>(target, ignore);
140 target = target->parent();
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());
154 for (size_t i = 0; i < child->children().size(); ++i)
155 GetLayersToStack(child->children()[i], layers);
160 class ScopedCursorHider {
162 explicit ScopedCursorHider(Window* window)
165 if (!window_->HasDispatcher())
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();
176 ~ScopedCursorHider() {
177 if (!window_->HasDispatcher())
180 // Update the device scale factor of the cursor client only when the last
181 // mouse location is on this root window.
183 client::CursorClient* cursor_client = client::GetCursorClient(window_);
185 const gfx::Display& display =
186 gfx::Screen::GetScreenFor(window_)->GetDisplayNearestWindow(
188 cursor_client->SetDisplay(display);
189 cursor_client->ShowCursor();
198 DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider);
201 Window::Window(WindowDelegate* delegate)
203 type_(ui::wm::WINDOW_TYPE_UNKNOWN),
204 owned_by_parent_(true),
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_);
220 // |layer_| can be NULL during tests, or if this Window is layerless.
222 layer_->SuppressPaint();
224 // Let the delegate know we're in the processing of destroying.
226 delegate_->OnWindowDestroying();
227 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this));
229 // Let the root know so that it can remove any references to us.
230 WindowEventDispatcher* dispatcher = GetDispatcher();
232 dispatcher->OnWindowDestroying(this);
234 // Then destroy the children.
235 RemoveOrDestroyChildren();
237 // The window needs to be removed from the parent before calling the
238 // WindowDestroyed callbacks of delegate and the observers.
240 parent_->RemoveChild(this);
243 delegate_->OnWindowDestroyed();
244 ObserverListBase<WindowObserver>::Iterator iter(observers_);
245 WindowObserver* observer;
246 while ((observer = iter.GetNext())) {
247 RemoveObserver(observer);
248 observer->OnWindowDestroyed(this);
252 for (std::map<const void*, Value>::const_iterator iter = prop_map_.begin();
253 iter != prop_map_.end();
255 if (iter->second.deallocator)
256 (*iter->second.deallocator)(iter->second.value);
260 // If we have layer it will either be destroyed by |layer_owner_|'s dtor, or
261 // by whoever acquired it. We don't have a layer if Init() wasn't invoked or
264 layer_->set_delegate(NULL);
269 void Window::Init(WindowLayerType window_layer_type) {
270 if (window_layer_type != WINDOW_LAYER_NONE) {
271 layer_ = new ui::Layer(WindowLayerTypeToUILayerType(window_layer_type));
272 layer_owner_.reset(layer_);
273 layer_->SetVisible(false);
274 layer_->set_delegate(this);
275 UpdateLayerName(name_);
276 layer_->SetFillsBoundsOpaquely(!transparent_);
279 Env::GetInstance()->NotifyWindowInitialized(this);
282 ui::Layer* Window::RecreateLayer() {
283 // Disconnect the old layer, but don't delete it.
284 ui::Layer* old_layer = AcquireLayer();
288 bounds_.SetRect(0, 0, 0, 0);
290 old_layer->set_delegate(NULL);
292 layer_ = new ui::Layer(old_layer->type());
293 layer_owner_.reset(layer_);
294 layer_->SetVisible(old_layer->visible());
295 layer_->set_scale_content(old_layer->scale_content());
296 layer_->set_delegate(this);
297 layer_->SetMasksToBounds(old_layer->GetMasksToBounds());
300 delegate_->DidRecreateLayer(old_layer, layer_);
302 UpdateLayerName(name_);
303 layer_->SetFillsBoundsOpaquely(!transparent_);
304 // Install new layer as a sibling of the old layer, stacked below it.
305 if (old_layer->parent()) {
306 old_layer->parent()->Add(layer_);
307 old_layer->parent()->StackBelow(layer_, old_layer);
309 // Migrate all the child layers over to the new layer. Copy the list because
310 // the items are removed during iteration.
311 std::vector<ui::Layer*> children_copy = old_layer->children();
312 for (std::vector<ui::Layer*>::const_iterator it = children_copy.begin();
313 it != children_copy.end();
315 ui::Layer* child = *it;
321 void Window::SetType(ui::wm::WindowType type) {
322 // Cannot change type after the window is initialized.
327 void Window::SetName(const std::string& name) {
331 UpdateLayerName(name_);
334 void Window::SetTransparent(bool transparent) {
335 transparent_ = transparent;
337 layer_->SetFillsBoundsOpaquely(!transparent_);
340 Window* Window::GetRootWindow() {
341 return const_cast<Window*>(
342 static_cast<const Window*>(this)->GetRootWindow());
345 const Window* Window::GetRootWindow() const {
346 return dispatcher_ ? this : parent_ ? parent_->GetRootWindow() : NULL;
349 WindowEventDispatcher* Window::GetDispatcher() {
350 return const_cast<WindowEventDispatcher*>(const_cast<const Window*>(this)->
354 const WindowEventDispatcher* Window::GetDispatcher() const {
355 const Window* root_window = GetRootWindow();
356 return root_window ? root_window->dispatcher_ : NULL;
359 void Window::Show() {
363 void Window::Hide() {
364 // RootWindow::OnVisibilityChanged will call ReleaseCapture.
368 bool Window::IsVisible() const {
369 // Layer visibility can be inconsistent with window visibility, for example
370 // when a Window is hidden, we want this function to return false immediately
371 // after, even though the client may decide to animate the hide effect (and
372 // so the layer will be visible for some time after Hide() is called).
373 for (const Window* window = this; window; window = window->parent()) {
374 if (!window->visible_)
377 return window->layer_->IsDrawn();
382 gfx::Rect Window::GetBoundsInRootWindow() const {
383 // TODO(beng): There may be a better way to handle this, and the existing code
384 // is likely wrong anyway in a multi-display world, but this will
386 if (!GetRootWindow())
388 gfx::Point origin = bounds().origin();
389 ConvertPointToTarget(parent_, GetRootWindow(), &origin);
390 return gfx::Rect(origin, bounds().size());
393 gfx::Rect Window::GetBoundsInScreen() const {
394 gfx::Rect bounds(GetBoundsInRootWindow());
395 const Window* root = GetRootWindow();
397 aura::client::ScreenPositionClient* screen_position_client =
398 aura::client::GetScreenPositionClient(root);
399 if (screen_position_client) {
400 gfx::Point origin = bounds.origin();
401 screen_position_client->ConvertPointToScreen(root, &origin);
402 bounds.set_origin(origin);
408 void Window::SetTransform(const gfx::Transform& transform) {
410 // Transforms aren't supported on layerless windows.
414 WindowEventDispatcher* dispatcher = GetDispatcher();
415 bool contained_mouse = IsVisible() && dispatcher &&
416 ContainsPointInRoot(dispatcher->GetLastMouseLocationInRoot());
417 layer_->SetTransform(transform);
419 dispatcher->OnWindowTransformed(this, contained_mouse);
422 void Window::SetLayoutManager(LayoutManager* layout_manager) {
423 if (layout_manager == layout_manager_)
425 layout_manager_.reset(layout_manager);
428 // If we're changing to a new layout manager, ensure it is aware of all the
429 // existing child windows.
430 for (Windows::const_iterator it = children_.begin();
431 it != children_.end();
433 layout_manager_->OnWindowAddedToLayout(*it);
436 scoped_ptr<ui::EventTargeter>
437 Window::SetEventTargeter(scoped_ptr<ui::EventTargeter> targeter) {
438 scoped_ptr<ui::EventTargeter> old_targeter = targeter_.Pass();
439 targeter_ = targeter.Pass();
440 return old_targeter.Pass();
443 void Window::SetBounds(const gfx::Rect& new_bounds) {
444 if (parent_ && parent_->layout_manager())
445 parent_->layout_manager()->SetChildBounds(this, new_bounds);
447 SetBoundsInternal(new_bounds);
450 void Window::SetBoundsInScreen(const gfx::Rect& new_bounds_in_screen,
451 const gfx::Display& dst_display) {
452 Window* root = GetRootWindow();
454 gfx::Point origin = new_bounds_in_screen.origin();
455 aura::client::ScreenPositionClient* screen_position_client =
456 aura::client::GetScreenPositionClient(root);
457 screen_position_client->SetBounds(this, new_bounds_in_screen, dst_display);
460 SetBounds(new_bounds_in_screen);
463 gfx::Rect Window::GetTargetBounds() const {
467 if (!parent_ || parent_->layer_)
468 return layer_->GetTargetBounds();
470 // We have a layer but our parent (who is valid) doesn't. This means the
471 // coordinates of the layer are relative to the first ancestor with a layer;
472 // convert to be relative to parent.
473 gfx::Vector2d offset;
474 const aura::Window* ancestor_with_layer =
475 parent_->GetAncestorWithLayer(&offset);
476 if (!ancestor_with_layer)
477 return layer_->GetTargetBounds();
479 gfx::Rect layer_target_bounds = layer_->GetTargetBounds();
480 layer_target_bounds -= offset;
481 return layer_target_bounds;
484 void Window::SchedulePaintInRect(const gfx::Rect& rect) {
485 if (!layer_ && parent_) {
486 // Notification of paint scheduled happens for the window with a layer.
487 gfx::Rect parent_rect(bounds().size());
488 parent_rect.Intersect(rect);
489 if (!parent_rect.IsEmpty()) {
490 parent_rect.Offset(bounds().origin().OffsetFromOrigin());
491 parent_->SchedulePaintInRect(parent_rect);
493 } else if (layer_ && layer_->SchedulePaint(rect)) {
495 WindowObserver, observers_, OnWindowPaintScheduled(this, rect));
499 void Window::StackChildAtTop(Window* child) {
500 if (children_.size() <= 1 || child == children_.back())
501 return; // In the front already.
502 StackChildAbove(child, children_.back());
505 void Window::StackChildAbove(Window* child, Window* target) {
506 StackChildRelativeTo(child, target, STACK_ABOVE);
509 void Window::StackChildAtBottom(Window* child) {
510 if (children_.size() <= 1 || child == children_.front())
511 return; // At the bottom already.
512 StackChildBelow(child, children_.front());
515 void Window::StackChildBelow(Window* child, Window* target) {
516 StackChildRelativeTo(child, target, STACK_BELOW);
519 void Window::AddChild(Window* child) {
520 WindowObserver::HierarchyChangeParams params;
521 params.target = child;
522 params.new_parent = this;
523 params.old_parent = child->parent();
524 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
525 NotifyWindowHierarchyChange(params);
527 Window* old_root = child->GetRootWindow();
529 DCHECK(std::find(children_.begin(), children_.end(), child) ==
532 child->parent()->RemoveChildImpl(child, this);
534 gfx::Vector2d offset;
535 aura::Window* ancestor_with_layer = GetAncestorWithLayer(&offset);
536 if (ancestor_with_layer) {
537 offset += child->bounds().OffsetFromOrigin();
538 child->ReparentLayers(ancestor_with_layer->layer(), offset);
541 child->parent_ = this;
543 children_.push_back(child);
545 layout_manager_->OnWindowAddedToLayout(child);
546 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child));
547 child->OnParentChanged();
549 Window* root_window = GetRootWindow();
550 if (root_window && old_root != root_window) {
551 root_window->GetDispatcher()->OnWindowAddedToRootWindow(child);
552 child->NotifyAddedToRootWindow();
555 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
556 NotifyWindowHierarchyChange(params);
559 void Window::RemoveChild(Window* child) {
560 WindowObserver::HierarchyChangeParams params;
561 params.target = child;
562 params.new_parent = NULL;
563 params.old_parent = this;
564 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
565 NotifyWindowHierarchyChange(params);
567 RemoveChildImpl(child, NULL);
569 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
570 NotifyWindowHierarchyChange(params);
573 bool Window::Contains(const Window* other) const {
574 for (const Window* parent = other; parent; parent = parent->parent_) {
581 Window* Window::GetChildById(int id) {
582 return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id));
585 const Window* Window::GetChildById(int id) const {
586 Windows::const_iterator i;
587 for (i = children_.begin(); i != children_.end(); ++i) {
588 if ((*i)->id() == id)
590 const Window* result = (*i)->GetChildById(id);
598 void Window::ConvertPointToTarget(const Window* source,
599 const Window* target,
603 if (source->GetRootWindow() != target->GetRootWindow()) {
604 client::ScreenPositionClient* source_client =
605 client::GetScreenPositionClient(source->GetRootWindow());
606 source_client->ConvertPointToScreen(source, point);
608 client::ScreenPositionClient* target_client =
609 client::GetScreenPositionClient(target->GetRootWindow());
610 target_client->ConvertPointFromScreen(target, point);
611 } else if ((source != target) && (!source->layer_ || !target->layer_)) {
612 if (!source->layer_) {
613 gfx::Vector2d offset_to_layer;
614 source = source->GetAncestorWithLayer(&offset_to_layer);
615 *point += offset_to_layer;
617 if (!target->layer_) {
618 gfx::Vector2d offset_to_layer;
619 target = target->GetAncestorWithLayer(&offset_to_layer);
620 *point -= offset_to_layer;
622 ui::Layer::ConvertPointToLayer(source->layer_, target->layer_, point);
624 ui::Layer::ConvertPointToLayer(source->layer_, target->layer_, point);
628 void Window::MoveCursorTo(const gfx::Point& point_in_window) {
629 Window* root_window = GetRootWindow();
631 gfx::Point point_in_root(point_in_window);
632 ConvertPointToTarget(this, root_window, &point_in_root);
633 root_window->GetDispatcher()->host()->MoveCursorTo(point_in_root);
636 gfx::NativeCursor Window::GetCursor(const gfx::Point& point) const {
637 return delegate_ ? delegate_->GetCursor(point) : gfx::kNullCursor;
640 void Window::SetEventFilter(ui::EventHandler* event_filter) {
642 RemovePreTargetHandler(event_filter_.get());
643 event_filter_.reset(event_filter);
645 AddPreTargetHandler(event_filter);
648 void Window::AddObserver(WindowObserver* observer) {
649 observers_.AddObserver(observer);
652 void Window::RemoveObserver(WindowObserver* observer) {
653 observers_.RemoveObserver(observer);
656 bool Window::HasObserver(WindowObserver* observer) {
657 return observers_.HasObserver(observer);
660 bool Window::ContainsPointInRoot(const gfx::Point& point_in_root) const {
661 const Window* root_window = GetRootWindow();
664 gfx::Point local_point(point_in_root);
665 ConvertPointToTarget(root_window, this, &local_point);
666 return gfx::Rect(GetTargetBounds().size()).Contains(local_point);
669 bool Window::ContainsPoint(const gfx::Point& local_point) const {
670 return gfx::Rect(bounds().size()).Contains(local_point);
673 bool Window::HitTest(const gfx::Point& local_point) {
674 gfx::Rect local_bounds(bounds().size());
675 if (!delegate_ || !delegate_->HasHitTestMask())
676 return local_bounds.Contains(local_point);
679 delegate_->GetHitTestMask(&mask);
681 SkRegion clip_region;
682 clip_region.setRect(local_bounds.x(), local_bounds.y(),
683 local_bounds.width(), local_bounds.height());
684 SkRegion mask_region;
685 return mask_region.setPath(mask, clip_region) &&
686 mask_region.contains(local_point.x(), local_point.y());
689 Window* Window::GetEventHandlerForPoint(const gfx::Point& local_point) {
690 return GetWindowForPoint(local_point, true, true);
693 Window* Window::GetTopWindowContainingPoint(const gfx::Point& local_point) {
694 return GetWindowForPoint(local_point, false, false);
697 Window* Window::GetToplevelWindow() {
698 Window* topmost_window_with_delegate = NULL;
699 for (aura::Window* window = this; window != NULL; window = window->parent()) {
700 if (window->delegate())
701 topmost_window_with_delegate = window;
703 return topmost_window_with_delegate;
706 void Window::Focus() {
707 client::FocusClient* client = client::GetFocusClient(this);
709 client->FocusWindow(this);
712 void Window::Blur() {
713 client::FocusClient* client = client::GetFocusClient(this);
715 client->FocusWindow(NULL);
718 bool Window::HasFocus() const {
719 client::FocusClient* client = client::GetFocusClient(this);
720 return client && client->GetFocusedWindow() == this;
723 bool Window::CanFocus() const {
727 // NOTE: as part of focusing the window the ActivationClient may make the
728 // window visible (by way of making a hidden ancestor visible). For this
729 // reason we can't check visibility here and assume the client is doing it.
730 if (!parent_ || (delegate_ && !delegate_->CanFocus()))
733 // The client may forbid certain windows from receiving focus at a given point
735 client::EventClient* client = client::GetEventClient(GetRootWindow());
736 if (client && !client->CanProcessEventsWithinSubtree(this))
739 return parent_->CanFocus();
742 bool Window::CanReceiveEvents() const {
746 // The client may forbid certain windows from receiving events at a given
748 client::EventClient* client = client::GetEventClient(GetRootWindow());
749 if (client && !client->CanProcessEventsWithinSubtree(this))
752 return parent_ && IsVisible() && parent_->CanReceiveEvents();
755 void Window::SetCapture() {
759 Window* root_window = GetRootWindow();
762 client::GetCaptureClient(root_window)->SetCapture(this);
765 void Window::ReleaseCapture() {
766 Window* root_window = GetRootWindow();
769 client::GetCaptureClient(root_window)->ReleaseCapture(this);
772 bool Window::HasCapture() {
773 Window* root_window = GetRootWindow();
776 client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
777 return capture_client && capture_client->GetCaptureWindow() == this;
780 void Window::SuppressPaint() {
782 layer_->SuppressPaint();
785 // {Set,Get,Clear}Property are implemented in window_property.h.
787 void Window::SetNativeWindowProperty(const char* key, void* value) {
789 key, key, NULL, reinterpret_cast<int64>(value), 0);
792 void* Window::GetNativeWindowProperty(const char* key) const {
793 return reinterpret_cast<void*>(GetPropertyInternal(key, 0));
796 void Window::OnDeviceScaleFactorChanged(float device_scale_factor) {
797 ScopedCursorHider hider(this);
799 dispatcher_->host()->OnDeviceScaleFactorChanged(device_scale_factor);
801 delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
805 std::string Window::GetDebugInfo() const {
806 return base::StringPrintf(
807 "%s<%d> bounds(%d, %d, %d, %d) %s %s opacity=%.1f",
808 name().empty() ? "Unknown" : name().c_str(), id(),
809 bounds().x(), bounds().y(), bounds().width(), bounds().height(),
810 visible_ ? "WindowVisible" : "WindowHidden",
812 (layer_->GetTargetVisibility() ? "LayerVisible" : "LayerHidden") :
814 layer_ ? layer_->opacity() : 1.0f);
817 void Window::PrintWindowHierarchy(int depth) const {
818 VLOG(0) << base::StringPrintf(
819 "%*s%s", depth * 2, "", GetDebugInfo().c_str());
820 for (Windows::const_iterator it = children_.begin();
821 it != children_.end(); ++it) {
823 child->PrintWindowHierarchy(depth + 1);
828 void Window::RemoveOrDestroyChildren() {
829 while (!children_.empty()) {
830 Window* child = children_[0];
831 if (child->owned_by_parent_) {
833 // Deleting the child so remove it from out children_ list.
834 DCHECK(std::find(children_.begin(), children_.end(), child) ==
837 // Even if we can't delete the child, we still need to remove it from the
838 // parent so that relevant bookkeeping (parent_ back-pointers etc) are
845 ///////////////////////////////////////////////////////////////////////////////
848 int64 Window::SetPropertyInternal(const void* key,
850 PropertyDeallocator deallocator,
852 int64 default_value) {
853 int64 old = GetPropertyInternal(key, default_value);
854 if (value == default_value) {
855 prop_map_.erase(key);
858 prop_value.name = name;
859 prop_value.value = value;
860 prop_value.deallocator = deallocator;
861 prop_map_[key] = prop_value;
863 FOR_EACH_OBSERVER(WindowObserver, observers_,
864 OnWindowPropertyChanged(this, key, old));
868 int64 Window::GetPropertyInternal(const void* key,
869 int64 default_value) const {
870 std::map<const void*, Value>::const_iterator iter = prop_map_.find(key);
871 if (iter == prop_map_.end())
872 return default_value;
873 return iter->second.value;
876 void Window::SetBoundsInternal(const gfx::Rect& new_bounds) {
877 gfx::Rect actual_new_bounds(new_bounds);
879 // Ensure we don't go smaller than our minimum bounds.
881 const gfx::Size& min_size = delegate_->GetMinimumSize();
882 actual_new_bounds.set_width(
883 std::max(min_size.width(), actual_new_bounds.width()));
884 actual_new_bounds.set_height(
885 std::max(min_size.height(), actual_new_bounds.height()));
888 gfx::Rect old_bounds = GetTargetBounds();
890 // Always need to set the layer's bounds -- even if it is to the same thing.
891 // This may cause important side effects such as stopping animation.
893 const gfx::Vector2d origin_delta = new_bounds.OffsetFromOrigin() -
894 bounds_.OffsetFromOrigin();
895 bounds_ = new_bounds;
896 OffsetLayerBounds(origin_delta);
898 if (parent_ && !parent_->layer_) {
899 gfx::Vector2d offset;
900 const aura::Window* ancestor_with_layer =
901 parent_->GetAncestorWithLayer(&offset);
902 if (ancestor_with_layer)
903 actual_new_bounds.Offset(offset);
905 layer_->SetBounds(actual_new_bounds);
908 // If we are currently not the layer's delegate, we will not get bounds
909 // changed notification from the layer (this typically happens after animating
910 // hidden). We must notify ourselves.
911 if (!layer_ || layer_->delegate() != this)
912 OnWindowBoundsChanged(old_bounds, ContainsMouse());
915 void Window::SetVisible(bool visible) {
916 if ((layer_ && visible == layer_->GetTargetVisibility()) ||
917 (!layer_ && visible == visible_))
918 return; // No change.
920 FOR_EACH_OBSERVER(WindowObserver, observers_,
921 OnWindowVisibilityChanging(this, visible));
923 WindowEventDispatcher* dispatcher = GetDispatcher();
925 dispatcher->DispatchMouseExitToHidingWindow(this);
927 client::VisibilityClient* visibility_client =
928 client::GetVisibilityClient(this);
929 if (visibility_client)
930 visibility_client->UpdateLayerVisibility(this, visible);
932 layer_->SetVisible(visible);
935 if (parent_ && parent_->layout_manager_)
936 parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible);
939 delegate_->OnWindowTargetVisibilityChanged(visible);
941 NotifyWindowVisibilityChanged(this, visible);
944 dispatcher->OnWindowVisibilityChanged(this, visible);
947 void Window::SchedulePaint() {
948 SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height()));
951 void Window::Paint(gfx::Canvas* canvas) {
953 delegate_->OnPaint(canvas);
954 PaintLayerlessChildren(canvas);
957 void Window::PaintLayerlessChildren(gfx::Canvas* canvas) {
958 for (size_t i = 0, count = children_.size(); i < count; ++i) {
959 Window* child = children_[i];
960 if (!child->layer_ && child->visible_) {
961 gfx::ScopedCanvas scoped_canvas(canvas);
962 if (canvas->ClipRect(child->bounds())) {
963 canvas->Translate(child->bounds().OffsetFromOrigin());
964 child->Paint(canvas);
970 Window* Window::GetWindowForPoint(const gfx::Point& local_point,
971 bool return_tightest,
972 bool for_event_handling) {
976 if ((for_event_handling && !HitTest(local_point)) ||
977 (!for_event_handling && !ContainsPoint(local_point)))
980 // Check if I should claim this event and not pass it to my children because
981 // the location is inside my hit test override area. For details, see
982 // set_hit_test_bounds_override_inner().
983 if (for_event_handling && !hit_test_bounds_override_inner_.empty()) {
984 gfx::Rect inset_local_bounds(gfx::Point(), bounds().size());
985 inset_local_bounds.Inset(hit_test_bounds_override_inner_);
986 // We know we're inside the normal local bounds, so if we're outside the
987 // inset bounds we must be in the special hit test override area.
988 DCHECK(HitTest(local_point));
989 if (!inset_local_bounds.Contains(local_point))
990 return delegate_ ? this : NULL;
993 if (!return_tightest && delegate_)
996 for (Windows::const_reverse_iterator it = children_.rbegin(),
997 rend = children_.rend();
1001 if (for_event_handling) {
1002 if (child->ignore_events_)
1004 // The client may not allow events to be processed by certain subtrees.
1005 client::EventClient* client = client::GetEventClient(GetRootWindow());
1006 if (client && !client->CanProcessEventsWithinSubtree(child))
1008 if (delegate_ && !delegate_->ShouldDescendIntoChildForEventHandling(
1009 child, local_point))
1013 gfx::Point point_in_child_coords(local_point);
1014 ConvertPointToTarget(this, child, &point_in_child_coords);
1015 Window* match = child->GetWindowForPoint(point_in_child_coords,
1017 for_event_handling);
1022 return delegate_ ? this : NULL;
1025 void Window::RemoveChildImpl(Window* child, Window* new_parent) {
1026 if (layout_manager_)
1027 layout_manager_->OnWillRemoveWindowFromLayout(child);
1028 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child));
1029 Window* root_window = child->GetRootWindow();
1030 Window* new_root_window = new_parent ? new_parent->GetRootWindow() : NULL;
1031 if (root_window && root_window != new_root_window) {
1032 root_window->GetDispatcher()->OnWindowRemovedFromRootWindow(
1033 child, new_root_window);
1034 child->NotifyRemovingFromRootWindow();
1037 gfx::Vector2d offset;
1038 GetAncestorWithLayer(&offset);
1039 child->UnparentLayers(!layer_, offset);
1040 child->parent_ = NULL;
1041 Windows::iterator i = std::find(children_.begin(), children_.end(), child);
1042 DCHECK(i != children_.end());
1044 child->OnParentChanged();
1045 if (layout_manager_)
1046 layout_manager_->OnWindowRemovedFromLayout(child);
1049 void Window::UnparentLayers(bool has_layerless_ancestor,
1050 const gfx::Vector2d& offset) {
1052 const gfx::Vector2d new_offset = offset + bounds().OffsetFromOrigin();
1053 for (size_t i = 0; i < children_.size(); ++i) {
1054 children_[i]->UnparentLayers(true, new_offset);
1057 // Only remove the layer if we still own it. Someone else may have acquired
1058 // ownership of it via AcquireLayer() and may expect the hierarchy to go
1059 // unchanged as the Window is destroyed.
1061 if (layer_->parent())
1062 layer_->parent()->Remove(layer_);
1063 if (has_layerless_ancestor) {
1064 const gfx::Rect real_bounds(bounds_);
1065 gfx::Rect layer_bounds(layer_->bounds());
1066 layer_bounds.Offset(-offset);
1067 layer_->SetBounds(layer_bounds);
1068 bounds_ = real_bounds;
1074 void Window::ReparentLayers(ui::Layer* parent_layer,
1075 const gfx::Vector2d& offset) {
1077 for (size_t i = 0; i < children_.size(); ++i) {
1078 children_[i]->ReparentLayers(
1080 offset + children_[i]->bounds().OffsetFromOrigin());
1083 const gfx::Rect real_bounds(bounds());
1084 parent_layer->Add(layer_);
1085 gfx::Rect layer_bounds(layer_->bounds().size());
1086 layer_bounds += offset;
1087 layer_->SetBounds(layer_bounds);
1088 bounds_ = real_bounds;
1092 void Window::OffsetLayerBounds(const gfx::Vector2d& offset) {
1094 for (size_t i = 0; i < children_.size(); ++i)
1095 children_[i]->OffsetLayerBounds(offset);
1097 gfx::Rect layer_bounds(layer_->bounds());
1098 layer_bounds += offset;
1099 layer_->SetBounds(layer_bounds);
1103 void Window::OnParentChanged() {
1105 WindowObserver, observers_, OnWindowParentChanged(this, parent_));
1108 void Window::StackChildRelativeTo(Window* child,
1110 StackDirection direction) {
1111 DCHECK_NE(child, target);
1114 DCHECK_EQ(this, child->parent());
1115 DCHECK_EQ(this, target->parent());
1117 client::WindowStackingClient* stacking_client =
1118 client::GetWindowStackingClient();
1119 if (stacking_client &&
1120 !stacking_client->AdjustStacking(&child, &target, &direction))
1123 const size_t child_i =
1124 std::find(children_.begin(), children_.end(), child) - children_.begin();
1125 const size_t target_i =
1126 std::find(children_.begin(), children_.end(), target) - children_.begin();
1128 // Don't move the child if it is already in the right place.
1129 if ((direction == STACK_ABOVE && child_i == target_i + 1) ||
1130 (direction == STACK_BELOW && child_i + 1 == target_i))
1133 const size_t dest_i =
1134 direction == STACK_ABOVE ?
1135 (child_i < target_i ? target_i : target_i + 1) :
1136 (child_i < target_i ? target_i - 1 : target_i);
1137 children_.erase(children_.begin() + child_i);
1138 children_.insert(children_.begin() + dest_i, child);
1140 StackChildLayerRelativeTo(child, target, direction);
1142 child->OnStackingChanged();
1145 void Window::StackChildLayerRelativeTo(Window* child,
1147 StackDirection direction) {
1148 Window* ancestor_with_layer = GetAncestorWithLayer(NULL);
1149 ui::Layer* ancestor_layer =
1150 ancestor_with_layer ? ancestor_with_layer->layer() : NULL;
1151 if (!ancestor_layer)
1154 if (child->layer_ && target->layer_) {
1155 if (direction == STACK_ABOVE)
1156 ancestor_layer->StackAbove(child->layer_, target->layer_);
1158 ancestor_layer->StackBelow(child->layer_, target->layer_);
1161 typedef std::vector<ui::Layer*> Layers;
1163 GetLayersToStack(child, &layers);
1167 ui::Layer* target_layer;
1168 if (direction == STACK_ABOVE) {
1170 FindStackingTargetLayer<Windows::const_reverse_iterator>(target, child);
1173 FindStackingTargetLayer<Windows::const_iterator>(target, child);
1176 if (!target_layer) {
1177 if (direction == STACK_ABOVE) {
1178 for (Layers::const_reverse_iterator i = layers.rbegin(),
1179 rend = layers.rend(); i != rend; ++i) {
1180 ancestor_layer->StackAtBottom(*i);
1183 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1184 ancestor_layer->StackAtTop(*i);
1189 if (direction == STACK_ABOVE) {
1190 for (Layers::const_reverse_iterator i = layers.rbegin(),
1191 rend = layers.rend(); i != rend; ++i) {
1192 ancestor_layer->StackAbove(*i, target_layer);
1195 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1196 ancestor_layer->StackBelow(*i, target_layer);
1200 void Window::OnStackingChanged() {
1201 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowStackingChanged(this));
1204 void Window::NotifyRemovingFromRootWindow() {
1205 FOR_EACH_OBSERVER(WindowObserver, observers_,
1206 OnWindowRemovingFromRootWindow(this));
1207 for (Window::Windows::const_iterator it = children_.begin();
1208 it != children_.end(); ++it) {
1209 (*it)->NotifyRemovingFromRootWindow();
1213 void Window::NotifyAddedToRootWindow() {
1214 FOR_EACH_OBSERVER(WindowObserver, observers_,
1215 OnWindowAddedToRootWindow(this));
1216 for (Window::Windows::const_iterator it = children_.begin();
1217 it != children_.end(); ++it) {
1218 (*it)->NotifyAddedToRootWindow();
1222 void Window::NotifyWindowHierarchyChange(
1223 const WindowObserver::HierarchyChangeParams& params) {
1224 params.target->NotifyWindowHierarchyChangeDown(params);
1225 switch (params.phase) {
1226 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1227 if (params.old_parent)
1228 params.old_parent->NotifyWindowHierarchyChangeUp(params);
1230 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1231 if (params.new_parent)
1232 params.new_parent->NotifyWindowHierarchyChangeUp(params);
1240 void Window::NotifyWindowHierarchyChangeDown(
1241 const WindowObserver::HierarchyChangeParams& params) {
1242 NotifyWindowHierarchyChangeAtReceiver(params);
1243 for (Window::Windows::const_iterator it = children_.begin();
1244 it != children_.end(); ++it) {
1245 (*it)->NotifyWindowHierarchyChangeDown(params);
1249 void Window::NotifyWindowHierarchyChangeUp(
1250 const WindowObserver::HierarchyChangeParams& params) {
1251 for (Window* window = this; window; window = window->parent())
1252 window->NotifyWindowHierarchyChangeAtReceiver(params);
1255 void Window::NotifyWindowHierarchyChangeAtReceiver(
1256 const WindowObserver::HierarchyChangeParams& params) {
1257 WindowObserver::HierarchyChangeParams local_params = params;
1258 local_params.receiver = this;
1260 switch (params.phase) {
1261 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1262 FOR_EACH_OBSERVER(WindowObserver, observers_,
1263 OnWindowHierarchyChanging(local_params));
1265 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1266 FOR_EACH_OBSERVER(WindowObserver, observers_,
1267 OnWindowHierarchyChanged(local_params));
1275 void Window::NotifyWindowVisibilityChanged(aura::Window* target,
1277 if (!NotifyWindowVisibilityChangedDown(target, visible)) {
1278 return; // |this| has been deleted.
1280 NotifyWindowVisibilityChangedUp(target, visible);
1283 bool Window::NotifyWindowVisibilityChangedAtReceiver(aura::Window* target,
1285 // |this| may be deleted during a call to OnWindowVisibilityChanged() on one
1286 // of the observers. We create an local observer for that. In that case we
1287 // exit without further access to any members.
1288 WindowTracker tracker;
1290 FOR_EACH_OBSERVER(WindowObserver, observers_,
1291 OnWindowVisibilityChanged(target, visible));
1292 return tracker.Contains(this);
1295 bool Window::NotifyWindowVisibilityChangedDown(aura::Window* target,
1297 if (!NotifyWindowVisibilityChangedAtReceiver(target, visible))
1298 return false; // |this| was deleted.
1299 std::set<const Window*> child_already_processed;
1300 bool child_destroyed = false;
1302 child_destroyed = false;
1303 for (Window::Windows::const_iterator it = children_.begin();
1304 it != children_.end(); ++it) {
1305 if (!child_already_processed.insert(*it).second)
1307 if (!(*it)->NotifyWindowVisibilityChangedDown(target, visible)) {
1308 // |*it| was deleted, |it| is invalid and |children_| has changed.
1309 // We exit the current for-loop and enter a new one.
1310 child_destroyed = true;
1314 } while (child_destroyed);
1318 void Window::NotifyWindowVisibilityChangedUp(aura::Window* target,
1320 for (Window* window = this; window; window = window->parent()) {
1321 bool ret = window->NotifyWindowVisibilityChangedAtReceiver(target, visible);
1326 void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds,
1327 bool contained_mouse) {
1329 bounds_ = layer_->bounds();
1330 if (parent_ && !parent_->layer_) {
1331 gfx::Vector2d offset;
1332 aura::Window* ancestor_with_layer =
1333 parent_->GetAncestorWithLayer(&offset);
1334 if (ancestor_with_layer)
1335 bounds_.Offset(-offset);
1339 if (layout_manager_)
1340 layout_manager_->OnWindowResized();
1342 delegate_->OnBoundsChanged(old_bounds, bounds());
1343 FOR_EACH_OBSERVER(WindowObserver,
1345 OnWindowBoundsChanged(this, old_bounds, bounds()));
1346 WindowEventDispatcher* dispatcher = GetDispatcher();
1348 dispatcher->OnWindowBoundsChanged(this, contained_mouse);
1351 void Window::OnPaintLayer(gfx::Canvas* canvas) {
1355 base::Closure Window::PrepareForLayerBoundsChange() {
1356 return base::Bind(&Window::OnWindowBoundsChanged, base::Unretained(this),
1357 bounds(), ContainsMouse());
1360 bool Window::CanAcceptEvent(const ui::Event& event) {
1361 // The client may forbid certain windows from receiving events at a given
1363 client::EventClient* client = client::GetEventClient(GetRootWindow());
1364 if (client && !client->CanProcessEventsWithinSubtree(this))
1367 // We need to make sure that a touch cancel event and any gesture events it
1368 // creates can always reach the window. This ensures that we receive a valid
1369 // touch / gesture stream.
1370 if (event.IsEndingEvent())
1376 // The top-most window can always process an event.
1380 // For located events (i.e. mouse, touch etc.), an assumption is made that
1381 // windows that don't have a delegate cannot process the event (see more in
1382 // GetWindowForPoint()). This assumption is not made for key events.
1383 return event.IsKeyEvent() || delegate_;
1386 ui::EventTarget* Window::GetParentTarget() {
1388 return client::GetEventClient(this) ?
1389 client::GetEventClient(this)->GetToplevelEventTarget() :
1395 scoped_ptr<ui::EventTargetIterator> Window::GetChildIterator() const {
1396 return scoped_ptr<ui::EventTargetIterator>(
1397 new ui::EventTargetIteratorImpl<Window>(children()));
1400 ui::EventTargeter* Window::GetEventTargeter() {
1401 return targeter_.get();
1404 void Window::ConvertEventToTarget(ui::EventTarget* target,
1405 ui::LocatedEvent* event) {
1406 event->ConvertLocationToTarget(this,
1407 static_cast<Window*>(target));
1410 void Window::UpdateLayerName(const std::string& name) {
1411 #if !defined(NDEBUG)
1414 std::string layer_name(name_);
1415 if (layer_name.empty())
1416 layer_name = "Unnamed Window";
1419 layer_name += " " + base::IntToString(id_);
1421 layer_->set_name(layer_name);
1425 bool Window::ContainsMouse() {
1426 bool contains_mouse = false;
1428 WindowEventDispatcher* dispatcher = GetDispatcher();
1429 contains_mouse = dispatcher &&
1430 ContainsPointInRoot(dispatcher->GetLastMouseLocationInRoot());
1432 return contains_mouse;
1435 const Window* Window::GetAncestorWithLayer(gfx::Vector2d* offset) const {
1436 for (const aura::Window* window = this; window; window = window->parent()) {
1440 *offset += window->bounds().OffsetFromOrigin();
1443 *offset = gfx::Vector2d();