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.
4
5 #include "ui/aura/window.h"
6
7 #include <algorithm>
8
9 #include "base/bind.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/window_delegate.h"
26 #include "ui/aura/window_event_dispatcher.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/canvas.h"
34 #include "ui/gfx/path.h"
35 #include "ui/gfx/scoped_canvas.h"
36 #include "ui/gfx/screen.h"
37
38 namespace aura {
39
40 namespace {
41
WindowLayerTypeToUILayerType(WindowLayerType window_layer_type)42 ui::LayerType WindowLayerTypeToUILayerType(WindowLayerType window_layer_type) {
43 switch (window_layer_type) {
44 case WINDOW_LAYER_NONE:
45 break;
46 case WINDOW_LAYER_NOT_DRAWN:
47 return ui::LAYER_NOT_DRAWN;
48 case WINDOW_LAYER_TEXTURED:
49 return ui::LAYER_TEXTURED;
50 case WINDOW_LAYER_SOLID_COLOR:
51 return ui::LAYER_SOLID_COLOR;
52 }
53 NOTREACHED();
54 return ui::LAYER_NOT_DRAWN;
55 }
56
57 // Used when searching for a Window to stack relative to.
58 template <class T>
59 T IteratorForDirectionBegin(aura::Window* window);
60
61 template <>
IteratorForDirectionBegin(aura::Window * window)62 Window::Windows::const_iterator IteratorForDirectionBegin(
63 aura::Window* window) {
64 return window->children().begin();
65 }
66
67 template <>
IteratorForDirectionBegin(aura::Window * window)68 Window::Windows::const_reverse_iterator IteratorForDirectionBegin(
69 aura::Window* window) {
70 return window->children().rbegin();
71 }
72
73 template <class T>
74 T IteratorForDirectionEnd(aura::Window* window);
75
76 template <>
IteratorForDirectionEnd(aura::Window * window)77 Window::Windows::const_iterator IteratorForDirectionEnd(aura::Window* window) {
78 return window->children().end();
79 }
80
81 template <>
IteratorForDirectionEnd(aura::Window * window)82 Window::Windows::const_reverse_iterator IteratorForDirectionEnd(
83 aura::Window* window) {
84 return window->children().rend();
85 }
86
87 // Depth first search for the first Window with a layer to stack relative
88 // to. Starts at target. Does not descend into |ignore|.
89 template <class T>
FindStackingTargetLayerDown(aura::Window * target,aura::Window * ignore)90 ui::Layer* FindStackingTargetLayerDown(aura::Window* target,
91 aura::Window* ignore) {
92 if (target == ignore)
93 return NULL;
94
95 if (target->layer())
96 return target->layer();
97
98 for (T i = IteratorForDirectionBegin<T>(target);
99 i != IteratorForDirectionEnd<T>(target); ++i) {
100 ui::Layer* layer = FindStackingTargetLayerDown<T>(*i, ignore);
101 if (layer)
102 return layer;
103 }
104 return NULL;
105 }
106
107 // Depth first search through the siblings of |target||. This does not search
108 // all the siblings, only those before/after |target| (depening upon the
109 // template type) and ignoring |ignore|. Returns the Layer of the first Window
110 // encountered with a Layer.
111 template <class T>
FindStackingLayerInSiblings(aura::Window * target,aura::Window * ignore)112 ui::Layer* FindStackingLayerInSiblings(aura::Window* target,
113 aura::Window* ignore) {
114 aura::Window* parent = target->parent();
115 for (T i = std::find(IteratorForDirectionBegin<T>(parent),
116 IteratorForDirectionEnd<T>(parent), target);
117 i != IteratorForDirectionEnd<T>(parent); ++i) {
118 ui::Layer* layer = FindStackingTargetLayerDown<T>(*i, ignore);
119 if (layer)
120 return layer;
121 }
122 return NULL;
123 }
124
125 // Returns the first Window that has a Layer. This does a depth first search
126 // through the descendants of |target| first, then ascends up doing a depth
127 // first search through siblings of all ancestors until a Layer is found or an
128 // ancestor with a layer is found. This is intended to locate a layer to stack
129 // other layers relative to.
130 template <class T>
FindStackingTargetLayer(aura::Window * target,aura::Window * ignore)131 ui::Layer* FindStackingTargetLayer(aura::Window* target, aura::Window* ignore) {
132 ui::Layer* result = FindStackingTargetLayerDown<T>(target, ignore);
133 if (result)
134 return result;
135 while (target->parent()) {
136 ui::Layer* result = FindStackingLayerInSiblings<T>(target, ignore);
137 if (result)
138 return result;
139 target = target->parent();
140 if (target->layer())
141 return NULL;
142 }
143 return NULL;
144 }
145
146 // Does a depth first search for all descendants of |child| that have layers.
147 // This stops at any descendants that have layers (and adds them to |layers|).
GetLayersToStack(aura::Window * child,std::vector<ui::Layer * > * layers)148 void GetLayersToStack(aura::Window* child, std::vector<ui::Layer*>* layers) {
149 if (child->layer()) {
150 layers->push_back(child->layer());
151 return;
152 }
153 for (size_t i = 0; i < child->children().size(); ++i)
154 GetLayersToStack(child->children()[i], layers);
155 }
156
157 } // namespace
158
159 class ScopedCursorHider {
160 public:
ScopedCursorHider(Window * window)161 explicit ScopedCursorHider(Window* window)
162 : window_(window),
163 hid_cursor_(false) {
164 if (!window_->IsRootWindow())
165 return;
166 const bool cursor_is_in_bounds = window_->GetBoundsInScreen().Contains(
167 Env::GetInstance()->last_mouse_location());
168 client::CursorClient* cursor_client = client::GetCursorClient(window_);
169 if (cursor_is_in_bounds && cursor_client &&
170 cursor_client->IsCursorVisible()) {
171 cursor_client->HideCursor();
172 hid_cursor_ = true;
173 }
174 }
~ScopedCursorHider()175 ~ScopedCursorHider() {
176 if (!window_->IsRootWindow())
177 return;
178
179 // Update the device scale factor of the cursor client only when the last
180 // mouse location is on this root window.
181 if (hid_cursor_) {
182 client::CursorClient* cursor_client = client::GetCursorClient(window_);
183 if (cursor_client) {
184 const gfx::Display& display =
185 gfx::Screen::GetScreenFor(window_)->GetDisplayNearestWindow(
186 window_);
187 cursor_client->SetDisplay(display);
188 cursor_client->ShowCursor();
189 }
190 }
191 }
192
193 private:
194 Window* window_;
195 bool hid_cursor_;
196
197 DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider);
198 };
199
Window(WindowDelegate * delegate)200 Window::Window(WindowDelegate* delegate)
201 : host_(NULL),
202 type_(ui::wm::WINDOW_TYPE_UNKNOWN),
203 owned_by_parent_(true),
204 delegate_(delegate),
205 parent_(NULL),
206 visible_(false),
207 id_(-1),
208 transparent_(false),
209 user_data_(NULL),
210 ignore_events_(false),
211 // Don't notify newly added observers during notification. This causes
212 // problems for code that adds an observer as part of an observer
213 // notification (such as the workspace code).
214 observers_(ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY) {
215 set_target_handler(delegate_);
216 }
217
~Window()218 Window::~Window() {
219 // |layer()| can be NULL during tests, or if this Window is layerless.
220 if (layer()) {
221 if (layer()->owner() == this)
222 layer()->CompleteAllAnimations();
223 layer()->SuppressPaint();
224 }
225
226 // Let the delegate know we're in the processing of destroying.
227 if (delegate_)
228 delegate_->OnWindowDestroying(this);
229 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this));
230
231 // TODO(beng): See comment in window_event_dispatcher.h. This shouldn't be
232 // necessary but unfortunately is right now due to ordering
233 // peculiarities. WED must be notified _after_ other observers
234 // are notified of pending teardown but before the hierarchy
235 // is actually torn down.
236 WindowTreeHost* host = GetHost();
237 if (host)
238 host->dispatcher()->OnPostNotifiedWindowDestroying(this);
239
240 // The window should have already had its state cleaned up in
241 // WindowEventDispatcher::OnWindowHidden(), but there have been some crashes
242 // involving windows being destroyed without being hidden first. See
243 // crbug.com/342040. This should help us debug the issue. TODO(tdresser):
244 // remove this once we determine why we have windows that are destroyed
245 // without being hidden.
246 bool window_incorrectly_cleaned_up = CleanupGestureState();
247 CHECK(!window_incorrectly_cleaned_up);
248
249 // Then destroy the children.
250 RemoveOrDestroyChildren();
251
252 // The window needs to be removed from the parent before calling the
253 // WindowDestroyed callbacks of delegate and the observers.
254 if (parent_)
255 parent_->RemoveChild(this);
256
257 if (delegate_)
258 delegate_->OnWindowDestroyed(this);
259 ObserverListBase<WindowObserver>::Iterator iter(observers_);
260 WindowObserver* observer;
261 while ((observer = iter.GetNext())) {
262 RemoveObserver(observer);
263 observer->OnWindowDestroyed(this);
264 }
265
266 // Clear properties.
267 for (std::map<const void*, Value>::const_iterator iter = prop_map_.begin();
268 iter != prop_map_.end();
269 ++iter) {
270 if (iter->second.deallocator)
271 (*iter->second.deallocator)(iter->second.value);
272 }
273 prop_map_.clear();
274
275 // If we have layer it will either be destroyed by |layer_owner_|'s dtor, or
276 // by whoever acquired it. We don't have a layer if Init() wasn't invoked or
277 // we are layerless.
278 if (layer())
279 layer()->set_delegate(NULL);
280 DestroyLayer();
281 }
282
Init(WindowLayerType window_layer_type)283 void Window::Init(WindowLayerType window_layer_type) {
284 if (window_layer_type != WINDOW_LAYER_NONE) {
285 SetLayer(new ui::Layer(WindowLayerTypeToUILayerType(window_layer_type)));
286 layer()->SetVisible(false);
287 layer()->set_delegate(this);
288 UpdateLayerName();
289 layer()->SetFillsBoundsOpaquely(!transparent_);
290 }
291
292 Env::GetInstance()->NotifyWindowInitialized(this);
293 }
294
SetType(ui::wm::WindowType type)295 void Window::SetType(ui::wm::WindowType type) {
296 // Cannot change type after the window is initialized.
297 DCHECK(!layer());
298 type_ = type;
299 }
300
SetName(const std::string & name)301 void Window::SetName(const std::string& name) {
302 name_ = name;
303
304 if (layer())
305 UpdateLayerName();
306 }
307
SetTransparent(bool transparent)308 void Window::SetTransparent(bool transparent) {
309 transparent_ = transparent;
310 if (layer())
311 layer()->SetFillsBoundsOpaquely(!transparent_);
312 }
313
SetFillsBoundsCompletely(bool fills_bounds)314 void Window::SetFillsBoundsCompletely(bool fills_bounds) {
315 if (layer())
316 layer()->SetFillsBoundsCompletely(fills_bounds);
317 }
318
GetRootWindow()319 Window* Window::GetRootWindow() {
320 return const_cast<Window*>(
321 static_cast<const Window*>(this)->GetRootWindow());
322 }
323
GetRootWindow() const324 const Window* Window::GetRootWindow() const {
325 return IsRootWindow() ? this : parent_ ? parent_->GetRootWindow() : NULL;
326 }
327
GetHost()328 WindowTreeHost* Window::GetHost() {
329 return const_cast<WindowTreeHost*>(const_cast<const Window*>(this)->
330 GetHost());
331 }
332
GetHost() const333 const WindowTreeHost* Window::GetHost() const {
334 const Window* root_window = GetRootWindow();
335 return root_window ? root_window->host_ : NULL;
336 }
337
Show()338 void Window::Show() {
339 if (layer()) {
340 DCHECK_EQ(visible_, layer()->GetTargetVisibility());
341 // It is not allowed that a window is visible but the layers alpha is fully
342 // transparent since the window would still be considered to be active but
343 // could not be seen.
344 DCHECK(!(visible_ && layer()->GetTargetOpacity() == 0.0f));
345 }
346 SetVisible(true);
347 }
348
Hide()349 void Window::Hide() {
350 // RootWindow::OnVisibilityChanged will call ReleaseCapture.
351 SetVisible(false);
352 }
353
IsVisible() const354 bool Window::IsVisible() const {
355 // Layer visibility can be inconsistent with window visibility, for example
356 // when a Window is hidden, we want this function to return false immediately
357 // after, even though the client may decide to animate the hide effect (and
358 // so the layer will be visible for some time after Hide() is called).
359 for (const Window* window = this; window; window = window->parent()) {
360 if (!window->visible_)
361 return false;
362 if (window->layer())
363 return window->layer()->IsDrawn();
364 }
365 return false;
366 }
367
GetBoundsInRootWindow() const368 gfx::Rect Window::GetBoundsInRootWindow() const {
369 // TODO(beng): There may be a better way to handle this, and the existing code
370 // is likely wrong anyway in a multi-display world, but this will
371 // do for now.
372 if (!GetRootWindow())
373 return bounds();
374 gfx::Point origin = bounds().origin();
375 ConvertPointToTarget(parent_, GetRootWindow(), &origin);
376 return gfx::Rect(origin, bounds().size());
377 }
378
GetBoundsInScreen() const379 gfx::Rect Window::GetBoundsInScreen() const {
380 gfx::Rect bounds(GetBoundsInRootWindow());
381 const Window* root = GetRootWindow();
382 if (root) {
383 aura::client::ScreenPositionClient* screen_position_client =
384 aura::client::GetScreenPositionClient(root);
385 if (screen_position_client) {
386 gfx::Point origin = bounds.origin();
387 screen_position_client->ConvertPointToScreen(root, &origin);
388 bounds.set_origin(origin);
389 }
390 }
391 return bounds;
392 }
393
SetTransform(const gfx::Transform & transform)394 void Window::SetTransform(const gfx::Transform& transform) {
395 if (!layer()) {
396 // Transforms aren't supported on layerless windows.
397 NOTREACHED();
398 return;
399 }
400 FOR_EACH_OBSERVER(WindowObserver, observers_,
401 OnWindowTransforming(this));
402 layer()->SetTransform(transform);
403 FOR_EACH_OBSERVER(WindowObserver, observers_,
404 OnWindowTransformed(this));
405 }
406
SetLayoutManager(LayoutManager * layout_manager)407 void Window::SetLayoutManager(LayoutManager* layout_manager) {
408 if (layout_manager == layout_manager_)
409 return;
410 layout_manager_.reset(layout_manager);
411 if (!layout_manager)
412 return;
413 // If we're changing to a new layout manager, ensure it is aware of all the
414 // existing child windows.
415 for (Windows::const_iterator it = children_.begin();
416 it != children_.end();
417 ++it)
418 layout_manager_->OnWindowAddedToLayout(*it);
419 }
420
421 scoped_ptr<ui::EventTargeter>
SetEventTargeter(scoped_ptr<ui::EventTargeter> targeter)422 Window::SetEventTargeter(scoped_ptr<ui::EventTargeter> targeter) {
423 scoped_ptr<ui::EventTargeter> old_targeter = targeter_.Pass();
424 targeter_ = targeter.Pass();
425 return old_targeter.Pass();
426 }
427
SetBounds(const gfx::Rect & new_bounds)428 void Window::SetBounds(const gfx::Rect& new_bounds) {
429 if (parent_ && parent_->layout_manager())
430 parent_->layout_manager()->SetChildBounds(this, new_bounds);
431 else {
432 // Ensure we don't go smaller than our minimum bounds.
433 gfx::Rect final_bounds(new_bounds);
434 if (delegate_) {
435 const gfx::Size& min_size = delegate_->GetMinimumSize();
436 final_bounds.set_width(std::max(min_size.width(), final_bounds.width()));
437 final_bounds.set_height(std::max(min_size.height(),
438 final_bounds.height()));
439 }
440 SetBoundsInternal(final_bounds);
441 }
442 }
443
SetBoundsInScreen(const gfx::Rect & new_bounds_in_screen,const gfx::Display & dst_display)444 void Window::SetBoundsInScreen(const gfx::Rect& new_bounds_in_screen,
445 const gfx::Display& dst_display) {
446 Window* root = GetRootWindow();
447 if (root) {
448 gfx::Point origin = new_bounds_in_screen.origin();
449 aura::client::ScreenPositionClient* screen_position_client =
450 aura::client::GetScreenPositionClient(root);
451 screen_position_client->SetBounds(this, new_bounds_in_screen, dst_display);
452 return;
453 }
454 SetBounds(new_bounds_in_screen);
455 }
456
GetTargetBounds() const457 gfx::Rect Window::GetTargetBounds() const {
458 if (!layer())
459 return bounds();
460
461 if (!parent_ || parent_->layer())
462 return layer()->GetTargetBounds();
463
464 // We have a layer but our parent (who is valid) doesn't. This means the
465 // coordinates of the layer are relative to the first ancestor with a layer;
466 // convert to be relative to parent.
467 gfx::Vector2d offset;
468 const aura::Window* ancestor_with_layer =
469 parent_->GetAncestorWithLayer(&offset);
470 if (!ancestor_with_layer)
471 return layer()->GetTargetBounds();
472
473 gfx::Rect layer_target_bounds = layer()->GetTargetBounds();
474 layer_target_bounds -= offset;
475 return layer_target_bounds;
476 }
477
SchedulePaintInRect(const gfx::Rect & rect)478 void Window::SchedulePaintInRect(const gfx::Rect& rect) {
479 if (!layer() && parent_) {
480 // Notification of paint scheduled happens for the window with a layer.
481 gfx::Rect parent_rect(bounds().size());
482 parent_rect.Intersect(rect);
483 if (!parent_rect.IsEmpty()) {
484 parent_rect.Offset(bounds().origin().OffsetFromOrigin());
485 parent_->SchedulePaintInRect(parent_rect);
486 }
487 } else if (layer() && layer()->SchedulePaint(rect)) {
488 FOR_EACH_OBSERVER(
489 WindowObserver, observers_, OnWindowPaintScheduled(this, rect));
490 }
491 }
492
StackChildAtTop(Window * child)493 void Window::StackChildAtTop(Window* child) {
494 if (children_.size() <= 1 || child == children_.back())
495 return; // In the front already.
496 StackChildAbove(child, children_.back());
497 }
498
StackChildAbove(Window * child,Window * target)499 void Window::StackChildAbove(Window* child, Window* target) {
500 StackChildRelativeTo(child, target, STACK_ABOVE);
501 }
502
StackChildAtBottom(Window * child)503 void Window::StackChildAtBottom(Window* child) {
504 if (children_.size() <= 1 || child == children_.front())
505 return; // At the bottom already.
506 StackChildBelow(child, children_.front());
507 }
508
StackChildBelow(Window * child,Window * target)509 void Window::StackChildBelow(Window* child, Window* target) {
510 StackChildRelativeTo(child, target, STACK_BELOW);
511 }
512
AddChild(Window * child)513 void Window::AddChild(Window* child) {
514 WindowObserver::HierarchyChangeParams params;
515 params.target = child;
516 params.new_parent = this;
517 params.old_parent = child->parent();
518 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
519 NotifyWindowHierarchyChange(params);
520
521 Window* old_root = child->GetRootWindow();
522
523 DCHECK(std::find(children_.begin(), children_.end(), child) ==
524 children_.end());
525 if (child->parent())
526 child->parent()->RemoveChildImpl(child, this);
527
528 gfx::Vector2d offset;
529 aura::Window* ancestor_with_layer = GetAncestorWithLayer(&offset);
530
531 child->parent_ = this;
532
533 if (ancestor_with_layer) {
534 offset += child->bounds().OffsetFromOrigin();
535 child->ReparentLayers(ancestor_with_layer->layer(), offset);
536 }
537
538 children_.push_back(child);
539 if (layout_manager_)
540 layout_manager_->OnWindowAddedToLayout(child);
541 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child));
542 child->OnParentChanged();
543
544 Window* root_window = GetRootWindow();
545 if (root_window && old_root != root_window) {
546 root_window->GetHost()->dispatcher()->OnWindowAddedToRootWindow(child);
547 child->NotifyAddedToRootWindow();
548 }
549
550 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
551 NotifyWindowHierarchyChange(params);
552 }
553
RemoveChild(Window * child)554 void Window::RemoveChild(Window* child) {
555 WindowObserver::HierarchyChangeParams params;
556 params.target = child;
557 params.new_parent = NULL;
558 params.old_parent = this;
559 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
560 NotifyWindowHierarchyChange(params);
561
562 RemoveChildImpl(child, NULL);
563
564 params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
565 NotifyWindowHierarchyChange(params);
566 }
567
Contains(const Window * other) const568 bool Window::Contains(const Window* other) const {
569 for (const Window* parent = other; parent; parent = parent->parent_) {
570 if (parent == this)
571 return true;
572 }
573 return false;
574 }
575
GetChildById(int id)576 Window* Window::GetChildById(int id) {
577 return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id));
578 }
579
GetChildById(int id) const580 const Window* Window::GetChildById(int id) const {
581 Windows::const_iterator i;
582 for (i = children_.begin(); i != children_.end(); ++i) {
583 if ((*i)->id() == id)
584 return *i;
585 const Window* result = (*i)->GetChildById(id);
586 if (result)
587 return result;
588 }
589 return NULL;
590 }
591
592 // static
ConvertPointToTarget(const Window * source,const Window * target,gfx::Point * point)593 void Window::ConvertPointToTarget(const Window* source,
594 const Window* target,
595 gfx::Point* point) {
596 if (!source)
597 return;
598 if (source->GetRootWindow() != target->GetRootWindow()) {
599 client::ScreenPositionClient* source_client =
600 client::GetScreenPositionClient(source->GetRootWindow());
601 // |source_client| can be NULL in tests.
602 if (source_client)
603 source_client->ConvertPointToScreen(source, point);
604
605 client::ScreenPositionClient* target_client =
606 client::GetScreenPositionClient(target->GetRootWindow());
607 // |target_client| can be NULL in tests.
608 if (target_client)
609 target_client->ConvertPointFromScreen(target, point);
610 } else if ((source != target) && (!source->layer() || !target->layer())) {
611 if (!source->layer()) {
612 gfx::Vector2d offset_to_layer;
613 source = source->GetAncestorWithLayer(&offset_to_layer);
614 *point += offset_to_layer;
615 }
616 if (!target->layer()) {
617 gfx::Vector2d offset_to_layer;
618 target = target->GetAncestorWithLayer(&offset_to_layer);
619 *point -= offset_to_layer;
620 }
621 ui::Layer::ConvertPointToLayer(source->layer(), target->layer(), point);
622 } else {
623 ui::Layer::ConvertPointToLayer(source->layer(), target->layer(), point);
624 }
625 }
626
627 // static
ConvertRectToTarget(const Window * source,const Window * target,gfx::Rect * rect)628 void Window::ConvertRectToTarget(const Window* source,
629 const Window* target,
630 gfx::Rect* rect) {
631 DCHECK(rect);
632 gfx::Point origin = rect->origin();
633 ConvertPointToTarget(source, target, &origin);
634 rect->set_origin(origin);
635 }
636
MoveCursorTo(const gfx::Point & point_in_window)637 void Window::MoveCursorTo(const gfx::Point& point_in_window) {
638 Window* root_window = GetRootWindow();
639 DCHECK(root_window);
640 gfx::Point point_in_root(point_in_window);
641 ConvertPointToTarget(this, root_window, &point_in_root);
642 root_window->GetHost()->MoveCursorTo(point_in_root);
643 }
644
GetCursor(const gfx::Point & point) const645 gfx::NativeCursor Window::GetCursor(const gfx::Point& point) const {
646 return delegate_ ? delegate_->GetCursor(point) : gfx::kNullCursor;
647 }
648
AddObserver(WindowObserver * observer)649 void Window::AddObserver(WindowObserver* observer) {
650 observer->OnObservingWindow(this);
651 observers_.AddObserver(observer);
652 }
653
RemoveObserver(WindowObserver * observer)654 void Window::RemoveObserver(WindowObserver* observer) {
655 observer->OnUnobservingWindow(this);
656 observers_.RemoveObserver(observer);
657 }
658
HasObserver(WindowObserver * observer)659 bool Window::HasObserver(WindowObserver* observer) {
660 return observers_.HasObserver(observer);
661 }
662
ContainsPointInRoot(const gfx::Point & point_in_root) const663 bool Window::ContainsPointInRoot(const gfx::Point& point_in_root) const {
664 const Window* root_window = GetRootWindow();
665 if (!root_window)
666 return false;
667 gfx::Point local_point(point_in_root);
668 ConvertPointToTarget(root_window, this, &local_point);
669 return gfx::Rect(GetTargetBounds().size()).Contains(local_point);
670 }
671
ContainsPoint(const gfx::Point & local_point) const672 bool Window::ContainsPoint(const gfx::Point& local_point) const {
673 return gfx::Rect(bounds().size()).Contains(local_point);
674 }
675
GetEventHandlerForPoint(const gfx::Point & local_point)676 Window* Window::GetEventHandlerForPoint(const gfx::Point& local_point) {
677 return GetWindowForPoint(local_point, true, true);
678 }
679
GetTopWindowContainingPoint(const gfx::Point & local_point)680 Window* Window::GetTopWindowContainingPoint(const gfx::Point& local_point) {
681 return GetWindowForPoint(local_point, false, false);
682 }
683
GetToplevelWindow()684 Window* Window::GetToplevelWindow() {
685 Window* topmost_window_with_delegate = NULL;
686 for (aura::Window* window = this; window != NULL; window = window->parent()) {
687 if (window->delegate())
688 topmost_window_with_delegate = window;
689 }
690 return topmost_window_with_delegate;
691 }
692
Focus()693 void Window::Focus() {
694 client::FocusClient* client = client::GetFocusClient(this);
695 DCHECK(client);
696 client->FocusWindow(this);
697 }
698
Blur()699 void Window::Blur() {
700 client::FocusClient* client = client::GetFocusClient(this);
701 DCHECK(client);
702 client->FocusWindow(NULL);
703 }
704
HasFocus() const705 bool Window::HasFocus() const {
706 client::FocusClient* client = client::GetFocusClient(this);
707 return client && client->GetFocusedWindow() == this;
708 }
709
CanFocus() const710 bool Window::CanFocus() const {
711 if (IsRootWindow())
712 return IsVisible();
713
714 // NOTE: as part of focusing the window the ActivationClient may make the
715 // window visible (by way of making a hidden ancestor visible). For this
716 // reason we can't check visibility here and assume the client is doing it.
717 if (!parent_ || (delegate_ && !delegate_->CanFocus()))
718 return false;
719
720 // The client may forbid certain windows from receiving focus at a given point
721 // in time.
722 client::EventClient* client = client::GetEventClient(GetRootWindow());
723 if (client && !client->CanProcessEventsWithinSubtree(this))
724 return false;
725
726 return parent_->CanFocus();
727 }
728
CanReceiveEvents() const729 bool Window::CanReceiveEvents() const {
730 if (IsRootWindow())
731 return IsVisible();
732
733 // The client may forbid certain windows from receiving events at a given
734 // point in time.
735 client::EventClient* client = client::GetEventClient(GetRootWindow());
736 if (client && !client->CanProcessEventsWithinSubtree(this))
737 return false;
738
739 return parent_ && IsVisible() && parent_->CanReceiveEvents();
740 }
741
SetCapture()742 void Window::SetCapture() {
743 if (!IsVisible())
744 return;
745
746 Window* root_window = GetRootWindow();
747 if (!root_window)
748 return;
749 client::GetCaptureClient(root_window)->SetCapture(this);
750 }
751
ReleaseCapture()752 void Window::ReleaseCapture() {
753 Window* root_window = GetRootWindow();
754 if (!root_window)
755 return;
756 client::GetCaptureClient(root_window)->ReleaseCapture(this);
757 }
758
HasCapture()759 bool Window::HasCapture() {
760 Window* root_window = GetRootWindow();
761 if (!root_window)
762 return false;
763 client::CaptureClient* capture_client = client::GetCaptureClient(root_window);
764 return capture_client && capture_client->GetCaptureWindow() == this;
765 }
766
SuppressPaint()767 void Window::SuppressPaint() {
768 if (layer())
769 layer()->SuppressPaint();
770 }
771
772 // {Set,Get,Clear}Property are implemented in window_property.h.
773
SetNativeWindowProperty(const char * key,void * value)774 void Window::SetNativeWindowProperty(const char* key, void* value) {
775 SetPropertyInternal(
776 key, key, NULL, reinterpret_cast<int64>(value), 0);
777 }
778
GetNativeWindowProperty(const char * key) const779 void* Window::GetNativeWindowProperty(const char* key) const {
780 return reinterpret_cast<void*>(GetPropertyInternal(key, 0));
781 }
782
OnDeviceScaleFactorChanged(float device_scale_factor)783 void Window::OnDeviceScaleFactorChanged(float device_scale_factor) {
784 ScopedCursorHider hider(this);
785 if (IsRootWindow())
786 host_->OnDeviceScaleFactorChanged(device_scale_factor);
787 if (delegate_)
788 delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
789 }
790
791 #if !defined(NDEBUG)
GetDebugInfo() const792 std::string Window::GetDebugInfo() const {
793 return base::StringPrintf(
794 "%s<%d> bounds(%d, %d, %d, %d) %s %s opacity=%.1f",
795 name().empty() ? "Unknown" : name().c_str(), id(),
796 bounds().x(), bounds().y(), bounds().width(), bounds().height(),
797 visible_ ? "WindowVisible" : "WindowHidden",
798 layer() ?
799 (layer()->GetTargetVisibility() ? "LayerVisible" : "LayerHidden") :
800 "NoLayer",
801 layer() ? layer()->opacity() : 1.0f);
802 }
803
PrintWindowHierarchy(int depth) const804 void Window::PrintWindowHierarchy(int depth) const {
805 VLOG(0) << base::StringPrintf(
806 "%*s%s", depth * 2, "", GetDebugInfo().c_str());
807 for (Windows::const_iterator it = children_.begin();
808 it != children_.end(); ++it) {
809 Window* child = *it;
810 child->PrintWindowHierarchy(depth + 1);
811 }
812 }
813 #endif
814
RemoveOrDestroyChildren()815 void Window::RemoveOrDestroyChildren() {
816 while (!children_.empty()) {
817 Window* child = children_[0];
818 if (child->owned_by_parent_) {
819 delete child;
820 // Deleting the child so remove it from out children_ list.
821 DCHECK(std::find(children_.begin(), children_.end(), child) ==
822 children_.end());
823 } else {
824 // Even if we can't delete the child, we still need to remove it from the
825 // parent so that relevant bookkeeping (parent_ back-pointers etc) are
826 // updated.
827 RemoveChild(child);
828 }
829 }
830 }
831
832 ///////////////////////////////////////////////////////////////////////////////
833 // Window, private:
834
SetPropertyInternal(const void * key,const char * name,PropertyDeallocator deallocator,int64 value,int64 default_value)835 int64 Window::SetPropertyInternal(const void* key,
836 const char* name,
837 PropertyDeallocator deallocator,
838 int64 value,
839 int64 default_value) {
840 int64 old = GetPropertyInternal(key, default_value);
841 if (value == default_value) {
842 prop_map_.erase(key);
843 } else {
844 Value prop_value;
845 prop_value.name = name;
846 prop_value.value = value;
847 prop_value.deallocator = deallocator;
848 prop_map_[key] = prop_value;
849 }
850 FOR_EACH_OBSERVER(WindowObserver, observers_,
851 OnWindowPropertyChanged(this, key, old));
852 return old;
853 }
854
GetPropertyInternal(const void * key,int64 default_value) const855 int64 Window::GetPropertyInternal(const void* key,
856 int64 default_value) const {
857 std::map<const void*, Value>::const_iterator iter = prop_map_.find(key);
858 if (iter == prop_map_.end())
859 return default_value;
860 return iter->second.value;
861 }
862
HitTest(const gfx::Point & local_point)863 bool Window::HitTest(const gfx::Point& local_point) {
864 gfx::Rect local_bounds(bounds().size());
865 if (!delegate_ || !delegate_->HasHitTestMask())
866 return local_bounds.Contains(local_point);
867
868 gfx::Path mask;
869 delegate_->GetHitTestMask(&mask);
870
871 SkRegion clip_region;
872 clip_region.setRect(local_bounds.x(), local_bounds.y(),
873 local_bounds.width(), local_bounds.height());
874 SkRegion mask_region;
875 return mask_region.setPath(mask, clip_region) &&
876 mask_region.contains(local_point.x(), local_point.y());
877 }
878
SetBoundsInternal(const gfx::Rect & new_bounds)879 void Window::SetBoundsInternal(const gfx::Rect& new_bounds) {
880 gfx::Rect actual_new_bounds(new_bounds);
881 gfx::Rect old_bounds = GetTargetBounds();
882
883 // Always need to set the layer's bounds -- even if it is to the same thing.
884 // This may cause important side effects such as stopping animation.
885 if (!layer()) {
886 const gfx::Vector2d origin_delta = new_bounds.OffsetFromOrigin() -
887 bounds_.OffsetFromOrigin();
888 bounds_ = new_bounds;
889 OffsetLayerBounds(origin_delta);
890 } else {
891 if (parent_ && !parent_->layer()) {
892 gfx::Vector2d offset;
893 const aura::Window* ancestor_with_layer =
894 parent_->GetAncestorWithLayer(&offset);
895 if (ancestor_with_layer)
896 actual_new_bounds.Offset(offset);
897 }
898 layer()->SetBounds(actual_new_bounds);
899 }
900
901 // If we are currently not the layer's delegate, we will not get bounds
902 // changed notification from the layer (this typically happens after animating
903 // hidden). We must notify ourselves.
904 if (!layer() || layer()->delegate() != this)
905 OnWindowBoundsChanged(old_bounds);
906 }
907
SetVisible(bool visible)908 void Window::SetVisible(bool visible) {
909 if ((layer() && visible == layer()->GetTargetVisibility()) ||
910 (!layer() && visible == visible_))
911 return; // No change.
912
913 FOR_EACH_OBSERVER(WindowObserver, observers_,
914 OnWindowVisibilityChanging(this, visible));
915
916 client::VisibilityClient* visibility_client =
917 client::GetVisibilityClient(this);
918 if (visibility_client)
919 visibility_client->UpdateLayerVisibility(this, visible);
920 else if (layer())
921 layer()->SetVisible(visible);
922 visible_ = visible;
923 SchedulePaint();
924 if (parent_ && parent_->layout_manager_)
925 parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible);
926
927 if (delegate_)
928 delegate_->OnWindowTargetVisibilityChanged(visible);
929
930 NotifyWindowVisibilityChanged(this, visible);
931 }
932
SchedulePaint()933 void Window::SchedulePaint() {
934 SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height()));
935 }
936
Paint(gfx::Canvas * canvas)937 void Window::Paint(gfx::Canvas* canvas) {
938 if (delegate_)
939 delegate_->OnPaint(canvas);
940 PaintLayerlessChildren(canvas);
941 }
942
PaintLayerlessChildren(gfx::Canvas * canvas)943 void Window::PaintLayerlessChildren(gfx::Canvas* canvas) {
944 for (size_t i = 0, count = children_.size(); i < count; ++i) {
945 Window* child = children_[i];
946 if (!child->layer() && child->visible_) {
947 gfx::ScopedCanvas scoped_canvas(canvas);
948 canvas->ClipRect(child->bounds());
949 if (!canvas->IsClipEmpty()) {
950 canvas->Translate(child->bounds().OffsetFromOrigin());
951 child->Paint(canvas);
952 }
953 }
954 }
955 }
956
GetWindowForPoint(const gfx::Point & local_point,bool return_tightest,bool for_event_handling)957 Window* Window::GetWindowForPoint(const gfx::Point& local_point,
958 bool return_tightest,
959 bool for_event_handling) {
960 if (!IsVisible())
961 return NULL;
962
963 if ((for_event_handling && !HitTest(local_point)) ||
964 (!for_event_handling && !ContainsPoint(local_point)))
965 return NULL;
966
967 // Check if I should claim this event and not pass it to my children because
968 // the location is inside my hit test override area. For details, see
969 // set_hit_test_bounds_override_inner().
970 if (for_event_handling && !hit_test_bounds_override_inner_.empty()) {
971 gfx::Rect inset_local_bounds(gfx::Point(), bounds().size());
972 inset_local_bounds.Inset(hit_test_bounds_override_inner_);
973 // We know we're inside the normal local bounds, so if we're outside the
974 // inset bounds we must be in the special hit test override area.
975 DCHECK(HitTest(local_point));
976 if (!inset_local_bounds.Contains(local_point))
977 return delegate_ ? this : NULL;
978 }
979
980 if (!return_tightest && delegate_)
981 return this;
982
983 for (Windows::const_reverse_iterator it = children_.rbegin(),
984 rend = children_.rend();
985 it != rend; ++it) {
986 Window* child = *it;
987
988 if (for_event_handling) {
989 if (child->ignore_events_)
990 continue;
991 // The client may not allow events to be processed by certain subtrees.
992 client::EventClient* client = client::GetEventClient(GetRootWindow());
993 if (client && !client->CanProcessEventsWithinSubtree(child))
994 continue;
995 if (delegate_ && !delegate_->ShouldDescendIntoChildForEventHandling(
996 child, local_point))
997 continue;
998 }
999
1000 gfx::Point point_in_child_coords(local_point);
1001 ConvertPointToTarget(this, child, &point_in_child_coords);
1002 Window* match = child->GetWindowForPoint(point_in_child_coords,
1003 return_tightest,
1004 for_event_handling);
1005 if (match)
1006 return match;
1007 }
1008
1009 return delegate_ ? this : NULL;
1010 }
1011
RemoveChildImpl(Window * child,Window * new_parent)1012 void Window::RemoveChildImpl(Window* child, Window* new_parent) {
1013 if (layout_manager_)
1014 layout_manager_->OnWillRemoveWindowFromLayout(child);
1015 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child));
1016 Window* root_window = child->GetRootWindow();
1017 Window* new_root_window = new_parent ? new_parent->GetRootWindow() : NULL;
1018 if (root_window && root_window != new_root_window)
1019 child->NotifyRemovingFromRootWindow(new_root_window);
1020
1021 gfx::Vector2d offset;
1022 GetAncestorWithLayer(&offset);
1023 child->UnparentLayers(!layer(), offset);
1024 child->parent_ = NULL;
1025 Windows::iterator i = std::find(children_.begin(), children_.end(), child);
1026 DCHECK(i != children_.end());
1027 children_.erase(i);
1028 child->OnParentChanged();
1029 if (layout_manager_)
1030 layout_manager_->OnWindowRemovedFromLayout(child);
1031 }
1032
UnparentLayers(bool has_layerless_ancestor,const gfx::Vector2d & offset)1033 void Window::UnparentLayers(bool has_layerless_ancestor,
1034 const gfx::Vector2d& offset) {
1035 if (!layer()) {
1036 const gfx::Vector2d new_offset = offset + bounds().OffsetFromOrigin();
1037 for (size_t i = 0; i < children_.size(); ++i) {
1038 children_[i]->UnparentLayers(true, new_offset);
1039 }
1040 } else {
1041 // Only remove the layer if we still own it. Someone else may have acquired
1042 // ownership of it via AcquireLayer() and may expect the hierarchy to go
1043 // unchanged as the Window is destroyed.
1044 if (OwnsLayer()) {
1045 if (layer()->parent())
1046 layer()->parent()->Remove(layer());
1047 if (has_layerless_ancestor) {
1048 const gfx::Rect real_bounds(bounds_);
1049 gfx::Rect layer_bounds(layer()->bounds());
1050 layer_bounds.Offset(-offset);
1051 layer()->SetBounds(layer_bounds);
1052 bounds_ = real_bounds;
1053 }
1054 }
1055 }
1056 }
1057
ReparentLayers(ui::Layer * parent_layer,const gfx::Vector2d & offset)1058 void Window::ReparentLayers(ui::Layer* parent_layer,
1059 const gfx::Vector2d& offset) {
1060 if (!layer()) {
1061 for (size_t i = 0; i < children_.size(); ++i) {
1062 children_[i]->ReparentLayers(
1063 parent_layer,
1064 offset + children_[i]->bounds().OffsetFromOrigin());
1065 }
1066 } else {
1067 const gfx::Rect real_bounds(bounds());
1068 parent_layer->Add(layer());
1069 gfx::Rect layer_bounds(layer()->bounds().size());
1070 layer_bounds += offset;
1071 layer()->SetBounds(layer_bounds);
1072 bounds_ = real_bounds;
1073 }
1074 }
1075
OffsetLayerBounds(const gfx::Vector2d & offset)1076 void Window::OffsetLayerBounds(const gfx::Vector2d& offset) {
1077 if (!layer()) {
1078 for (size_t i = 0; i < children_.size(); ++i)
1079 children_[i]->OffsetLayerBounds(offset);
1080 } else {
1081 gfx::Rect layer_bounds(layer()->bounds());
1082 layer_bounds += offset;
1083 layer()->SetBounds(layer_bounds);
1084 }
1085 }
1086
OnParentChanged()1087 void Window::OnParentChanged() {
1088 FOR_EACH_OBSERVER(
1089 WindowObserver, observers_, OnWindowParentChanged(this, parent_));
1090 }
1091
StackChildRelativeTo(Window * child,Window * target,StackDirection direction)1092 void Window::StackChildRelativeTo(Window* child,
1093 Window* target,
1094 StackDirection direction) {
1095 DCHECK_NE(child, target);
1096 DCHECK(child);
1097 DCHECK(target);
1098 DCHECK_EQ(this, child->parent());
1099 DCHECK_EQ(this, target->parent());
1100
1101 client::WindowStackingClient* stacking_client =
1102 client::GetWindowStackingClient();
1103 if (stacking_client &&
1104 !stacking_client->AdjustStacking(&child, &target, &direction))
1105 return;
1106
1107 const size_t child_i =
1108 std::find(children_.begin(), children_.end(), child) - children_.begin();
1109 const size_t target_i =
1110 std::find(children_.begin(), children_.end(), target) - children_.begin();
1111
1112 // Don't move the child if it is already in the right place.
1113 if ((direction == STACK_ABOVE && child_i == target_i + 1) ||
1114 (direction == STACK_BELOW && child_i + 1 == target_i))
1115 return;
1116
1117 const size_t dest_i =
1118 direction == STACK_ABOVE ?
1119 (child_i < target_i ? target_i : target_i + 1) :
1120 (child_i < target_i ? target_i - 1 : target_i);
1121 children_.erase(children_.begin() + child_i);
1122 children_.insert(children_.begin() + dest_i, child);
1123
1124 StackChildLayerRelativeTo(child, target, direction);
1125
1126 child->OnStackingChanged();
1127 }
1128
StackChildLayerRelativeTo(Window * child,Window * target,StackDirection direction)1129 void Window::StackChildLayerRelativeTo(Window* child,
1130 Window* target,
1131 StackDirection direction) {
1132 Window* ancestor_with_layer = GetAncestorWithLayer(NULL);
1133 ui::Layer* ancestor_layer =
1134 ancestor_with_layer ? ancestor_with_layer->layer() : NULL;
1135 if (!ancestor_layer)
1136 return;
1137
1138 if (child->layer() && target->layer()) {
1139 if (direction == STACK_ABOVE)
1140 ancestor_layer->StackAbove(child->layer(), target->layer());
1141 else
1142 ancestor_layer->StackBelow(child->layer(), target->layer());
1143 return;
1144 }
1145 typedef std::vector<ui::Layer*> Layers;
1146 Layers layers;
1147 GetLayersToStack(child, &layers);
1148 if (layers.empty())
1149 return;
1150
1151 ui::Layer* target_layer;
1152 if (direction == STACK_ABOVE) {
1153 target_layer =
1154 FindStackingTargetLayer<Windows::const_reverse_iterator>(target, child);
1155 } else {
1156 target_layer =
1157 FindStackingTargetLayer<Windows::const_iterator>(target, child);
1158 }
1159
1160 if (!target_layer) {
1161 if (direction == STACK_ABOVE) {
1162 for (Layers::const_reverse_iterator i = layers.rbegin(),
1163 rend = layers.rend(); i != rend; ++i) {
1164 ancestor_layer->StackAtBottom(*i);
1165 }
1166 } else {
1167 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1168 ancestor_layer->StackAtTop(*i);
1169 }
1170 return;
1171 }
1172
1173 if (direction == STACK_ABOVE) {
1174 for (Layers::const_reverse_iterator i = layers.rbegin(),
1175 rend = layers.rend(); i != rend; ++i) {
1176 ancestor_layer->StackAbove(*i, target_layer);
1177 }
1178 } else {
1179 for (Layers::const_iterator i = layers.begin(); i != layers.end(); ++i)
1180 ancestor_layer->StackBelow(*i, target_layer);
1181 }
1182 }
1183
OnStackingChanged()1184 void Window::OnStackingChanged() {
1185 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowStackingChanged(this));
1186 }
1187
NotifyRemovingFromRootWindow(Window * new_root)1188 void Window::NotifyRemovingFromRootWindow(Window* new_root) {
1189 FOR_EACH_OBSERVER(WindowObserver, observers_,
1190 OnWindowRemovingFromRootWindow(this, new_root));
1191 for (Window::Windows::const_iterator it = children_.begin();
1192 it != children_.end(); ++it) {
1193 (*it)->NotifyRemovingFromRootWindow(new_root);
1194 }
1195 }
1196
NotifyAddedToRootWindow()1197 void Window::NotifyAddedToRootWindow() {
1198 FOR_EACH_OBSERVER(WindowObserver, observers_,
1199 OnWindowAddedToRootWindow(this));
1200 for (Window::Windows::const_iterator it = children_.begin();
1201 it != children_.end(); ++it) {
1202 (*it)->NotifyAddedToRootWindow();
1203 }
1204 }
1205
NotifyWindowHierarchyChange(const WindowObserver::HierarchyChangeParams & params)1206 void Window::NotifyWindowHierarchyChange(
1207 const WindowObserver::HierarchyChangeParams& params) {
1208 params.target->NotifyWindowHierarchyChangeDown(params);
1209 switch (params.phase) {
1210 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1211 if (params.old_parent)
1212 params.old_parent->NotifyWindowHierarchyChangeUp(params);
1213 break;
1214 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1215 if (params.new_parent)
1216 params.new_parent->NotifyWindowHierarchyChangeUp(params);
1217 break;
1218 default:
1219 NOTREACHED();
1220 break;
1221 }
1222 }
1223
NotifyWindowHierarchyChangeDown(const WindowObserver::HierarchyChangeParams & params)1224 void Window::NotifyWindowHierarchyChangeDown(
1225 const WindowObserver::HierarchyChangeParams& params) {
1226 NotifyWindowHierarchyChangeAtReceiver(params);
1227 for (Window::Windows::const_iterator it = children_.begin();
1228 it != children_.end(); ++it) {
1229 (*it)->NotifyWindowHierarchyChangeDown(params);
1230 }
1231 }
1232
NotifyWindowHierarchyChangeUp(const WindowObserver::HierarchyChangeParams & params)1233 void Window::NotifyWindowHierarchyChangeUp(
1234 const WindowObserver::HierarchyChangeParams& params) {
1235 for (Window* window = this; window; window = window->parent())
1236 window->NotifyWindowHierarchyChangeAtReceiver(params);
1237 }
1238
NotifyWindowHierarchyChangeAtReceiver(const WindowObserver::HierarchyChangeParams & params)1239 void Window::NotifyWindowHierarchyChangeAtReceiver(
1240 const WindowObserver::HierarchyChangeParams& params) {
1241 WindowObserver::HierarchyChangeParams local_params = params;
1242 local_params.receiver = this;
1243
1244 switch (params.phase) {
1245 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING:
1246 FOR_EACH_OBSERVER(WindowObserver, observers_,
1247 OnWindowHierarchyChanging(local_params));
1248 break;
1249 case WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED:
1250 FOR_EACH_OBSERVER(WindowObserver, observers_,
1251 OnWindowHierarchyChanged(local_params));
1252 break;
1253 default:
1254 NOTREACHED();
1255 break;
1256 }
1257 }
1258
NotifyWindowVisibilityChanged(aura::Window * target,bool visible)1259 void Window::NotifyWindowVisibilityChanged(aura::Window* target,
1260 bool visible) {
1261 if (!NotifyWindowVisibilityChangedDown(target, visible)) {
1262 return; // |this| has been deleted.
1263 }
1264 NotifyWindowVisibilityChangedUp(target, visible);
1265 }
1266
NotifyWindowVisibilityChangedAtReceiver(aura::Window * target,bool visible)1267 bool Window::NotifyWindowVisibilityChangedAtReceiver(aura::Window* target,
1268 bool visible) {
1269 // |this| may be deleted during a call to OnWindowVisibilityChanged() on one
1270 // of the observers. We create an local observer for that. In that case we
1271 // exit without further access to any members.
1272 WindowTracker tracker;
1273 tracker.Add(this);
1274 FOR_EACH_OBSERVER(WindowObserver, observers_,
1275 OnWindowVisibilityChanged(target, visible));
1276 return tracker.Contains(this);
1277 }
1278
NotifyWindowVisibilityChangedDown(aura::Window * target,bool visible)1279 bool Window::NotifyWindowVisibilityChangedDown(aura::Window* target,
1280 bool visible) {
1281 if (!NotifyWindowVisibilityChangedAtReceiver(target, visible))
1282 return false; // |this| was deleted.
1283 std::set<const Window*> child_already_processed;
1284 bool child_destroyed = false;
1285 do {
1286 child_destroyed = false;
1287 for (Window::Windows::const_iterator it = children_.begin();
1288 it != children_.end(); ++it) {
1289 if (!child_already_processed.insert(*it).second)
1290 continue;
1291 if (!(*it)->NotifyWindowVisibilityChangedDown(target, visible)) {
1292 // |*it| was deleted, |it| is invalid and |children_| has changed.
1293 // We exit the current for-loop and enter a new one.
1294 child_destroyed = true;
1295 break;
1296 }
1297 }
1298 } while (child_destroyed);
1299 return true;
1300 }
1301
NotifyWindowVisibilityChangedUp(aura::Window * target,bool visible)1302 void Window::NotifyWindowVisibilityChangedUp(aura::Window* target,
1303 bool visible) {
1304 for (Window* window = this; window; window = window->parent()) {
1305 bool ret = window->NotifyWindowVisibilityChangedAtReceiver(target, visible);
1306 DCHECK(ret);
1307 }
1308 }
1309
OnWindowBoundsChanged(const gfx::Rect & old_bounds)1310 void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds) {
1311 if (layer()) {
1312 bounds_ = layer()->bounds();
1313 if (parent_ && !parent_->layer()) {
1314 gfx::Vector2d offset;
1315 aura::Window* ancestor_with_layer =
1316 parent_->GetAncestorWithLayer(&offset);
1317 if (ancestor_with_layer)
1318 bounds_.Offset(-offset);
1319 }
1320 }
1321
1322 if (layout_manager_)
1323 layout_manager_->OnWindowResized();
1324 if (delegate_)
1325 delegate_->OnBoundsChanged(old_bounds, bounds());
1326 FOR_EACH_OBSERVER(WindowObserver,
1327 observers_,
1328 OnWindowBoundsChanged(this, old_bounds, bounds()));
1329 }
1330
CleanupGestureState()1331 bool Window::CleanupGestureState() {
1332 bool state_modified = false;
1333 state_modified |= ui::GestureRecognizer::Get()->CancelActiveTouches(this);
1334 state_modified |=
1335 ui::GestureRecognizer::Get()->CleanupStateForConsumer(this);
1336 for (Window::Windows::iterator iter = children_.begin();
1337 iter != children_.end();
1338 ++iter) {
1339 state_modified |= (*iter)->CleanupGestureState();
1340 }
1341 return state_modified;
1342 }
1343
OnPaintLayer(gfx::Canvas * canvas)1344 void Window::OnPaintLayer(gfx::Canvas* canvas) {
1345 Paint(canvas);
1346 }
1347
PrepareForLayerBoundsChange()1348 base::Closure Window::PrepareForLayerBoundsChange() {
1349 return base::Bind(&Window::OnWindowBoundsChanged, base::Unretained(this),
1350 bounds());
1351 }
1352
CanAcceptEvent(const ui::Event & event)1353 bool Window::CanAcceptEvent(const ui::Event& event) {
1354 // The client may forbid certain windows from receiving events at a given
1355 // point in time.
1356 client::EventClient* client = client::GetEventClient(GetRootWindow());
1357 if (client && !client->CanProcessEventsWithinSubtree(this))
1358 return false;
1359
1360 // We need to make sure that a touch cancel event and any gesture events it
1361 // creates can always reach the window. This ensures that we receive a valid
1362 // touch / gesture stream.
1363 if (event.IsEndingEvent())
1364 return true;
1365
1366 if (!IsVisible())
1367 return false;
1368
1369 // The top-most window can always process an event.
1370 if (!parent_)
1371 return true;
1372
1373 // For located events (i.e. mouse, touch etc.), an assumption is made that
1374 // windows that don't have a default event-handler cannot process the event
1375 // (see more in GetWindowForPoint()). This assumption is not made for key
1376 // events.
1377 return event.IsKeyEvent() || target_handler();
1378 }
1379
GetParentTarget()1380 ui::EventTarget* Window::GetParentTarget() {
1381 if (IsRootWindow()) {
1382 return client::GetEventClient(this) ?
1383 client::GetEventClient(this)->GetToplevelEventTarget() :
1384 Env::GetInstance();
1385 }
1386 return parent_;
1387 }
1388
GetChildIterator() const1389 scoped_ptr<ui::EventTargetIterator> Window::GetChildIterator() const {
1390 return scoped_ptr<ui::EventTargetIterator>(
1391 new ui::EventTargetIteratorImpl<Window>(children()));
1392 }
1393
GetEventTargeter()1394 ui::EventTargeter* Window::GetEventTargeter() {
1395 return targeter_.get();
1396 }
1397
ConvertEventToTarget(ui::EventTarget * target,ui::LocatedEvent * event)1398 void Window::ConvertEventToTarget(ui::EventTarget* target,
1399 ui::LocatedEvent* event) {
1400 event->ConvertLocationToTarget(this,
1401 static_cast<Window*>(target));
1402 }
1403
UpdateLayerName()1404 void Window::UpdateLayerName() {
1405 #if !defined(NDEBUG)
1406 DCHECK(layer());
1407
1408 std::string layer_name(name_);
1409 if (layer_name.empty())
1410 layer_name = "Unnamed Window";
1411
1412 if (id_ != -1)
1413 layer_name += " " + base::IntToString(id_);
1414
1415 layer()->set_name(layer_name);
1416 #endif
1417 }
1418
ContainsMouse()1419 bool Window::ContainsMouse() {
1420 bool contains_mouse = false;
1421 if (IsVisible()) {
1422 WindowTreeHost* host = GetHost();
1423 contains_mouse = host &&
1424 ContainsPointInRoot(host->dispatcher()->GetLastMouseLocationInRoot());
1425 }
1426 return contains_mouse;
1427 }
1428
GetAncestorWithLayer(gfx::Vector2d * offset) const1429 const Window* Window::GetAncestorWithLayer(gfx::Vector2d* offset) const {
1430 for (const aura::Window* window = this; window; window = window->parent()) {
1431 if (window->layer())
1432 return window;
1433 if (offset)
1434 *offset += window->bounds().OffsetFromOrigin();
1435 }
1436 if (offset)
1437 *offset = gfx::Vector2d();
1438 return NULL;
1439 }
1440
1441 } // namespace aura
1442