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() {
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 void Window::SetBounds(const gfx::Rect& new_bounds) {
437 if (parent_ && parent_->layout_manager())
438 parent_->layout_manager()->SetChildBounds(this, new_bounds);
440 SetBoundsInternal(new_bounds);
443 void Window::SetBoundsInScreen(const gfx::Rect& new_bounds_in_screen,
444 const gfx::Display& dst_display) {
445 Window* root = GetRootWindow();
447 gfx::Point origin = new_bounds_in_screen.origin();
448 aura::client::ScreenPositionClient* screen_position_client =
449 aura::client::GetScreenPositionClient(root);
450 screen_position_client->SetBounds(this, new_bounds_in_screen, dst_display);
453 SetBounds(new_bounds_in_screen);
456 gfx::Rect Window::GetTargetBounds() const {
460 if (!parent_ || parent_->layer_)
461 return layer_->GetTargetBounds();
463 // We have a layer but our parent (who is valid) doesn't. This means the
464 // coordinates of the layer are relative to the first ancestor with a layer;
465 // convert to be relative to parent.
466 gfx::Vector2d offset;
467 const aura::Window* ancestor_with_layer =
468 parent_->GetAncestorWithLayer(&offset);
469 if (!ancestor_with_layer)
470 return layer_->GetTargetBounds();
472 gfx::Rect layer_target_bounds = layer_->GetTargetBounds();
473 layer_target_bounds -= offset;
474 return layer_target_bounds;
477 void Window::SchedulePaintInRect(const gfx::Rect& rect) {
478 if (!layer_ && parent_) {
479 // Notification of paint scheduled happens for the window with a layer.
480 gfx::Rect parent_rect(bounds().size());
481 parent_rect.Intersect(rect);
482 if (!parent_rect.IsEmpty()) {
483 parent_rect.Offset(bounds().origin().OffsetFromOrigin());
484 parent_->SchedulePaintInRect(parent_rect);
486 } else if (layer_ && layer_->SchedulePaint(rect)) {
488 WindowObserver, observers_, OnWindowPaintScheduled(this, rect));
492 void Window::StackChildAtTop(Window* child) {
493 if (children_.size() <= 1 || child == children_.back())
494 return; // In the front already.
495 StackChildAbove(child, children_.back());
498 void Window::StackChildAbove(Window* child, Window* target) {
499 StackChildRelativeTo(child, target, STACK_ABOVE);
502 void Window::StackChildAtBottom(Window* child) {
503 if (children_.size() <= 1 || child == children_.front())
504 return; // At the bottom already.
505 StackChildBelow(child, children_.front());
508 void Window::StackChildBelow(Window* child, Window* target) {
509 StackChildRelativeTo(child, target, STACK_BELOW);
512 void Window::AddChild(Window* child) {
513 WindowObserver::HierarchyChangeParams params;
514 params.target = child;
515 params.new_parent = this;
516 params.old_parent = child->parent();
517 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
518 NotifyWindowHierarchyChange(params);
520 Window* old_root = child->GetRootWindow();
522 DCHECK(std::find(children_.begin(), children_.end(), child) ==
525 child->parent()->RemoveChildImpl(child, this);
527 gfx::Vector2d offset;
528 aura::Window* ancestor_with_layer = GetAncestorWithLayer(&offset);
529 if (ancestor_with_layer) {
530 offset += child->bounds().OffsetFromOrigin();
531 child->ReparentLayers(ancestor_with_layer->layer(), offset);
534 child->parent_ = this;
536 children_.push_back(child);
538 layout_manager_->OnWindowAddedToLayout(child);
539 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child));
540 child->OnParentChanged();
542 Window* root_window = GetRootWindow();
543 if (root_window && old_root != root_window) {
544 root_window->GetDispatcher()->OnWindowAddedToRootWindow(child);
545 child->NotifyAddedToRootWindow();
548 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
549 NotifyWindowHierarchyChange(params);
552 void Window::RemoveChild(Window* child) {
553 WindowObserver::HierarchyChangeParams params;
554 params.target = child;
555 params.new_parent = NULL;
556 params.old_parent = this;
557 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
558 NotifyWindowHierarchyChange(params);
560 RemoveChildImpl(child, NULL);
562 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
563 NotifyWindowHierarchyChange(params);
566 bool Window::Contains(const Window* other) const {
567 for (const Window* parent = other; parent; parent = parent->parent_) {
574 Window* Window::GetChildById(int id) {
575 return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id));
578 const Window* Window::GetChildById(int id) const {
579 Windows::const_iterator i;
580 for (i = children_.begin(); i != children_.end(); ++i) {
581 if ((*i)->id() == id)
583 const Window* result = (*i)->GetChildById(id);
591 void Window::ConvertPointToTarget(const Window* source,
592 const Window* target,
596 if (source->GetRootWindow() != target->GetRootWindow()) {
597 client::ScreenPositionClient* source_client =
598 client::GetScreenPositionClient(source->GetRootWindow());
599 source_client->ConvertPointToScreen(source, point);
601 client::ScreenPositionClient* target_client =
602 client::GetScreenPositionClient(target->GetRootWindow());
603 target_client->ConvertPointFromScreen(target, point);
604 } else if ((source != target) && (!source->layer_ || !target->layer_)) {
605 if (!source->layer_) {
606 gfx::Vector2d offset_to_layer;
607 source = source->GetAncestorWithLayer(&offset_to_layer);
608 *point += offset_to_layer;
610 if (!target->layer_) {
611 gfx::Vector2d offset_to_layer;
612 target = target->GetAncestorWithLayer(&offset_to_layer);
613 *point -= offset_to_layer;
615 ui::Layer::ConvertPointToLayer(source->layer_, target->layer_, point);
617 ui::Layer::ConvertPointToLayer(source->layer_, target->layer_, point);
621 void Window::MoveCursorTo(const gfx::Point& point_in_window) {
622 Window* root_window = GetRootWindow();
624 gfx::Point point_in_root(point_in_window);
625 ConvertPointToTarget(this, root_window, &point_in_root);
626 root_window->GetDispatcher()->MoveCursorTo(point_in_root);
629 gfx::NativeCursor Window::GetCursor(const gfx::Point& point) const {
630 return delegate_ ? delegate_->GetCursor(point) : gfx::kNullCursor;
633 void Window::SetEventFilter(ui::EventHandler* event_filter) {
635 RemovePreTargetHandler(event_filter_.get());
636 event_filter_.reset(event_filter);
638 AddPreTargetHandler(event_filter);
641 void Window::AddObserver(WindowObserver* observer) {
642 observers_.AddObserver(observer);
645 void Window::RemoveObserver(WindowObserver* observer) {
646 observers_.RemoveObserver(observer);
649 bool Window::HasObserver(WindowObserver* observer) {
650 return observers_.HasObserver(observer);
653 bool Window::ContainsPointInRoot(const gfx::Point& point_in_root) const {
654 const Window* root_window = GetRootWindow();
657 gfx::Point local_point(point_in_root);
658 ConvertPointToTarget(root_window, this, &local_point);
659 return gfx::Rect(GetTargetBounds().size()).Contains(local_point);
662 bool Window::ContainsPoint(const gfx::Point& local_point) const {
663 return gfx::Rect(bounds().size()).Contains(local_point);
666 bool Window::HitTest(const gfx::Point& local_point) {
667 // Expand my bounds for hit testing (override is usually zero but it's
668 // probably cheaper to do the math every time than to branch).
669 gfx::Rect local_bounds(gfx::Point(), bounds().size());
670 local_bounds.Inset(aura::Env::GetInstance()->is_touch_down() ?
671 hit_test_bounds_override_outer_touch_ :
672 hit_test_bounds_override_outer_mouse_);
674 if (!delegate_ || !delegate_->HasHitTestMask())
675 return local_bounds.Contains(local_point);
678 delegate_->GetHitTestMask(&mask);
680 SkRegion clip_region;
681 clip_region.setRect(local_bounds.x(), local_bounds.y(),
682 local_bounds.width(), local_bounds.height());
683 SkRegion mask_region;
684 return mask_region.setPath(mask, clip_region) &&
685 mask_region.contains(local_point.x(), local_point.y());
688 Window* Window::GetEventHandlerForPoint(const gfx::Point& local_point) {
689 return GetWindowForPoint(local_point, true, true);
692 Window* Window::GetTopWindowContainingPoint(const gfx::Point& local_point) {
693 return GetWindowForPoint(local_point, false, false);
696 Window* Window::GetToplevelWindow() {
697 Window* topmost_window_with_delegate = NULL;
698 for (aura::Window* window = this; window != NULL; window = window->parent()) {
699 if (window->delegate())
700 topmost_window_with_delegate = window;
702 return topmost_window_with_delegate;
705 void Window::Focus() {
706 client::FocusClient* client = client::GetFocusClient(this);
708 client->FocusWindow(this);
711 void Window::Blur() {
712 client::FocusClient* client = client::GetFocusClient(this);
714 client->FocusWindow(NULL);
717 bool Window::HasFocus() const {
718 client::FocusClient* client = client::GetFocusClient(this);
719 return client && client->GetFocusedWindow() == this;
722 bool Window::CanFocus() const {
726 // NOTE: as part of focusing the window the ActivationClient may make the
727 // window visible (by way of making a hidden ancestor visible). For this
728 // reason we can't check visibility here and assume the client is doing it.
729 if (!parent_ || (delegate_ && !delegate_->CanFocus()))
732 // The client may forbid certain windows from receiving focus at a given point
734 client::EventClient* client = client::GetEventClient(GetRootWindow());
735 if (client && !client->CanProcessEventsWithinSubtree(this))
738 return parent_->CanFocus();
741 bool Window::CanReceiveEvents() const {
745 // The client may forbid certain windows from receiving events at a given
747 client::EventClient* client = client::GetEventClient(GetRootWindow());
748 if (client && !client->CanProcessEventsWithinSubtree(this))
751 return parent_ && IsVisible() && parent_->CanReceiveEvents();
754 void Window::SetCapture() {
758 Window* root_window = GetRootWindow();
761 client::GetCaptureClient(root_window)->SetCapture(this);
764 void Window::ReleaseCapture() {
765 Window* root_window = GetRootWindow();
768 client::GetCaptureClient(root_window)->ReleaseCapture(this);
771 bool Window::HasCapture() {
772 Window* root_window = GetRootWindow();
775 client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
776 return capture_client && capture_client->GetCaptureWindow() == this;
779 void Window::SuppressPaint() {
781 layer_->SuppressPaint();
784 // {Set,Get,Clear}Property are implemented in window_property.h.
786 void Window::SetNativeWindowProperty(const char* key, void* value) {
788 key, key, NULL, reinterpret_cast<int64>(value), 0);
791 void* Window::GetNativeWindowProperty(const char* key) const {
792 return reinterpret_cast<void*>(GetPropertyInternal(key, 0));
795 void Window::OnDeviceScaleFactorChanged(float device_scale_factor) {
796 ScopedCursorHider hider(this);
798 dispatcher_->host()->OnDeviceScaleFactorChanged(device_scale_factor);
800 delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
804 std::string Window::GetDebugInfo() const {
805 return base::StringPrintf(
806 "%s<%d> bounds(%d, %d, %d, %d) %s %s opacity=%.1f",
807 name().empty() ? "Unknown" : name().c_str(), id(),
808 bounds().x(), bounds().y(), bounds().width(), bounds().height(),
809 visible_ ? "WindowVisible" : "WindowHidden",
811 (layer_->GetTargetVisibility() ? "LayerVisible" : "LayerHidden") :
813 layer_ ? layer_->opacity() : 1.0f);
816 void Window::PrintWindowHierarchy(int depth) const {
817 VLOG(0) << base::StringPrintf(
818 "%*s%s", depth * 2, "", GetDebugInfo().c_str());
819 for (Windows::const_iterator it = children_.begin();
820 it != children_.end(); ++it) {
822 child->PrintWindowHierarchy(depth + 1);
827 void Window::RemoveOrDestroyChildren() {
828 while (!children_.empty()) {
829 Window* child = children_[0];
830 if (child->owned_by_parent_) {
832 // Deleting the child so remove it from out children_ list.
833 DCHECK(std::find(children_.begin(), children_.end(), child) ==
836 // Even if we can't delete the child, we still need to remove it from the
837 // parent so that relevant bookkeeping (parent_ back-pointers etc) are
844 ///////////////////////////////////////////////////////////////////////////////
847 int64 Window::SetPropertyInternal(const void* key,
849 PropertyDeallocator deallocator,
851 int64 default_value) {
852 int64 old = GetPropertyInternal(key, default_value);
853 if (value == default_value) {
854 prop_map_.erase(key);
857 prop_value.name = name;
858 prop_value.value = value;
859 prop_value.deallocator = deallocator;
860 prop_map_[key] = prop_value;
862 FOR_EACH_OBSERVER(WindowObserver, observers_,
863 OnWindowPropertyChanged(this, key, old));
867 int64 Window::GetPropertyInternal(const void* key,
868 int64 default_value) const {
869 std::map<const void*, Value>::const_iterator iter = prop_map_.find(key);
870 if (iter == prop_map_.end())
871 return default_value;
872 return iter->second.value;
875 void Window::SetBoundsInternal(const gfx::Rect& new_bounds) {
876 gfx::Rect actual_new_bounds(new_bounds);
878 // Ensure we don't go smaller than our minimum bounds.
880 const gfx::Size& min_size = delegate_->GetMinimumSize();
881 actual_new_bounds.set_width(
882 std::max(min_size.width(), actual_new_bounds.width()));
883 actual_new_bounds.set_height(
884 std::max(min_size.height(), actual_new_bounds.height()));
887 gfx::Rect old_bounds = GetTargetBounds();
889 // Always need to set the layer's bounds -- even if it is to the same thing.
890 // This may cause important side effects such as stopping animation.
892 const gfx::Vector2d origin_delta = new_bounds.OffsetFromOrigin() -
893 bounds_.OffsetFromOrigin();
894 bounds_ = new_bounds;
895 OffsetLayerBounds(origin_delta);
897 if (parent_ && !parent_->layer_) {
898 gfx::Vector2d offset;
899 const aura::Window* ancestor_with_layer =
900 parent_->GetAncestorWithLayer(&offset);
901 if (ancestor_with_layer)
902 actual_new_bounds.Offset(offset);
904 layer_->SetBounds(actual_new_bounds);
907 // If we are currently not the layer's delegate, we will not get bounds
908 // changed notification from the layer (this typically happens after animating
909 // hidden). We must notify ourselves.
910 if (!layer_ || layer_->delegate() != this)
911 OnWindowBoundsChanged(old_bounds, ContainsMouse());
914 void Window::SetVisible(bool visible) {
915 if ((layer_ && visible == layer_->GetTargetVisibility()) ||
916 (!layer_ && visible == visible_))
917 return; // No change.
919 FOR_EACH_OBSERVER(WindowObserver, observers_,
920 OnWindowVisibilityChanging(this, visible));
922 WindowEventDispatcher* dispatcher = GetDispatcher();
924 dispatcher->DispatchMouseExitToHidingWindow(this);
926 client::VisibilityClient* visibility_client =
927 client::GetVisibilityClient(this);
928 if (visibility_client)
929 visibility_client->UpdateLayerVisibility(this, visible);
931 layer_->SetVisible(visible);
934 if (parent_ && parent_->layout_manager_)
935 parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible);
938 delegate_->OnWindowTargetVisibilityChanged(visible);
940 NotifyWindowVisibilityChanged(this, visible);
943 dispatcher->OnWindowVisibilityChanged(this, visible);
946 void Window::SchedulePaint() {
947 SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height()));
950 void Window::Paint(gfx::Canvas* canvas) {
952 delegate_->OnPaint(canvas);
953 PaintLayerlessChildren(canvas);
956 void Window::PaintLayerlessChildren(gfx::Canvas* canvas) {
957 for (size_t i = 0, count = children_.size(); i < count; ++i) {
958 Window* child = children_[i];
959 if (!child->layer_ && child->visible_) {
960 gfx::ScopedCanvas scoped_canvas(canvas);
961 if (canvas->ClipRect(child->bounds())) {
962 canvas->Translate(child->bounds().OffsetFromOrigin());
963 child->Paint(canvas);
969 Window* Window::GetWindowForPoint(const gfx::Point& local_point,
970 bool return_tightest,
971 bool for_event_handling) {
975 if ((for_event_handling && !HitTest(local_point)) ||
976 (!for_event_handling && !ContainsPoint(local_point)))
979 // Check if I should claim this event and not pass it to my children because
980 // the location is inside my hit test override area. For details, see
981 // set_hit_test_bounds_override_inner().
982 if (for_event_handling && !hit_test_bounds_override_inner_.empty()) {
983 gfx::Rect inset_local_bounds(gfx::Point(), bounds().size());
984 inset_local_bounds.Inset(hit_test_bounds_override_inner_);
985 // We know we're inside the normal local bounds, so if we're outside the
986 // inset bounds we must be in the special hit test override area.
987 DCHECK(HitTest(local_point));
988 if (!inset_local_bounds.Contains(local_point))
989 return delegate_ ? this : NULL;
992 if (!return_tightest && delegate_)
995 for (Windows::const_reverse_iterator it = children_.rbegin(),
996 rend = children_.rend();
1000 if (for_event_handling) {
1001 if (child->ignore_events_)
1003 // The client may not allow events to be processed by certain subtrees.
1004 client::EventClient* client = client::GetEventClient(GetRootWindow());
1005 if (client && !client->CanProcessEventsWithinSubtree(child))
1007 if (delegate_ && !delegate_->ShouldDescendIntoChildForEventHandling(
1008 child, local_point))
1012 gfx::Point point_in_child_coords(local_point);
1013 ConvertPointToTarget(this, child, &point_in_child_coords);
1014 Window* match = child->GetWindowForPoint(point_in_child_coords,
1016 for_event_handling);
1021 return delegate_ ? this : NULL;
1024 void Window::RemoveChildImpl(Window* child, Window* new_parent) {
1025 if (layout_manager_)
1026 layout_manager_->OnWillRemoveWindowFromLayout(child);
1027 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child));
1028 Window* root_window = child->GetRootWindow();
1029 Window* new_root_window = new_parent ? new_parent->GetRootWindow() : NULL;
1030 if (root_window && root_window != new_root_window) {
1031 root_window->GetDispatcher()->OnWindowRemovedFromRootWindow(
1032 child, new_root_window);
1033 child->NotifyRemovingFromRootWindow();
1036 gfx::Vector2d offset;
1037 GetAncestorWithLayer(&offset);
1038 child->UnparentLayers(!layer_, offset);
1039 child->parent_ = NULL;
1040 Windows::iterator i = std::find(children_.begin(), children_.end(), child);
1041 DCHECK(i != children_.end());
1043 child->OnParentChanged();
1044 if (layout_manager_)
1045 layout_manager_->OnWindowRemovedFromLayout(child);
1048 void Window::UnparentLayers(bool has_layerless_ancestor,
1049 const gfx::Vector2d& offset) {
1051 const gfx::Vector2d new_offset = offset + bounds().OffsetFromOrigin();
1052 for (size_t i = 0; i < children_.size(); ++i) {
1053 children_[i]->UnparentLayers(true, new_offset);
1056 // Only remove the layer if we still own it. Someone else may have acquired
1057 // ownership of it via AcquireLayer() and may expect the hierarchy to go
1058 // unchanged as the Window is destroyed.
1060 if (layer_->parent())
1061 layer_->parent()->Remove(layer_);
1062 if (has_layerless_ancestor) {
1063 const gfx::Rect real_bounds(bounds_);
1064 gfx::Rect layer_bounds(layer_->bounds());
1065 layer_bounds.Offset(-offset);
1066 layer_->SetBounds(layer_bounds);
1067 bounds_ = real_bounds;
1073 void Window::ReparentLayers(ui::Layer* parent_layer,
1074 const gfx::Vector2d& offset) {
1076 for (size_t i = 0; i < children_.size(); ++i) {
1077 children_[i]->ReparentLayers(
1079 offset + children_[i]->bounds().OffsetFromOrigin());
1082 const gfx::Rect real_bounds(bounds());
1083 parent_layer->Add(layer_);
1084 gfx::Rect layer_bounds(layer_->bounds().size());
1085 layer_bounds += offset;
1086 layer_->SetBounds(layer_bounds);
1087 bounds_ = real_bounds;
1091 void Window::OffsetLayerBounds(const gfx::Vector2d& offset) {
1093 for (size_t i = 0; i < children_.size(); ++i)
1094 children_[i]->OffsetLayerBounds(offset);
1096 gfx::Rect layer_bounds(layer_->bounds());
1097 layer_bounds += offset;
1098 layer_->SetBounds(layer_bounds);
1102 void Window::OnParentChanged() {
1104 WindowObserver, observers_, OnWindowParentChanged(this, parent_));
1107 void Window::StackChildRelativeTo(Window* child,
1109 StackDirection direction) {
1110 DCHECK_NE(child, target);
1113 DCHECK_EQ(this, child->parent());
1114 DCHECK_EQ(this, target->parent());
1116 client::WindowStackingClient* stacking_client =
1117 client::GetWindowStackingClient();
1118 if (stacking_client &&
1119 !stacking_client->AdjustStacking(&child, &target, &direction))
1122 const size_t child_i =
1123 std::find(children_.begin(), children_.end(), child) - children_.begin();
1124 const size_t target_i =
1125 std::find(children_.begin(), children_.end(), target) - children_.begin();
1127 // Don't move the child if it is already in the right place.
1128 if ((direction == STACK_ABOVE && child_i == target_i + 1) ||
1129 (direction == STACK_BELOW && child_i + 1 == target_i))
1132 const size_t dest_i =
1133 direction == STACK_ABOVE ?
1134 (child_i < target_i ? target_i : target_i + 1) :
1135 (child_i < target_i ? target_i - 1 : target_i);
1136 children_.erase(children_.begin() + child_i);
1137 children_.insert(children_.begin() + dest_i, child);
1139 StackChildLayerRelativeTo(child, target, direction);
1141 child->OnStackingChanged();
1144 void Window::StackChildLayerRelativeTo(Window* child,
1146 StackDirection direction) {
1147 Window* ancestor_with_layer = GetAncestorWithLayer(NULL);
1148 ui::Layer* ancestor_layer =
1149 ancestor_with_layer ? ancestor_with_layer->layer() : NULL;
1150 if (!ancestor_layer)
1153 if (child->layer_ && target->layer_) {
1154 if (direction == STACK_ABOVE)
1155 ancestor_layer->StackAbove(child->layer_, target->layer_);
1157 ancestor_layer->StackBelow(child->layer_, target->layer_);
1160 typedef std::vector<ui::Layer*> Layers;
1162 GetLayersToStack(child, &layers);
1166 ui::Layer* target_layer;
1167 if (direction == STACK_ABOVE) {
1169 FindStackingTargetLayer<Windows::const_reverse_iterator>(target, child);
1172 FindStackingTargetLayer<Windows::const_iterator>(target, child);
1175 if (!target_layer) {
1176 if (direction == STACK_ABOVE) {
1177 for (Layers::const_reverse_iterator i = layers.rbegin(),
1178 rend = layers.rend(); i != rend; ++i) {
1179 ancestor_layer->StackAtBottom(*i);
1182 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1183 ancestor_layer->StackAtTop(*i);
1188 if (direction == STACK_ABOVE) {
1189 for (Layers::const_reverse_iterator i = layers.rbegin(),
1190 rend = layers.rend(); i != rend; ++i) {
1191 ancestor_layer->StackAbove(*i, target_layer);
1194 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1195 ancestor_layer->StackBelow(*i, target_layer);
1199 void Window::OnStackingChanged() {
1200 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowStackingChanged(this));
1203 void Window::NotifyRemovingFromRootWindow() {
1204 FOR_EACH_OBSERVER(WindowObserver, observers_,
1205 OnWindowRemovingFromRootWindow(this));
1206 for (Window::Windows::const_iterator it = children_.begin();
1207 it != children_.end(); ++it) {
1208 (*it)->NotifyRemovingFromRootWindow();
1212 void Window::NotifyAddedToRootWindow() {
1213 FOR_EACH_OBSERVER(WindowObserver, observers_,
1214 OnWindowAddedToRootWindow(this));
1215 for (Window::Windows::const_iterator it = children_.begin();
1216 it != children_.end(); ++it) {
1217 (*it)->NotifyAddedToRootWindow();
1221 void Window::NotifyWindowHierarchyChange(
1222 const WindowObserver::HierarchyChangeParams& params) {
1223 params.target->NotifyWindowHierarchyChangeDown(params);
1224 switch (params.phase) {
1225 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1226 if (params.old_parent)
1227 params.old_parent->NotifyWindowHierarchyChangeUp(params);
1229 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1230 if (params.new_parent)
1231 params.new_parent->NotifyWindowHierarchyChangeUp(params);
1239 void Window::NotifyWindowHierarchyChangeDown(
1240 const WindowObserver::HierarchyChangeParams& params) {
1241 NotifyWindowHierarchyChangeAtReceiver(params);
1242 for (Window::Windows::const_iterator it = children_.begin();
1243 it != children_.end(); ++it) {
1244 (*it)->NotifyWindowHierarchyChangeDown(params);
1248 void Window::NotifyWindowHierarchyChangeUp(
1249 const WindowObserver::HierarchyChangeParams& params) {
1250 for (Window* window = this; window; window = window->parent())
1251 window->NotifyWindowHierarchyChangeAtReceiver(params);
1254 void Window::NotifyWindowHierarchyChangeAtReceiver(
1255 const WindowObserver::HierarchyChangeParams& params) {
1256 WindowObserver::HierarchyChangeParams local_params = params;
1257 local_params.receiver = this;
1259 switch (params.phase) {
1260 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1261 FOR_EACH_OBSERVER(WindowObserver, observers_,
1262 OnWindowHierarchyChanging(local_params));
1264 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1265 FOR_EACH_OBSERVER(WindowObserver, observers_,
1266 OnWindowHierarchyChanged(local_params));
1274 void Window::NotifyWindowVisibilityChanged(aura::Window* target,
1276 if (!NotifyWindowVisibilityChangedDown(target, visible)) {
1277 return; // |this| has been deleted.
1279 NotifyWindowVisibilityChangedUp(target, visible);
1282 bool Window::NotifyWindowVisibilityChangedAtReceiver(aura::Window* target,
1284 // |this| may be deleted during a call to OnWindowVisibilityChanged() on one
1285 // of the observers. We create an local observer for that. In that case we
1286 // exit without further access to any members.
1287 WindowTracker tracker;
1289 FOR_EACH_OBSERVER(WindowObserver, observers_,
1290 OnWindowVisibilityChanged(target, visible));
1291 return tracker.Contains(this);
1294 bool Window::NotifyWindowVisibilityChangedDown(aura::Window* target,
1296 if (!NotifyWindowVisibilityChangedAtReceiver(target, visible))
1297 return false; // |this| was deleted.
1298 std::set<const Window*> child_already_processed;
1299 bool child_destroyed = false;
1301 child_destroyed = false;
1302 for (Window::Windows::const_iterator it = children_.begin();
1303 it != children_.end(); ++it) {
1304 if (!child_already_processed.insert(*it).second)
1306 if (!(*it)->NotifyWindowVisibilityChangedDown(target, visible)) {
1307 // |*it| was deleted, |it| is invalid and |children_| has changed.
1308 // We exit the current for-loop and enter a new one.
1309 child_destroyed = true;
1313 } while (child_destroyed);
1317 void Window::NotifyWindowVisibilityChangedUp(aura::Window* target,
1319 for (Window* window = this; window; window = window->parent()) {
1320 bool ret = window->NotifyWindowVisibilityChangedAtReceiver(target, visible);
1325 void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds,
1326 bool contained_mouse) {
1328 bounds_ = layer_->bounds();
1329 if (parent_ && !parent_->layer_) {
1330 gfx::Vector2d offset;
1331 aura::Window* ancestor_with_layer =
1332 parent_->GetAncestorWithLayer(&offset);
1333 if (ancestor_with_layer)
1334 bounds_.Offset(-offset);
1338 if (layout_manager_)
1339 layout_manager_->OnWindowResized();
1341 delegate_->OnBoundsChanged(old_bounds, bounds());
1342 FOR_EACH_OBSERVER(WindowObserver,
1344 OnWindowBoundsChanged(this, old_bounds, bounds()));
1345 WindowEventDispatcher* dispatcher = GetDispatcher();
1347 dispatcher->OnWindowBoundsChanged(this, contained_mouse);
1350 void Window::OnPaintLayer(gfx::Canvas* canvas) {
1354 base::Closure Window::PrepareForLayerBoundsChange() {
1355 return base::Bind(&Window::OnWindowBoundsChanged, base::Unretained(this),
1356 bounds(), ContainsMouse());
1359 bool Window::CanAcceptEvent(const ui::Event& event) {
1360 // The client may forbid certain windows from receiving events at a given
1362 client::EventClient* client = client::GetEventClient(GetRootWindow());
1363 if (client && !client->CanProcessEventsWithinSubtree(this))
1366 // We need to make sure that a touch cancel event and any gesture events it
1367 // creates can always reach the window. This ensures that we receive a valid
1368 // touch / gesture stream.
1369 if (event.IsEndingEvent())
1375 // The top-most window can always process an event.
1379 // For located events (i.e. mouse, touch etc.), an assumption is made that
1380 // windows that don't have a delegate cannot process the event (see more in
1381 // GetWindowForPoint()). This assumption is not made for key events.
1382 return event.IsKeyEvent() || delegate_;
1385 ui::EventTarget* Window::GetParentTarget() {
1387 return client::GetEventClient(this) ?
1388 client::GetEventClient(this)->GetToplevelEventTarget() :
1394 scoped_ptr<ui::EventTargetIterator> Window::GetChildIterator() const {
1395 return scoped_ptr<ui::EventTargetIterator>(
1396 new ui::EventTargetIteratorImpl<Window>(children()));
1399 ui::EventTargeter* Window::GetEventTargeter() {
1400 return targeter_.get();
1403 void Window::ConvertEventToTarget(ui::EventTarget* target,
1404 ui::LocatedEvent* event) {
1405 event->ConvertLocationToTarget(this,
1406 static_cast<Window*>(target));
1409 void Window::UpdateLayerName(const std::string& name) {
1410 #if !defined(NDEBUG)
1413 std::string layer_name(name_);
1414 if (layer_name.empty())
1415 layer_name = "Unnamed Window";
1418 layer_name += " " + base::IntToString(id_);
1420 layer_->set_name(layer_name);
1424 bool Window::ContainsMouse() {
1425 bool contains_mouse = false;
1427 WindowEventDispatcher* dispatcher = GetDispatcher();
1428 contains_mouse = dispatcher &&
1429 ContainsPointInRoot(dispatcher->GetLastMouseLocationInRoot());
1431 return contains_mouse;
1434 const Window* Window::GetAncestorWithLayer(gfx::Vector2d* offset) const {
1435 for (const aura::Window* window = this; window; window = window->parent()) {
1439 *offset += window->bounds().OffsetFromOrigin();
1442 *offset = gfx::Vector2d();