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"
41 class ScopedCursorHider
{
43 explicit ScopedCursorHider(Window
* window
)
46 if (!window_
->IsRootWindow())
48 const bool cursor_is_in_bounds
= window_
->GetBoundsInScreen().Contains(
49 Env::GetInstance()->last_mouse_location());
50 client::CursorClient
* cursor_client
= client::GetCursorClient(window_
);
51 if (cursor_is_in_bounds
&& cursor_client
&&
52 cursor_client
->IsCursorVisible()) {
53 cursor_client
->HideCursor();
57 ~ScopedCursorHider() {
58 if (!window_
->IsRootWindow())
61 // Update the device scale factor of the cursor client only when the last
62 // mouse location is on this root window.
64 client::CursorClient
* cursor_client
= client::GetCursorClient(window_
);
66 const gfx::Display
& display
=
67 gfx::Screen::GetScreenFor(window_
)->GetDisplayNearestWindow(
69 cursor_client
->SetDisplay(display
);
70 cursor_client
->ShowCursor();
79 DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider
);
82 Window::Window(WindowDelegate
* delegate
)
84 type_(ui::wm::WINDOW_TYPE_UNKNOWN
),
85 owned_by_parent_(true),
92 ignore_events_(false),
93 // Don't notify newly added observers during notification. This causes
94 // problems for code that adds an observer as part of an observer
95 // notification (such as the workspace code).
96 observers_(base::ObserverList
<WindowObserver
>::NOTIFY_EXISTING_ONLY
) {
97 set_target_handler(delegate_
);
101 if (layer()->owner() == this)
102 layer()->CompleteAllAnimations();
103 layer()->SuppressPaint();
105 // Let the delegate know we're in the processing of destroying.
107 delegate_
->OnWindowDestroying(this);
108 FOR_EACH_OBSERVER(WindowObserver
, observers_
, OnWindowDestroying(this));
110 // While we are being destroyed, our target handler may also be in the
111 // process of destruction or already destroyed, so do not forward any
112 // input events at the ui::EP_TARGET phase.
113 set_target_handler(nullptr);
115 // TODO(beng): See comment in window_event_dispatcher.h. This shouldn't be
116 // necessary but unfortunately is right now due to ordering
117 // peculiarities. WED must be notified _after_ other observers
118 // are notified of pending teardown but before the hierarchy
119 // is actually torn down.
120 WindowTreeHost
* host
= GetHost();
122 host
->dispatcher()->OnPostNotifiedWindowDestroying(this);
124 // The window should have already had its state cleaned up in
125 // WindowEventDispatcher::OnWindowHidden(), but there have been some crashes
126 // involving windows being destroyed without being hidden first. See
127 // crbug.com/342040. This should help us debug the issue. TODO(tdresser):
128 // remove this once we determine why we have windows that are destroyed
129 // without being hidden.
130 bool window_incorrectly_cleaned_up
= CleanupGestureState();
131 CHECK(!window_incorrectly_cleaned_up
);
133 // Then destroy the children.
134 RemoveOrDestroyChildren();
136 // The window needs to be removed from the parent before calling the
137 // WindowDestroyed callbacks of delegate and the observers.
139 parent_
->RemoveChild(this);
142 delegate_
->OnWindowDestroyed(this);
143 base::ObserverListBase
<WindowObserver
>::Iterator
iter(&observers_
);
144 for (WindowObserver
* observer
= iter
.GetNext(); observer
;
145 observer
= iter
.GetNext()) {
146 RemoveObserver(observer
);
147 observer
->OnWindowDestroyed(this);
151 for (std::map
<const void*, Value
>::const_iterator iter
= prop_map_
.begin();
152 iter
!= prop_map_
.end();
154 if (iter
->second
.deallocator
)
155 (*iter
->second
.deallocator
)(iter
->second
.value
);
159 // The layer will either be destroyed by |layer_owner_|'s dtor, or by whoever
161 layer()->set_delegate(NULL
);
165 void Window::Init(ui::LayerType layer_type
) {
166 SetLayer(new ui::Layer(layer_type
));
167 layer()->SetVisible(false);
168 layer()->set_delegate(this);
170 layer()->SetFillsBoundsOpaquely(!transparent_
);
171 Env::GetInstance()->NotifyWindowInitialized(this);
174 void Window::SetType(ui::wm::WindowType type
) {
175 // Cannot change type after the window is initialized.
180 void Window::SetName(const std::string
& name
) {
186 void Window::SetTitle(const base::string16
& title
) {
188 FOR_EACH_OBSERVER(WindowObserver
,
190 OnWindowTitleChanged(this));
193 void Window::SetTransparent(bool transparent
) {
194 transparent_
= transparent
;
196 layer()->SetFillsBoundsOpaquely(!transparent_
);
199 void Window::SetFillsBoundsCompletely(bool fills_bounds
) {
200 layer()->SetFillsBoundsCompletely(fills_bounds
);
203 Window
* Window::GetRootWindow() {
204 return const_cast<Window
*>(
205 static_cast<const Window
*>(this)->GetRootWindow());
208 const Window
* Window::GetRootWindow() const {
209 return IsRootWindow() ? this : parent_
? parent_
->GetRootWindow() : NULL
;
212 WindowTreeHost
* Window::GetHost() {
213 return const_cast<WindowTreeHost
*>(const_cast<const Window
*>(this)->
217 const WindowTreeHost
* Window::GetHost() const {
218 const Window
* root_window
= GetRootWindow();
219 return root_window
? root_window
->host_
: NULL
;
222 void Window::Show() {
223 DCHECK_EQ(visible_
, layer()->GetTargetVisibility());
224 // It is not allowed that a window is visible but the layers alpha is fully
225 // transparent since the window would still be considered to be active but
226 // could not be seen.
227 DCHECK_IMPLIES(visible_
, layer()->GetTargetOpacity() > 0.0f
);
231 void Window::Hide() {
232 // RootWindow::OnVisibilityChanged will call ReleaseCapture.
236 bool Window::IsVisible() const {
237 // Layer visibility can be inconsistent with window visibility, for example
238 // when a Window is hidden, we want this function to return false immediately
239 // after, even though the client may decide to animate the hide effect (and
240 // so the layer will be visible for some time after Hide() is called).
241 return visible_
? layer()->IsDrawn() : false;
244 gfx::Rect
Window::GetBoundsInRootWindow() const {
245 // TODO(beng): There may be a better way to handle this, and the existing code
246 // is likely wrong anyway in a multi-display world, but this will
248 if (!GetRootWindow())
250 gfx::Rect
bounds_in_root(bounds().size());
251 ConvertRectToTarget(this, GetRootWindow(), &bounds_in_root
);
252 return bounds_in_root
;
255 gfx::Rect
Window::GetBoundsInScreen() const {
256 gfx::Rect
bounds(GetBoundsInRootWindow());
257 const Window
* root
= GetRootWindow();
259 aura::client::ScreenPositionClient
* screen_position_client
=
260 aura::client::GetScreenPositionClient(root
);
261 if (screen_position_client
) {
262 gfx::Point origin
= bounds
.origin();
263 screen_position_client
->ConvertPointToScreen(root
, &origin
);
264 bounds
.set_origin(origin
);
270 void Window::SetTransform(const gfx::Transform
& transform
) {
271 FOR_EACH_OBSERVER(WindowObserver
, observers_
,
272 OnWindowTransforming(this));
273 layer()->SetTransform(transform
);
274 FOR_EACH_OBSERVER(WindowObserver
, observers_
,
275 OnWindowTransformed(this));
276 NotifyAncestorWindowTransformed(this);
279 void Window::SetLayoutManager(LayoutManager
* layout_manager
) {
280 if (layout_manager
== layout_manager_
)
282 layout_manager_
.reset(layout_manager
);
285 // If we're changing to a new layout manager, ensure it is aware of all the
286 // existing child windows.
287 for (Windows::const_iterator it
= children_
.begin();
288 it
!= children_
.end();
290 layout_manager_
->OnWindowAddedToLayout(*it
);
293 scoped_ptr
<ui::EventTargeter
>
294 Window::SetEventTargeter(scoped_ptr
<ui::EventTargeter
> targeter
) {
295 scoped_ptr
<ui::EventTargeter
> old_targeter
= targeter_
.Pass();
296 targeter_
= targeter
.Pass();
297 return old_targeter
.Pass();
300 void Window::SetBounds(const gfx::Rect
& new_bounds
) {
301 if (parent_
&& parent_
->layout_manager())
302 parent_
->layout_manager()->SetChildBounds(this, new_bounds
);
304 // Ensure we don't go smaller than our minimum bounds.
305 gfx::Rect
final_bounds(new_bounds
);
307 const gfx::Size
& min_size
= delegate_
->GetMinimumSize();
308 final_bounds
.set_width(std::max(min_size
.width(), final_bounds
.width()));
309 final_bounds
.set_height(std::max(min_size
.height(),
310 final_bounds
.height()));
312 SetBoundsInternal(final_bounds
);
316 void Window::SetBoundsInScreen(const gfx::Rect
& new_bounds_in_screen
,
317 const gfx::Display
& dst_display
) {
318 Window
* root
= GetRootWindow();
320 aura::client::ScreenPositionClient
* screen_position_client
=
321 aura::client::GetScreenPositionClient(root
);
322 screen_position_client
->SetBounds(this, new_bounds_in_screen
, dst_display
);
325 SetBounds(new_bounds_in_screen
);
328 gfx::Rect
Window::GetTargetBounds() const {
329 return layer() ? layer()->GetTargetBounds() : bounds();
332 void Window::SchedulePaintInRect(const gfx::Rect
& rect
) {
333 layer()->SchedulePaint(rect
);
336 void Window::StackChildAtTop(Window
* child
) {
337 if (children_
.size() <= 1 || child
== children_
.back())
338 return; // In the front already.
339 StackChildAbove(child
, children_
.back());
342 void Window::StackChildAbove(Window
* child
, Window
* target
) {
343 StackChildRelativeTo(child
, target
, STACK_ABOVE
);
346 void Window::StackChildAtBottom(Window
* child
) {
347 if (children_
.size() <= 1 || child
== children_
.front())
348 return; // At the bottom already.
349 StackChildBelow(child
, children_
.front());
352 void Window::StackChildBelow(Window
* child
, Window
* target
) {
353 StackChildRelativeTo(child
, target
, STACK_BELOW
);
356 void Window::AddChild(Window
* child
) {
357 DCHECK(layer()) << "Parent has not been Init()ed yet.";
358 DCHECK(child
->layer()) << "Child has not been Init()ed yt.";
359 WindowObserver::HierarchyChangeParams params
;
360 params
.target
= child
;
361 params
.new_parent
= this;
362 params
.old_parent
= child
->parent();
363 params
.phase
= WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING
;
364 NotifyWindowHierarchyChange(params
);
366 Window
* old_root
= child
->GetRootWindow();
368 DCHECK(std::find(children_
.begin(), children_
.end(), child
) ==
371 child
->parent()->RemoveChildImpl(child
, this);
373 child
->parent_
= this;
374 layer()->Add(child
->layer());
376 children_
.push_back(child
);
378 layout_manager_
->OnWindowAddedToLayout(child
);
379 FOR_EACH_OBSERVER(WindowObserver
, observers_
, OnWindowAdded(child
));
380 child
->OnParentChanged();
382 Window
* root_window
= GetRootWindow();
383 if (root_window
&& old_root
!= root_window
) {
384 root_window
->GetHost()->dispatcher()->OnWindowAddedToRootWindow(child
);
385 child
->NotifyAddedToRootWindow();
388 params
.phase
= WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED
;
389 NotifyWindowHierarchyChange(params
);
392 void Window::RemoveChild(Window
* child
) {
393 WindowObserver::HierarchyChangeParams params
;
394 params
.target
= child
;
395 params
.new_parent
= NULL
;
396 params
.old_parent
= this;
397 params
.phase
= WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING
;
398 NotifyWindowHierarchyChange(params
);
400 RemoveChildImpl(child
, NULL
);
402 params
.phase
= WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED
;
403 NotifyWindowHierarchyChange(params
);
406 bool Window::Contains(const Window
* other
) const {
407 for (const Window
* parent
= other
; parent
; parent
= parent
->parent_
) {
414 Window
* Window::GetChildById(int id
) {
415 return const_cast<Window
*>(const_cast<const Window
*>(this)->GetChildById(id
));
418 const Window
* Window::GetChildById(int id
) const {
419 Windows::const_iterator i
;
420 for (i
= children_
.begin(); i
!= children_
.end(); ++i
) {
421 if ((*i
)->id() == id
)
423 const Window
* result
= (*i
)->GetChildById(id
);
431 void Window::ConvertPointToTarget(const Window
* source
,
432 const Window
* target
,
436 if (source
->GetRootWindow() != target
->GetRootWindow()) {
437 client::ScreenPositionClient
* source_client
=
438 client::GetScreenPositionClient(source
->GetRootWindow());
439 // |source_client| can be NULL in tests.
441 source_client
->ConvertPointToScreen(source
, point
);
443 client::ScreenPositionClient
* target_client
=
444 client::GetScreenPositionClient(target
->GetRootWindow());
445 // |target_client| can be NULL in tests.
447 target_client
->ConvertPointFromScreen(target
, point
);
449 ui::Layer::ConvertPointToLayer(source
->layer(), target
->layer(), point
);
454 void Window::ConvertRectToTarget(const Window
* source
,
455 const Window
* target
,
458 gfx::Point origin
= rect
->origin();
459 ConvertPointToTarget(source
, target
, &origin
);
460 rect
->set_origin(origin
);
463 void Window::MoveCursorTo(const gfx::Point
& point_in_window
) {
464 Window
* root_window
= GetRootWindow();
466 gfx::Point
point_in_root(point_in_window
);
467 ConvertPointToTarget(this, root_window
, &point_in_root
);
468 root_window
->GetHost()->MoveCursorTo(point_in_root
);
471 gfx::NativeCursor
Window::GetCursor(const gfx::Point
& point
) const {
472 return delegate_
? delegate_
->GetCursor(point
) : gfx::kNullCursor
;
475 void Window::AddObserver(WindowObserver
* observer
) {
476 observer
->OnObservingWindow(this);
477 observers_
.AddObserver(observer
);
480 void Window::RemoveObserver(WindowObserver
* observer
) {
481 observer
->OnUnobservingWindow(this);
482 observers_
.RemoveObserver(observer
);
485 bool Window::HasObserver(const WindowObserver
* observer
) const {
486 return observers_
.HasObserver(observer
);
489 bool Window::ContainsPointInRoot(const gfx::Point
& point_in_root
) const {
490 const Window
* root_window
= GetRootWindow();
493 gfx::Point
local_point(point_in_root
);
494 ConvertPointToTarget(root_window
, this, &local_point
);
495 return gfx::Rect(GetTargetBounds().size()).Contains(local_point
);
498 bool Window::ContainsPoint(const gfx::Point
& local_point
) const {
499 return gfx::Rect(bounds().size()).Contains(local_point
);
502 Window
* Window::GetEventHandlerForPoint(const gfx::Point
& local_point
) {
503 return GetWindowForPoint(local_point
, true, true);
506 Window
* Window::GetTopWindowContainingPoint(const gfx::Point
& local_point
) {
507 return GetWindowForPoint(local_point
, false, false);
510 Window
* Window::GetToplevelWindow() {
511 Window
* topmost_window_with_delegate
= NULL
;
512 for (aura::Window
* window
= this; window
!= NULL
; window
= window
->parent()) {
513 if (window
->delegate())
514 topmost_window_with_delegate
= window
;
516 return topmost_window_with_delegate
;
519 void Window::Focus() {
520 client::FocusClient
* client
= client::GetFocusClient(this);
522 client
->FocusWindow(this);
525 bool Window::HasFocus() const {
526 client::FocusClient
* client
= client::GetFocusClient(this);
527 return client
&& client
->GetFocusedWindow() == this;
530 bool Window::CanFocus() const {
534 // NOTE: as part of focusing the window the ActivationClient may make the
535 // window visible (by way of making a hidden ancestor visible). For this
536 // reason we can't check visibility here and assume the client is doing it.
537 if (!parent_
|| (delegate_
&& !delegate_
->CanFocus()))
540 // The client may forbid certain windows from receiving focus at a given point
542 client::EventClient
* client
= client::GetEventClient(GetRootWindow());
543 if (client
&& !client
->CanProcessEventsWithinSubtree(this))
546 return parent_
->CanFocus();
549 bool Window::CanReceiveEvents() const {
553 // The client may forbid certain windows from receiving events at a given
555 client::EventClient
* client
= client::GetEventClient(GetRootWindow());
556 if (client
&& !client
->CanProcessEventsWithinSubtree(this))
559 return parent_
&& IsVisible() && parent_
->CanReceiveEvents();
562 void Window::SetCapture() {
566 Window
* root_window
= GetRootWindow();
569 client::CaptureClient
* capture_client
= client::GetCaptureClient(root_window
);
572 client::GetCaptureClient(root_window
)->SetCapture(this);
575 void Window::ReleaseCapture() {
576 Window
* root_window
= GetRootWindow();
579 client::CaptureClient
* capture_client
= client::GetCaptureClient(root_window
);
582 client::GetCaptureClient(root_window
)->ReleaseCapture(this);
585 bool Window::HasCapture() {
586 Window
* root_window
= GetRootWindow();
589 client::CaptureClient
* capture_client
= client::GetCaptureClient(root_window
);
590 return capture_client
&& capture_client
->GetCaptureWindow() == this;
593 void Window::SuppressPaint() {
594 layer()->SuppressPaint();
597 // {Set,Get,Clear}Property are implemented in window_property.h.
599 void Window::SetNativeWindowProperty(const char* key
, void* value
) {
601 key
, key
, NULL
, reinterpret_cast<int64
>(value
), 0);
604 void* Window::GetNativeWindowProperty(const char* key
) const {
605 return reinterpret_cast<void*>(GetPropertyInternal(key
, 0));
608 void Window::OnDeviceScaleFactorChanged(float device_scale_factor
) {
609 ScopedCursorHider
hider(this);
611 delegate_
->OnDeviceScaleFactorChanged(device_scale_factor
);
615 std::string
Window::GetDebugInfo() const {
616 return base::StringPrintf(
617 "%s<%d> bounds(%d, %d, %d, %d) %s %s opacity=%.1f",
618 name().empty() ? "Unknown" : name().c_str(), id(),
619 bounds().x(), bounds().y(), bounds().width(), bounds().height(),
620 visible_
? "WindowVisible" : "WindowHidden",
622 (layer()->GetTargetVisibility() ? "LayerVisible" : "LayerHidden") :
624 layer() ? layer()->opacity() : 1.0f
);
627 void Window::PrintWindowHierarchy(int depth
) const {
628 VLOG(0) << base::StringPrintf(
629 "%*s%s", depth
* 2, "", GetDebugInfo().c_str());
630 for (Windows::const_iterator it
= children_
.begin();
631 it
!= children_
.end(); ++it
) {
633 child
->PrintWindowHierarchy(depth
+ 1);
638 void Window::RemoveOrDestroyChildren() {
639 while (!children_
.empty()) {
640 Window
* child
= children_
[0];
641 if (child
->owned_by_parent_
) {
643 // Deleting the child so remove it from out children_ list.
644 DCHECK(std::find(children_
.begin(), children_
.end(), child
) ==
647 // Even if we can't delete the child, we still need to remove it from the
648 // parent so that relevant bookkeeping (parent_ back-pointers etc) are
655 ///////////////////////////////////////////////////////////////////////////////
658 int64
Window::SetPropertyInternal(const void* key
,
660 PropertyDeallocator deallocator
,
662 int64 default_value
) {
663 int64 old
= GetPropertyInternal(key
, default_value
);
664 if (value
== default_value
) {
665 prop_map_
.erase(key
);
668 prop_value
.name
= name
;
669 prop_value
.value
= value
;
670 prop_value
.deallocator
= deallocator
;
671 prop_map_
[key
] = prop_value
;
673 FOR_EACH_OBSERVER(WindowObserver
, observers_
,
674 OnWindowPropertyChanged(this, key
, old
));
678 int64
Window::GetPropertyInternal(const void* key
,
679 int64 default_value
) const {
680 std::map
<const void*, Value
>::const_iterator iter
= prop_map_
.find(key
);
681 if (iter
== prop_map_
.end())
682 return default_value
;
683 return iter
->second
.value
;
686 bool Window::HitTest(const gfx::Point
& local_point
) {
687 gfx::Rect
local_bounds(bounds().size());
688 if (!delegate_
|| !delegate_
->HasHitTestMask())
689 return local_bounds
.Contains(local_point
);
692 delegate_
->GetHitTestMask(&mask
);
694 SkRegion clip_region
;
695 clip_region
.setRect(local_bounds
.x(), local_bounds
.y(),
696 local_bounds
.width(), local_bounds
.height());
697 SkRegion mask_region
;
698 return mask_region
.setPath(mask
, clip_region
) &&
699 mask_region
.contains(local_point
.x(), local_point
.y());
702 void Window::SetBoundsInternal(const gfx::Rect
& new_bounds
) {
703 gfx::Rect old_bounds
= GetTargetBounds();
705 // Always need to set the layer's bounds -- even if it is to the same thing.
706 // This may cause important side effects such as stopping animation.
707 layer()->SetBounds(new_bounds
);
709 // If we are currently not the layer's delegate, we will not get bounds
710 // changed notification from the layer (this typically happens after animating
711 // hidden). We must notify ourselves.
712 if (layer()->delegate() != this)
713 OnWindowBoundsChanged(old_bounds
);
716 void Window::SetVisible(bool visible
) {
717 // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed.
718 tracked_objects::ScopedTracker
tracking_profile(
719 FROM_HERE_WITH_EXPLICIT_FUNCTION("440919 Window::SetVisible"));
721 if (visible
== layer()->GetTargetVisibility())
722 return; // No change.
724 FOR_EACH_OBSERVER(WindowObserver
, observers_
,
725 OnWindowVisibilityChanging(this, visible
));
727 client::VisibilityClient
* visibility_client
=
728 client::GetVisibilityClient(this);
729 if (visibility_client
)
730 visibility_client
->UpdateLayerVisibility(this, visible
);
732 layer()->SetVisible(visible
);
735 if (parent_
&& parent_
->layout_manager_
)
736 parent_
->layout_manager_
->OnChildWindowVisibilityChanged(this, visible
);
739 delegate_
->OnWindowTargetVisibilityChanged(visible
);
741 NotifyWindowVisibilityChanged(this, visible
);
744 void Window::SchedulePaint() {
745 SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height()));
748 void Window::Paint(const ui::PaintContext
& context
) {
750 delegate_
->OnPaint(context
);
753 Window
* Window::GetWindowForPoint(const gfx::Point
& local_point
,
754 bool return_tightest
,
755 bool for_event_handling
) {
759 if ((for_event_handling
&& !HitTest(local_point
)) ||
760 (!for_event_handling
&& !ContainsPoint(local_point
)))
763 // Check if I should claim this event and not pass it to my children because
764 // the location is inside my hit test override area. For details, see
765 // set_hit_test_bounds_override_inner().
766 if (for_event_handling
&& !hit_test_bounds_override_inner_
.empty()) {
767 gfx::Rect
inset_local_bounds(gfx::Point(), bounds().size());
768 inset_local_bounds
.Inset(hit_test_bounds_override_inner_
);
769 // We know we're inside the normal local bounds, so if we're outside the
770 // inset bounds we must be in the special hit test override area.
771 DCHECK(HitTest(local_point
));
772 if (!inset_local_bounds
.Contains(local_point
))
773 return delegate_
? this : NULL
;
776 if (!return_tightest
&& delegate_
)
779 for (Windows::const_reverse_iterator it
= children_
.rbegin(),
780 rend
= children_
.rend();
784 if (for_event_handling
) {
785 if (child
->ignore_events_
)
787 // The client may not allow events to be processed by certain subtrees.
788 client::EventClient
* client
= client::GetEventClient(GetRootWindow());
789 if (client
&& !client
->CanProcessEventsWithinSubtree(child
))
791 if (delegate_
&& !delegate_
->ShouldDescendIntoChildForEventHandling(
796 gfx::Point
point_in_child_coords(local_point
);
797 ConvertPointToTarget(this, child
, &point_in_child_coords
);
798 Window
* match
= child
->GetWindowForPoint(point_in_child_coords
,
805 return delegate_
? this : NULL
;
808 void Window::RemoveChildImpl(Window
* child
, Window
* new_parent
) {
810 layout_manager_
->OnWillRemoveWindowFromLayout(child
);
811 FOR_EACH_OBSERVER(WindowObserver
, observers_
, OnWillRemoveWindow(child
));
812 Window
* root_window
= child
->GetRootWindow();
813 Window
* new_root_window
= new_parent
? new_parent
->GetRootWindow() : NULL
;
814 if (root_window
&& root_window
!= new_root_window
)
815 child
->NotifyRemovingFromRootWindow(new_root_window
);
817 if (child
->OwnsLayer())
818 layer()->Remove(child
->layer());
819 child
->parent_
= NULL
;
820 Windows::iterator i
= std::find(children_
.begin(), children_
.end(), child
);
821 DCHECK(i
!= children_
.end());
823 child
->OnParentChanged();
825 layout_manager_
->OnWindowRemovedFromLayout(child
);
828 void Window::OnParentChanged() {
830 WindowObserver
, observers_
, OnWindowParentChanged(this, parent_
));
833 void Window::StackChildRelativeTo(Window
* child
,
835 StackDirection direction
) {
836 DCHECK_NE(child
, target
);
839 DCHECK_EQ(this, child
->parent());
840 DCHECK_EQ(this, target
->parent());
842 client::WindowStackingClient
* stacking_client
=
843 client::GetWindowStackingClient();
844 if (stacking_client
&&
845 !stacking_client
->AdjustStacking(&child
, &target
, &direction
))
848 const size_t child_i
=
849 std::find(children_
.begin(), children_
.end(), child
) - children_
.begin();
850 const size_t target_i
=
851 std::find(children_
.begin(), children_
.end(), target
) - children_
.begin();
853 // Don't move the child if it is already in the right place.
854 if ((direction
== STACK_ABOVE
&& child_i
== target_i
+ 1) ||
855 (direction
== STACK_BELOW
&& child_i
+ 1 == target_i
))
858 const size_t dest_i
=
859 direction
== STACK_ABOVE
?
860 (child_i
< target_i
? target_i
: target_i
+ 1) :
861 (child_i
< target_i
? target_i
- 1 : target_i
);
862 children_
.erase(children_
.begin() + child_i
);
863 children_
.insert(children_
.begin() + dest_i
, child
);
865 StackChildLayerRelativeTo(child
, target
, direction
);
867 child
->OnStackingChanged();
870 void Window::StackChildLayerRelativeTo(Window
* child
,
872 StackDirection direction
) {
873 DCHECK(layer() && child
->layer() && target
->layer());
874 if (direction
== STACK_ABOVE
)
875 layer()->StackAbove(child
->layer(), target
->layer());
877 layer()->StackBelow(child
->layer(), target
->layer());
880 void Window::OnStackingChanged() {
881 FOR_EACH_OBSERVER(WindowObserver
, observers_
, OnWindowStackingChanged(this));
884 void Window::NotifyRemovingFromRootWindow(Window
* new_root
) {
885 FOR_EACH_OBSERVER(WindowObserver
, observers_
,
886 OnWindowRemovingFromRootWindow(this, new_root
));
887 for (Window::Windows::const_iterator it
= children_
.begin();
888 it
!= children_
.end(); ++it
) {
889 (*it
)->NotifyRemovingFromRootWindow(new_root
);
893 void Window::NotifyAddedToRootWindow() {
894 FOR_EACH_OBSERVER(WindowObserver
, observers_
,
895 OnWindowAddedToRootWindow(this));
896 for (Window::Windows::const_iterator it
= children_
.begin();
897 it
!= children_
.end(); ++it
) {
898 (*it
)->NotifyAddedToRootWindow();
902 void Window::NotifyWindowHierarchyChange(
903 const WindowObserver::HierarchyChangeParams
& params
) {
904 params
.target
->NotifyWindowHierarchyChangeDown(params
);
905 switch (params
.phase
) {
906 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING
:
907 if (params
.old_parent
)
908 params
.old_parent
->NotifyWindowHierarchyChangeUp(params
);
910 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED
:
911 if (params
.new_parent
)
912 params
.new_parent
->NotifyWindowHierarchyChangeUp(params
);
920 void Window::NotifyWindowHierarchyChangeDown(
921 const WindowObserver::HierarchyChangeParams
& params
) {
922 NotifyWindowHierarchyChangeAtReceiver(params
);
923 for (Window::Windows::const_iterator it
= children_
.begin();
924 it
!= children_
.end(); ++it
) {
925 (*it
)->NotifyWindowHierarchyChangeDown(params
);
929 void Window::NotifyWindowHierarchyChangeUp(
930 const WindowObserver::HierarchyChangeParams
& params
) {
931 for (Window
* window
= this; window
; window
= window
->parent())
932 window
->NotifyWindowHierarchyChangeAtReceiver(params
);
935 void Window::NotifyWindowHierarchyChangeAtReceiver(
936 const WindowObserver::HierarchyChangeParams
& params
) {
937 WindowObserver::HierarchyChangeParams local_params
= params
;
938 local_params
.receiver
= this;
940 switch (params
.phase
) {
941 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING
:
942 FOR_EACH_OBSERVER(WindowObserver
, observers_
,
943 OnWindowHierarchyChanging(local_params
));
945 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED
:
946 FOR_EACH_OBSERVER(WindowObserver
, observers_
,
947 OnWindowHierarchyChanged(local_params
));
955 void Window::NotifyWindowVisibilityChanged(aura::Window
* target
,
957 if (!NotifyWindowVisibilityChangedDown(target
, visible
)) {
958 return; // |this| has been deleted.
960 NotifyWindowVisibilityChangedUp(target
, visible
);
963 bool Window::NotifyWindowVisibilityChangedAtReceiver(aura::Window
* target
,
965 // |this| may be deleted during a call to OnWindowVisibilityChanged() on one
966 // of the observers. We create an local observer for that. In that case we
967 // exit without further access to any members.
968 WindowTracker tracker
;
970 FOR_EACH_OBSERVER(WindowObserver
, observers_
,
971 OnWindowVisibilityChanged(target
, visible
));
972 return tracker
.Contains(this);
975 bool Window::NotifyWindowVisibilityChangedDown(aura::Window
* target
,
977 if (!NotifyWindowVisibilityChangedAtReceiver(target
, visible
))
978 return false; // |this| was deleted.
979 std::set
<const Window
*> child_already_processed
;
980 bool child_destroyed
= false;
982 child_destroyed
= false;
983 for (Window::Windows::const_iterator it
= children_
.begin();
984 it
!= children_
.end(); ++it
) {
985 if (!child_already_processed
.insert(*it
).second
)
987 if (!(*it
)->NotifyWindowVisibilityChangedDown(target
, visible
)) {
988 // |*it| was deleted, |it| is invalid and |children_| has changed.
989 // We exit the current for-loop and enter a new one.
990 child_destroyed
= true;
994 } while (child_destroyed
);
998 void Window::NotifyWindowVisibilityChangedUp(aura::Window
* target
,
1000 // Start with the parent as we already notified |this|
1001 // in NotifyWindowVisibilityChangedDown.
1002 for (Window
* window
= parent(); window
; window
= window
->parent()) {
1003 bool ret
= window
->NotifyWindowVisibilityChangedAtReceiver(target
, visible
);
1008 void Window::NotifyAncestorWindowTransformed(Window
* source
) {
1009 FOR_EACH_OBSERVER(WindowObserver
, observers_
,
1010 OnAncestorWindowTransformed(source
, this));
1011 for (Window::Windows::const_iterator it
= children_
.begin();
1012 it
!= children_
.end(); ++it
) {
1013 (*it
)->NotifyAncestorWindowTransformed(source
);
1017 void Window::OnWindowBoundsChanged(const gfx::Rect
& old_bounds
) {
1018 bounds_
= layer()->bounds();
1019 if (layout_manager_
)
1020 layout_manager_
->OnWindowResized();
1022 delegate_
->OnBoundsChanged(old_bounds
, bounds());
1023 FOR_EACH_OBSERVER(WindowObserver
,
1025 OnWindowBoundsChanged(this, old_bounds
, bounds()));
1028 bool Window::CleanupGestureState() {
1029 bool state_modified
= false;
1030 state_modified
|= ui::GestureRecognizer::Get()->CancelActiveTouches(this);
1032 ui::GestureRecognizer::Get()->CleanupStateForConsumer(this);
1033 for (Window::Windows::iterator iter
= children_
.begin();
1034 iter
!= children_
.end();
1036 state_modified
|= (*iter
)->CleanupGestureState();
1038 return state_modified
;
1041 void Window::OnPaintLayer(const ui::PaintContext
& context
) {
1045 void Window::OnDelegatedFrameDamage(const gfx::Rect
& damage_rect_in_dip
) {
1047 FOR_EACH_OBSERVER(WindowObserver
,
1049 OnDelegatedFrameDamage(this, damage_rect_in_dip
));
1052 base::Closure
Window::PrepareForLayerBoundsChange() {
1053 return base::Bind(&Window::OnWindowBoundsChanged
, base::Unretained(this),
1057 bool Window::CanAcceptEvent(const ui::Event
& event
) {
1058 // The client may forbid certain windows from receiving events at a given
1060 client::EventClient
* client
= client::GetEventClient(GetRootWindow());
1061 if (client
&& !client
->CanProcessEventsWithinSubtree(this))
1064 // We need to make sure that a touch cancel event and any gesture events it
1065 // creates can always reach the window. This ensures that we receive a valid
1066 // touch / gesture stream.
1067 if (event
.IsEndingEvent())
1073 // The top-most window can always process an event.
1077 // For located events (i.e. mouse, touch etc.), an assumption is made that
1078 // windows that don't have a default event-handler cannot process the event
1079 // (see more in GetWindowForPoint()). This assumption is not made for key
1081 return event
.IsKeyEvent() || target_handler();
1084 ui::EventTarget
* Window::GetParentTarget() {
1085 if (IsRootWindow()) {
1086 return client::GetEventClient(this) ?
1087 client::GetEventClient(this)->GetToplevelEventTarget() :
1093 scoped_ptr
<ui::EventTargetIterator
> Window::GetChildIterator() const {
1094 return make_scoped_ptr(new ui::EventTargetIteratorImpl
<Window
>(children()));
1097 ui::EventTargeter
* Window::GetEventTargeter() {
1098 return targeter_
.get();
1101 void Window::ConvertEventToTarget(ui::EventTarget
* target
,
1102 ui::LocatedEvent
* event
) {
1103 event
->ConvertLocationToTarget(this,
1104 static_cast<Window
*>(target
));
1107 void Window::UpdateLayerName() {
1108 #if !defined(NDEBUG)
1111 std::string
layer_name(name_
);
1112 if (layer_name
.empty())
1113 layer_name
= "Unnamed Window";
1116 layer_name
+= " " + base::IntToString(id_
);
1118 layer()->set_name(layer_name
);