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/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"
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_
->IsRootWindow())
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_
->IsRootWindow())
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 if (layer()->owner() == this)
223 layer()->CompleteAllAnimations();
224 layer()->SuppressPaint();
227 // Let the delegate know we're in the processing of destroying.
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();
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.
261 parent_
->RemoveChild(this);
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);
273 for (std::map
<const void*, Value
>::const_iterator iter
= prop_map_
.begin();
274 iter
!= prop_map_
.end();
276 if (iter
->second
.deallocator
)
277 (*iter
->second
.deallocator
)(iter
->second
.value
);
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
285 layer()->set_delegate(NULL
);
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);
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.
307 void Window::SetName(const std::string
& name
) {
314 void Window::SetTitle(const base::string16
& title
) {
316 FOR_EACH_OBSERVER(WindowObserver
,
318 OnWindowTitleChanged(this));
321 void Window::SetTransparent(bool transparent
) {
322 transparent_
= transparent
;
324 layer()->SetFillsBoundsOpaquely(!transparent_
);
327 void Window::SetFillsBoundsCompletely(bool fills_bounds
) {
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)->
346 const WindowTreeHost
* Window::GetHost() const {
347 const Window
* root_window
= GetRootWindow();
348 return root_window
? root_window
->host_
: NULL
;
351 void Window::Show() {
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
));
362 void Window::Hide() {
363 // RootWindow::OnVisibilityChanged will call ReleaseCapture.
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_
)
376 return window
->layer()->IsDrawn();
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
385 if (!GetRootWindow())
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();
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
);
407 void Window::SetTransform(const gfx::Transform
& transform
) {
409 // Transforms aren't supported on layerless windows.
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_
)
424 layout_manager_
.reset(layout_manager
);
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();
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
);
446 // Ensure we don't go smaller than our minimum bounds.
447 gfx::Rect
final_bounds(new_bounds
);
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();
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
);
468 SetBounds(new_bounds_in_screen
);
471 gfx::Rect
Window::GetTargetBounds() const {
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
) ==
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
);
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_
) {
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
)
598 const Window
* result
= (*i
)->GetChildById(id
);
606 void Window::ConvertPointToTarget(const Window
* source
,
607 const Window
* target
,
611 if (source
->GetRootWindow() != target
->GetRootWindow()) {
612 client::ScreenPositionClient
* source_client
=
613 client::GetScreenPositionClient(source
->GetRootWindow());
614 // |source_client| can be NULL in tests.
616 source_client
->ConvertPointToScreen(source
, point
);
618 client::ScreenPositionClient
* target_client
=
619 client::GetScreenPositionClient(target
->GetRootWindow());
620 // |target_client| can be NULL in tests.
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
);
636 ui::Layer::ConvertPointToLayer(source
->layer(), target
->layer(), point
);
641 void Window::ConvertRectToTarget(const Window
* source
,
642 const Window
* target
,
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();
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();
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);
713 client
->FocusWindow(this);
716 void Window::Blur() {
717 client::FocusClient
* client
= client::GetFocusClient(this);
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 {
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()))
737 // The client may forbid certain windows from receiving focus at a given point
739 client::EventClient
* client
= client::GetEventClient(GetRootWindow());
740 if (client
&& !client
->CanProcessEventsWithinSubtree(this))
743 return parent_
->CanFocus();
746 bool Window::CanReceiveEvents() const {
750 // The client may forbid certain windows from receiving events at a given
752 client::EventClient
* client
= client::GetEventClient(GetRootWindow());
753 if (client
&& !client
->CanProcessEventsWithinSubtree(this))
756 return parent_
&& IsVisible() && parent_
->CanReceiveEvents();
759 void Window::SetCapture() {
763 Window
* root_window
= GetRootWindow();
766 client::CaptureClient
* capture_client
= client::GetCaptureClient(root_window
);
769 client::GetCaptureClient(root_window
)->SetCapture(this);
772 void Window::ReleaseCapture() {
773 Window
* root_window
= GetRootWindow();
776 client::CaptureClient
* capture_client
= client::GetCaptureClient(root_window
);
779 client::GetCaptureClient(root_window
)->ReleaseCapture(this);
782 bool Window::HasCapture() {
783 Window
* root_window
= GetRootWindow();
786 client::CaptureClient
* capture_client
= client::GetCaptureClient(root_window
);
787 return capture_client
&& capture_client
->GetCaptureWindow() == this;
790 void Window::SuppressPaint() {
792 layer()->SuppressPaint();
795 // {Set,Get,Clear}Property are implemented in window_property.h.
797 void Window::SetNativeWindowProperty(const char* key
, void* value
) {
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);
809 delegate_
->OnDeviceScaleFactorChanged(device_scale_factor
);
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",
820 (layer()->GetTargetVisibility() ? "LayerVisible" : "LayerHidden") :
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
) {
831 child
->PrintWindowHierarchy(depth
+ 1);
836 void Window::RemoveOrDestroyChildren() {
837 while (!children_
.empty()) {
838 Window
* child
= children_
[0];
839 if (child
->owned_by_parent_
) {
841 // Deleting the child so remove it from out children_ list.
842 DCHECK(std::find(children_
.begin(), children_
.end(), child
) ==
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
853 ///////////////////////////////////////////////////////////////////////////////
856 int64
Window::SetPropertyInternal(const void* key
,
858 PropertyDeallocator deallocator
,
860 int64 default_value
) {
861 int64 old
= GetPropertyInternal(key
, default_value
);
862 if (value
== default_value
) {
863 prop_map_
.erase(key
);
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
));
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
);
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.
907 const gfx::Vector2d origin_delta
= new_bounds
.OffsetFromOrigin() -
908 bounds_
.OffsetFromOrigin();
909 bounds_
= new_bounds
;
910 OffsetLayerBounds(origin_delta
);
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
);
946 layer()->SetVisible(visible
);
949 if (parent_
&& parent_
->layout_manager_
)
950 parent_
->layout_manager_
->OnChildWindowVisibilityChanged(this, visible
);
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
) {
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
) {
988 if ((for_event_handling
&& !HitTest(local_point
)) ||
989 (!for_event_handling
&& !ContainsPoint(local_point
)))
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_
)
1008 for (Windows::const_reverse_iterator it
= children_
.rbegin(),
1009 rend
= children_
.rend();
1011 Window
* child
= *it
;
1013 if (for_event_handling
) {
1014 if (child
->ignore_events_
)
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
))
1020 if (delegate_
&& !delegate_
->ShouldDescendIntoChildForEventHandling(
1021 child
, local_point
))
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
,
1029 for_event_handling
);
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());
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
) {
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
);
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.
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
) {
1086 for (size_t i
= 0; i
< children_
.size(); ++i
) {
1087 children_
[i
]->ReparentLayers(
1089 offset
+ children_
[i
]->bounds().OffsetFromOrigin());
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
) {
1103 for (size_t i
= 0; i
< children_
.size(); ++i
)
1104 children_
[i
]->OffsetLayerBounds(offset
);
1106 gfx::Rect
layer_bounds(layer()->bounds());
1107 layer_bounds
+= offset
;
1108 layer()->SetBounds(layer_bounds
);
1112 void Window::OnParentChanged() {
1114 WindowObserver
, observers_
, OnWindowParentChanged(this, parent_
));
1117 void Window::StackChildRelativeTo(Window
* child
,
1119 StackDirection direction
) {
1120 DCHECK_NE(child
, 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
))
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
))
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
,
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
)
1163 if (child
->layer() && target
->layer()) {
1164 if (direction
== STACK_ABOVE
)
1165 ancestor_layer
->StackAbove(child
->layer(), target
->layer());
1167 ancestor_layer
->StackBelow(child
->layer(), target
->layer());
1170 typedef std::vector
<ui::Layer
*> Layers
;
1172 GetLayersToStack(child
, &layers
);
1176 ui::Layer
* target_layer
;
1177 if (direction
== STACK_ABOVE
) {
1179 FindStackingTargetLayer
<Windows::const_reverse_iterator
>(target
, child
);
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
);
1192 for (Layers::const_iterator i
= layers
.begin(); i
!= layers
.end(); ++i
)
1193 ancestor_layer
->StackAtTop(*i
);
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
);
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
);
1239 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED
:
1240 if (params
.new_parent
)
1241 params
.new_parent
->NotifyWindowHierarchyChangeUp(params
);
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
));
1274 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED
:
1275 FOR_EACH_OBSERVER(WindowObserver
, observers_
,
1276 OnWindowHierarchyChanged(local_params
));
1284 void Window::NotifyWindowVisibilityChanged(aura::Window
* target
,
1286 if (!NotifyWindowVisibilityChangedDown(target
, visible
)) {
1287 return; // |this| has been deleted.
1289 NotifyWindowVisibilityChangedUp(target
, visible
);
1292 bool Window::NotifyWindowVisibilityChangedAtReceiver(aura::Window
* target
,
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
;
1299 FOR_EACH_OBSERVER(WindowObserver
, observers_
,
1300 OnWindowVisibilityChanged(target
, visible
));
1301 return tracker
.Contains(this);
1304 bool Window::NotifyWindowVisibilityChangedDown(aura::Window
* target
,
1306 if (!NotifyWindowVisibilityChangedAtReceiver(target
, visible
))
1307 return false; // |this| was deleted.
1308 std::set
<const Window
*> child_already_processed
;
1309 bool child_destroyed
= false;
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
)
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;
1323 } while (child_destroyed
);
1327 void Window::NotifyWindowVisibilityChangedUp(aura::Window
* target
,
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
);
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
) {
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();
1361 delegate_
->OnBoundsChanged(old_bounds
, bounds());
1362 FOR_EACH_OBSERVER(WindowObserver
,
1364 OnWindowBoundsChanged(this, old_bounds
, bounds()));
1367 bool Window::CleanupGestureState() {
1368 bool state_modified
= false;
1369 state_modified
|= ui::GestureRecognizer::Get()->CancelActiveTouches(this);
1371 ui::GestureRecognizer::Get()->CleanupStateForConsumer(this);
1372 for (Window::Windows::iterator iter
= children_
.begin();
1373 iter
!= children_
.end();
1375 state_modified
|= (*iter
)->CleanupGestureState();
1377 return state_modified
;
1380 void Window::OnPaintLayer(gfx::Canvas
* canvas
) {
1384 void Window::OnDelegatedFrameDamage(const gfx::Rect
& damage_rect_in_dip
) {
1386 FOR_EACH_OBSERVER(WindowObserver
,
1388 OnDelegatedFrameDamage(this, damage_rect_in_dip
));
1391 base::Closure
Window::PrepareForLayerBoundsChange() {
1392 return base::Bind(&Window::OnWindowBoundsChanged
, base::Unretained(this),
1396 bool Window::CanAcceptEvent(const ui::Event
& event
) {
1397 // The client may forbid certain windows from receiving events at a given
1399 client::EventClient
* client
= client::GetEventClient(GetRootWindow());
1400 if (client
&& !client
->CanProcessEventsWithinSubtree(this))
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())
1412 // The top-most window can always process an event.
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
1420 return event
.IsKeyEvent() || target_handler();
1423 ui::EventTarget
* Window::GetParentTarget() {
1424 if (IsRootWindow()) {
1425 return client::GetEventClient(this) ?
1426 client::GetEventClient(this)->GetToplevelEventTarget() :
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)
1450 std::string
layer_name(name_
);
1451 if (layer_name
.empty())
1452 layer_name
= "Unnamed Window";
1455 layer_name
+= " " + base::IntToString(id_
);
1457 layer()->set_name(layer_name
);
1461 const Window
* Window::GetAncestorWithLayer(gfx::Vector2d
* offset
) const {
1462 for (const aura::Window
* window
= this; window
; window
= window
->parent()) {
1463 if (window
->layer())
1466 *offset
+= window
->bounds().OffsetFromOrigin();
1469 *offset
= gfx::Vector2d();