window.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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/stl_util.h"
14#include "base/string_util.h"
15#include "base/stringprintf.h"
16#include "ui/aura/client/capture_client.h"
17#include "ui/aura/client/event_client.h"
18#include "ui/aura/client/screen_position_client.h"
19#include "ui/aura/client/stacking_client.h"
20#include "ui/aura/client/visibility_client.h"
21#include "ui/aura/env.h"
22#include "ui/aura/event_filter.h"
23#include "ui/aura/focus_manager.h"
24#include "ui/aura/layout_manager.h"
25#include "ui/aura/root_window.h"
26#include "ui/aura/window_delegate.h"
27#include "ui/aura/window_observer.h"
28#include "ui/base/animation/multi_animation.h"
29#include "ui/compositor/compositor.h"
30#include "ui/compositor/layer.h"
31#include "ui/gfx/canvas.h"
32#include "ui/gfx/path.h"
33#include "ui/gfx/screen.h"
34
35namespace aura {
36
37namespace {
38
39Window* GetParentForWindow(Window* window, Window* suggested_parent) {
40  if (suggested_parent)
41    return suggested_parent;
42  if (client::GetStackingClient())
43    return client::GetStackingClient()->GetDefaultParent(window, gfx::Rect());
44  return NULL;
45}
46
47}  // namespace
48
49Window::TestApi::TestApi(Window* window) : window_(window) {}
50
51bool Window::TestApi::OwnsLayer() const {
52  return !!window_->layer_owner_.get();
53}
54
55bool Window::TestApi::ContainsMouse() {
56  return window_->ContainsMouse();
57}
58
59Window::Window(WindowDelegate* delegate)
60    : type_(client::WINDOW_TYPE_UNKNOWN),
61      owned_by_parent_(true),
62      delegate_(delegate),
63      parent_(NULL),
64      transient_parent_(NULL),
65      visible_(false),
66      id_(-1),
67      transparent_(false),
68      user_data_(NULL),
69      ignore_events_(false),
70      // Don't notify newly added observers during notification. This causes
71      // problems for code that adds an observer as part of an observer
72      // notification (such as the workspace code).
73      observers_(ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY) {
74  set_target_handler(delegate_);
75}
76
77Window::~Window() {
78  // layer_ can be NULL if Init() wasn't invoked, which can happen
79  // only in tests.
80  if (layer_)
81    layer_->SuppressPaint();
82
83  // Let the delegate know we're in the processing of destroying.
84  if (delegate_)
85    delegate_->OnWindowDestroying();
86  FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this));
87
88  // Let the root know so that it can remove any references to us.
89  RootWindow* root_window = GetRootWindow();
90  if (root_window)
91    root_window->OnWindowDestroying(this);
92
93  // Then destroy the children.
94  while (!children_.empty()) {
95    Window* child = children_[0];
96    if (child->owned_by_parent_) {
97      delete child;
98      // Deleting the child so remove it from out children_ list.
99      DCHECK(std::find(children_.begin(), children_.end(), child) ==
100             children_.end());
101    } else {
102      // Even if we can't delete the child, we still need to remove it from the
103      // parent so that relevant bookkeeping (parent_ back-pointers etc) are
104      // updated.
105      RemoveChild(child);
106    }
107  }
108
109  // Removes ourselves from our transient parent (if it hasn't been done by the
110  // RootWindow).
111  if (transient_parent_)
112    transient_parent_->RemoveTransientChild(this);
113
114  // The window needs to be removed from the parent before calling the
115  // WindowDestroyed callbacks of delegate and the observers.
116  if (parent_)
117    parent_->RemoveChild(this);
118
119  // And let the delegate do any post cleanup.
120  // TODO(beng): Figure out if this notification needs to happen here, or if it
121  // can be moved down adjacent to the observer notification. If it has to be
122  // done here, the reason why should be documented.
123  if (delegate_)
124    delegate_->OnWindowDestroyed();
125
126  // Destroy transient children, only after we've removed ourselves from our
127  // parent, as destroying an active transient child may otherwise attempt to
128  // refocus us.
129  Windows transient_children(transient_children_);
130  STLDeleteElements(&transient_children);
131  DCHECK(transient_children_.empty());
132
133  FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroyed(this));
134
135  // Clear properties.
136  for (std::map<const void*, Value>::const_iterator iter = prop_map_.begin();
137       iter != prop_map_.end();
138       ++iter) {
139    if (iter->second.deallocator)
140      (*iter->second.deallocator)(iter->second.value);
141  }
142  prop_map_.clear();
143
144  // If we have layer it will either be destroyed by layer_owner_'s dtor, or by
145  // whoever acquired it. We don't have a layer if Init() wasn't invoked, which
146  // can happen in tests.
147  if (layer_)
148    layer_->set_delegate(NULL);
149  layer_ = NULL;
150}
151
152void Window::Init(ui::LayerType layer_type) {
153  layer_ = new ui::Layer(layer_type);
154  layer_owner_.reset(layer_);
155  layer_->SetVisible(false);
156  layer_->set_delegate(this);
157  UpdateLayerName(name_);
158  layer_->SetFillsBoundsOpaquely(!transparent_);
159
160  Env::GetInstance()->NotifyWindowInitialized(this);
161}
162
163ui::Layer* Window::RecreateLayer() {
164  // Disconnect the old layer, but don't delete it.
165  ui::Layer* old_layer = AcquireLayer();
166  if (!old_layer)
167    return NULL;
168
169  old_layer->set_delegate(NULL);
170  if (delegate_ && old_layer->external_texture())
171    old_layer->SetExternalTexture(delegate_->CopyTexture());
172  layer_ = new ui::Layer(old_layer->type());
173  layer_owner_.reset(layer_);
174  layer_->SetVisible(old_layer->visible());
175  layer_->set_scale_content(old_layer->scale_content());
176  layer_->set_delegate(this);
177  UpdateLayerName(name_);
178  layer_->SetFillsBoundsOpaquely(!transparent_);
179  // Install new layer as a sibling of the old layer, stacked on top of it.
180  if (old_layer->parent()) {
181    old_layer->parent()->Add(layer_);
182    old_layer->parent()->StackAbove(layer_, old_layer);
183  }
184  // Migrate all the child layers over to the new layer. Copy the list because
185  // the items are removed during iteration.
186  std::vector<ui::Layer*> children_copy = old_layer->children();
187  for (std::vector<ui::Layer*>::const_iterator it = children_copy.begin();
188       it != children_copy.end();
189       ++it) {
190    ui::Layer* child = *it;
191    layer_->Add(child);
192  }
193  return old_layer;
194}
195
196void Window::SetType(client::WindowType type) {
197  // Cannot change type after the window is initialized.
198  DCHECK(!layer());
199  type_ = type;
200}
201
202void Window::SetName(const std::string& name) {
203  name_ = name;
204
205  if (layer())
206    UpdateLayerName(name_);
207}
208
209void Window::SetTransparent(bool transparent) {
210  // Cannot change transparent flag after the window is initialized.
211  DCHECK(!layer());
212  transparent_ = transparent;
213}
214
215RootWindow* Window::GetRootWindow() {
216  return const_cast<RootWindow*>(
217      static_cast<const Window*>(this)->GetRootWindow());
218}
219
220const RootWindow* Window::GetRootWindow() const {
221  return parent_ ? parent_->GetRootWindow() : NULL;
222}
223
224void Window::Show() {
225  SetVisible(true);
226}
227
228void Window::Hide() {
229  for (Windows::iterator it = transient_children_.begin();
230       it != transient_children_.end(); ++it) {
231    (*it)->Hide();
232  }
233  SetVisible(false);
234  ReleaseCapture();
235}
236
237bool Window::IsVisible() const {
238  // Layer visibility can be inconsistent with window visibility, for example
239  // when a Window is hidden, we want this function to return false immediately
240  // after, even though the client may decide to animate the hide effect (and
241  // so the layer will be visible for some time after Hide() is called).
242  return visible_ && layer_ && layer_->IsDrawn();
243}
244
245gfx::Rect Window::GetBoundsInRootWindow() const {
246  // TODO(beng): There may be a better way to handle this, and the existing code
247  //             is likely wrong anyway in a multi-display world, but this will
248  //             do for now.
249  if (!GetRootWindow())
250    return bounds();
251  gfx::Point origin = bounds().origin();
252  ConvertPointToTarget(parent_, GetRootWindow(), &origin);
253  return gfx::Rect(origin, bounds().size());
254}
255
256gfx::Rect Window::GetBoundsInScreen() const {
257  gfx::Rect bounds(GetBoundsInRootWindow());
258  const RootWindow* root = GetRootWindow();
259  if (root) {
260    aura::client::ScreenPositionClient* screen_position_client =
261        aura::client::GetScreenPositionClient(root);
262    if (screen_position_client) {
263      gfx::Point origin = bounds.origin();
264      screen_position_client->ConvertPointToScreen(root, &origin);
265      bounds.set_origin(origin);
266    }
267  }
268  return bounds;
269}
270
271void Window::SetTransform(const gfx::Transform& transform) {
272  RootWindow* root_window = GetRootWindow();
273  bool contained_mouse = IsVisible() && root_window &&
274      ContainsPointInRoot(root_window->GetLastMouseLocationInRoot());
275  layer()->SetTransform(transform);
276  if (root_window)
277    root_window->OnWindowTransformed(this, contained_mouse);
278}
279
280void Window::SetLayoutManager(LayoutManager* layout_manager) {
281  if (layout_manager == layout_manager_.get())
282    return;
283  layout_manager_.reset(layout_manager);
284  if (!layout_manager)
285    return;
286  // If we're changing to a new layout manager, ensure it is aware of all the
287  // existing child windows.
288  for (Windows::const_iterator it = children_.begin();
289       it != children_.end();
290       ++it)
291    layout_manager_->OnWindowAddedToLayout(*it);
292}
293
294void Window::SetBounds(const gfx::Rect& new_bounds) {
295  if (parent_ && parent_->layout_manager())
296    parent_->layout_manager()->SetChildBounds(this, new_bounds);
297  else
298    SetBoundsInternal(new_bounds);
299}
300
301void Window::SetBoundsInScreen(const gfx::Rect& new_bounds_in_screen,
302                               const gfx::Display& dst_display) {
303  RootWindow* root = GetRootWindow();
304  if (root) {
305    gfx::Point origin = new_bounds_in_screen.origin();
306    aura::client::ScreenPositionClient* screen_position_client =
307        aura::client::GetScreenPositionClient(root);
308    screen_position_client->SetBounds(this, new_bounds_in_screen, dst_display);
309    return;
310  }
311  SetBounds(new_bounds_in_screen);
312}
313
314gfx::Rect Window::GetTargetBounds() const {
315  return layer_->GetTargetBounds();
316}
317
318const gfx::Rect& Window::bounds() const {
319  return layer_->bounds();
320}
321
322void Window::SchedulePaintInRect(const gfx::Rect& rect) {
323  if (layer_->SchedulePaint(rect)) {
324    FOR_EACH_OBSERVER(
325        WindowObserver, observers_, OnWindowPaintScheduled(this, rect));
326  }
327}
328
329void Window::SetExternalTexture(ui::Texture* texture) {
330  layer_->SetExternalTexture(texture);
331  gfx::Rect region(bounds().size());
332  FOR_EACH_OBSERVER(
333      WindowObserver, observers_, OnWindowPaintScheduled(this, region));
334}
335
336void Window::SetParent(Window* parent) {
337  GetParentForWindow(this, parent)->AddChild(this);
338}
339
340void Window::StackChildAtTop(Window* child) {
341  if (children_.size() <= 1 || child == children_.back())
342    return;  // In the front already.
343  StackChildAbove(child, children_.back());
344}
345
346void Window::StackChildAbove(Window* child, Window* target) {
347  StackChildRelativeTo(child, target, STACK_ABOVE);
348}
349
350void Window::StackChildBelow(Window* child, Window* target) {
351  StackChildRelativeTo(child, target, STACK_BELOW);
352}
353
354void Window::AddChild(Window* child) {
355  RootWindow* old_root = child->GetRootWindow();
356
357  DCHECK(std::find(children_.begin(), children_.end(), child) ==
358      children_.end());
359  if (child->parent())
360    child->parent()->RemoveChildImpl(child, this);
361  child->parent_ = this;
362
363  layer_->Add(child->layer_);
364
365  children_.push_back(child);
366  if (layout_manager_.get())
367    layout_manager_->OnWindowAddedToLayout(child);
368  FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child));
369  child->OnParentChanged();
370
371  RootWindow* root_window = GetRootWindow();
372  if (root_window && old_root != root_window) {
373    root_window->OnWindowAddedToRootWindow(child);
374    child->NotifyAddedToRootWindow();
375  }
376}
377
378void Window::AddTransientChild(Window* child) {
379  if (child->transient_parent_)
380    child->transient_parent_->RemoveTransientChild(child);
381  DCHECK(std::find(transient_children_.begin(), transient_children_.end(),
382                   child) == transient_children_.end());
383  transient_children_.push_back(child);
384  child->transient_parent_ = this;
385}
386
387void Window::RemoveTransientChild(Window* child) {
388  Windows::iterator i =
389      std::find(transient_children_.begin(), transient_children_.end(), child);
390  DCHECK(i != transient_children_.end());
391  transient_children_.erase(i);
392  if (child->transient_parent_ == this)
393    child->transient_parent_ = NULL;
394}
395
396void Window::RemoveChild(Window* child) {
397  RemoveChildImpl(child, NULL);
398}
399
400bool Window::Contains(const Window* other) const {
401  for (const Window* parent = other; parent; parent = parent->parent_) {
402    if (parent == this)
403      return true;
404  }
405  return false;
406}
407
408Window* Window::GetChildById(int id) {
409  return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id));
410}
411
412const Window* Window::GetChildById(int id) const {
413  Windows::const_iterator i;
414  for (i = children_.begin(); i != children_.end(); ++i) {
415    if ((*i)->id() == id)
416      return *i;
417    const Window* result = (*i)->GetChildById(id);
418    if (result)
419      return result;
420  }
421  return NULL;
422}
423
424// static
425void Window::ConvertPointToTarget(const Window* source,
426                                  const Window* target,
427                                  gfx::Point* point) {
428  if (!source)
429    return;
430  if (source->GetRootWindow() != target->GetRootWindow()) {
431    client::ScreenPositionClient* source_client =
432        GetScreenPositionClient(source->GetRootWindow());
433    source_client->ConvertPointToScreen(source, point);
434
435    client::ScreenPositionClient* target_client =
436        GetScreenPositionClient(target->GetRootWindow());
437    target_client->ConvertPointFromScreen(target, point);
438  } else {
439    ui::Layer::ConvertPointToLayer(source->layer(), target->layer(), point);
440  }
441}
442
443void Window::MoveCursorTo(const gfx::Point& point_in_window) {
444  RootWindow* root_window = GetRootWindow();
445  DCHECK(root_window);
446  gfx::Point point_in_root(point_in_window);
447  ConvertPointToTarget(this, root_window, &point_in_root);
448  root_window->MoveCursorTo(point_in_root);
449}
450
451gfx::NativeCursor Window::GetCursor(const gfx::Point& point) const {
452  return delegate_ ? delegate_->GetCursor(point) : gfx::kNullCursor;
453}
454
455void Window::SetEventFilter(EventFilter* event_filter) {
456  if (event_filter_.get())
457    RemovePreTargetHandler(event_filter_.get());
458  event_filter_.reset(event_filter);
459  if (event_filter)
460    AddPreTargetHandler(event_filter);
461}
462
463void Window::AddObserver(WindowObserver* observer) {
464  observers_.AddObserver(observer);
465}
466
467void Window::RemoveObserver(WindowObserver* observer) {
468  observers_.RemoveObserver(observer);
469}
470
471bool Window::HasObserver(WindowObserver* observer) {
472  return observers_.HasObserver(observer);
473}
474
475bool Window::ContainsPointInRoot(const gfx::Point& point_in_root) const {
476  const Window* root_window = GetRootWindow();
477  if (!root_window)
478    return false;
479  gfx::Point local_point(point_in_root);
480  ConvertPointToTarget(root_window, this, &local_point);
481  return gfx::Rect(GetTargetBounds().size()).Contains(local_point);
482}
483
484bool Window::ContainsPoint(const gfx::Point& local_point) const {
485  return gfx::Rect(bounds().size()).Contains(local_point);
486}
487
488bool Window::HitTest(const gfx::Point& local_point) {
489  // Expand my bounds for hit testing (override is usually zero but it's
490  // probably cheaper to do the math every time than to branch).
491  gfx::Rect local_bounds(gfx::Point(), bounds().size());
492  local_bounds.Inset(aura::Env::GetInstance()->is_touch_down() ?
493      hit_test_bounds_override_outer_touch_ :
494      hit_test_bounds_override_outer_mouse_);
495
496  if (!delegate_ || !delegate_->HasHitTestMask())
497    return local_bounds.Contains(local_point);
498
499  gfx::Path mask;
500  delegate_->GetHitTestMask(&mask);
501
502  SkRegion clip_region;
503  clip_region.setRect(local_bounds.x(), local_bounds.y(),
504                      local_bounds.width(), local_bounds.height());
505  SkRegion mask_region;
506  return mask_region.setPath(mask, clip_region) &&
507      mask_region.contains(local_point.x(), local_point.y());
508}
509
510Window* Window::GetEventHandlerForPoint(const gfx::Point& local_point) {
511  return GetWindowForPoint(local_point, true, true);
512}
513
514Window* Window::GetTopWindowContainingPoint(const gfx::Point& local_point) {
515  return GetWindowForPoint(local_point, false, false);
516}
517
518Window* Window::GetToplevelWindow() {
519  Window* topmost_window_with_delegate = NULL;
520  for (aura::Window* window = this; window != NULL; window = window->parent()) {
521    if (window->delegate())
522      topmost_window_with_delegate = window;
523  }
524  return topmost_window_with_delegate;
525}
526
527void Window::Focus() {
528  DCHECK(GetFocusManager());
529  GetFocusManager()->SetFocusedWindow(this, NULL);
530}
531
532void Window::Blur() {
533  DCHECK(GetFocusManager());
534  GetFocusManager()->SetFocusedWindow(NULL, NULL);
535}
536
537bool Window::HasFocus() const {
538  const FocusManager* focus_manager = GetFocusManager();
539  return focus_manager ? focus_manager->IsFocusedWindow(this) : false;
540}
541
542bool Window::CanFocus() const {
543  // NOTE: as part of focusing the window the ActivationClient may make the
544  // window visible (by way of making a hidden ancestor visible). For this
545  // reason we can't check visibility here and assume the client is doing it.
546  if (!parent_ || (delegate_ && !delegate_->CanFocus()))
547    return false;
548
549  // The client may forbid certain windows from receiving focus at a given point
550  // in time.
551  client::EventClient* client = client::GetEventClient(GetRootWindow());
552  if (client && !client->CanProcessEventsWithinSubtree(this))
553    return false;
554
555  return parent_->CanFocus();
556}
557
558bool Window::CanReceiveEvents() const {
559  // The client may forbid certain windows from receiving events at a given
560  // point in time.
561  client::EventClient* client = client::GetEventClient(GetRootWindow());
562  if (client && !client->CanProcessEventsWithinSubtree(this))
563    return false;
564
565  return parent_ && IsVisible() && parent_->CanReceiveEvents();
566}
567
568FocusManager* Window::GetFocusManager() {
569  return const_cast<FocusManager*>(
570      static_cast<const Window*>(this)->GetFocusManager());
571}
572
573const FocusManager* Window::GetFocusManager() const {
574  return parent_ ? parent_->GetFocusManager() : NULL;
575}
576
577void Window::SetCapture() {
578  if (!IsVisible())
579    return;
580
581  RootWindow* root_window = GetRootWindow();
582  if (!root_window)
583    return;
584  client::GetCaptureClient(root_window)->SetCapture(this);
585}
586
587void Window::ReleaseCapture() {
588  RootWindow* root_window = GetRootWindow();
589  if (!root_window)
590    return;
591  client::GetCaptureClient(root_window)->ReleaseCapture(this);
592}
593
594bool Window::HasCapture() {
595  RootWindow* root_window = GetRootWindow();
596  return root_window &&
597      client::GetCaptureClient(root_window)->GetCaptureWindow() == this;
598}
599
600void Window::SuppressPaint() {
601  layer_->SuppressPaint();
602}
603
604// {Set,Get,Clear}Property are implemented in window_property.h.
605
606void Window::SetNativeWindowProperty(const char* key, void* value) {
607  SetPropertyInternal(
608      key, key, NULL, reinterpret_cast<int64>(value), 0);
609}
610
611void* Window::GetNativeWindowProperty(const char* key) const {
612  return reinterpret_cast<void*>(GetPropertyInternal(key, 0));
613}
614
615void Window::OnDeviceScaleFactorChanged(float device_scale_factor) {
616  if (delegate_)
617    delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
618}
619
620#ifndef NDEBUG
621std::string Window::GetDebugInfo() const {
622  return StringPrintf(
623      "%s<%d> bounds(%d, %d, %d, %d) %s %s opacity=%.1f",
624      name().empty() ? "Unknown" : name().c_str(), id(),
625      bounds().x(), bounds().y(), bounds().width(), bounds().height(),
626      visible_ ? "WindowVisible" : "WindowHidden",
627      layer_->GetTargetVisibility() ? "LayerVisible" : "LayerHidden",
628      layer_->opacity());
629}
630
631void Window::PrintWindowHierarchy(int depth) const {
632  printf("%*s%s\n", depth * 2, "", GetDebugInfo().c_str());
633  for (Windows::const_iterator it = children_.begin();
634       it != children_.end(); ++it) {
635    Window* child = *it;
636    child->PrintWindowHierarchy(depth + 1);
637  }
638}
639#endif
640
641///////////////////////////////////////////////////////////////////////////////
642// Window, private:
643
644int64 Window::SetPropertyInternal(const void* key,
645                                  const char* name,
646                                  PropertyDeallocator deallocator,
647                                  int64 value,
648                                  int64 default_value) {
649  int64 old = GetPropertyInternal(key, default_value);
650  if (value == default_value) {
651    prop_map_.erase(key);
652  } else {
653    Value prop_value;
654    prop_value.name = name;
655    prop_value.value = value;
656    prop_value.deallocator = deallocator;
657    prop_map_[key] = prop_value;
658  }
659  FOR_EACH_OBSERVER(WindowObserver, observers_,
660                    OnWindowPropertyChanged(this, key, old));
661  return old;
662}
663
664int64 Window::GetPropertyInternal(const void* key,
665                                  int64 default_value) const {
666  std::map<const void*, Value>::const_iterator iter = prop_map_.find(key);
667  if (iter == prop_map_.end())
668    return default_value;
669  return iter->second.value;
670}
671
672void Window::SetBoundsInternal(const gfx::Rect& new_bounds) {
673  gfx::Rect actual_new_bounds(new_bounds);
674
675  // Ensure we don't go smaller than our minimum bounds.
676  if (delegate_) {
677    const gfx::Size& min_size = delegate_->GetMinimumSize();
678    actual_new_bounds.set_width(
679        std::max(min_size.width(), actual_new_bounds.width()));
680    actual_new_bounds.set_height(
681        std::max(min_size.height(), actual_new_bounds.height()));
682  }
683
684  gfx::Rect old_bounds = GetTargetBounds();
685
686  // Always need to set the layer's bounds -- even if it is to the same thing.
687  // This may cause important side effects such as stopping animation.
688  layer_->SetBounds(actual_new_bounds);
689
690  // If we are currently not the layer's delegate, we will not get bounds
691  // changed notification from the layer (this typically happens after animating
692  // hidden). We must notify ourselves.
693  if (layer_->delegate() != this)
694    OnLayerBoundsChanged(old_bounds, ContainsMouse());
695}
696
697void Window::SetVisible(bool visible) {
698  if (visible == layer_->GetTargetVisibility())
699    return;  // No change.
700
701  RootWindow* root_window = GetRootWindow();
702  if (client::GetVisibilityClient(root_window)) {
703    client::GetVisibilityClient(root_window)->UpdateLayerVisibility(
704        this, visible);
705  } else {
706    layer_->SetVisible(visible);
707  }
708  visible_ = visible;
709  SchedulePaint();
710  if (delegate_)
711    delegate_->OnWindowTargetVisibilityChanged(visible);
712
713  if (parent_ && parent_->layout_manager_.get())
714    parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible);
715  FOR_EACH_OBSERVER(WindowObserver, observers_,
716                    OnWindowVisibilityChanged(this, visible));
717
718  if (root_window)
719    root_window->OnWindowVisibilityChanged(this, visible);
720}
721
722void Window::SchedulePaint() {
723  SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height()));
724}
725
726Window* Window::GetWindowForPoint(const gfx::Point& local_point,
727                                  bool return_tightest,
728                                  bool for_event_handling) {
729  if (!IsVisible())
730    return NULL;
731
732  if ((for_event_handling && !HitTest(local_point)) ||
733      (!for_event_handling && !ContainsPoint(local_point)))
734    return NULL;
735
736  // Check if I should claim this event and not pass it to my children because
737  // the location is inside my hit test override area.  For details, see
738  // set_hit_test_bounds_override_inner().
739  if (for_event_handling && !hit_test_bounds_override_inner_.empty()) {
740    gfx::Rect inset_local_bounds(gfx::Point(), bounds().size());
741    inset_local_bounds.Inset(hit_test_bounds_override_inner_);
742    // We know we're inside the normal local bounds, so if we're outside the
743    // inset bounds we must be in the special hit test override area.
744    DCHECK(HitTest(local_point));
745    if (!inset_local_bounds.Contains(local_point))
746      return delegate_ ? this : NULL;
747  }
748
749  if (!return_tightest && delegate_)
750    return this;
751
752  for (Windows::const_reverse_iterator it = children_.rbegin(),
753           rend = children_.rend();
754       it != rend; ++it) {
755    Window* child = *it;
756
757    if (for_event_handling) {
758      // The client may not allow events to be processed by certain subtrees.
759      client::EventClient* client = client::GetEventClient(GetRootWindow());
760      if (client && !client->CanProcessEventsWithinSubtree(child))
761        continue;
762    }
763
764    // We don't process events for invisible windows or those that have asked
765    // to ignore events.
766    if (!child->IsVisible() || (for_event_handling && child->ignore_events_))
767      continue;
768
769    gfx::Point point_in_child_coords(local_point);
770    ConvertPointToTarget(this, child, &point_in_child_coords);
771    if (for_event_handling && delegate_ &&
772        !delegate_->ShouldDescendIntoChildForEventHandling(
773            child, local_point)) {
774      continue;
775    }
776
777    Window* match = child->GetWindowForPoint(point_in_child_coords,
778                                             return_tightest,
779                                             for_event_handling);
780    if (match)
781      return match;
782  }
783
784  return delegate_ ? this : NULL;
785}
786
787void Window::RemoveChildImpl(Window* child, Window* new_parent) {
788  Windows::iterator i = std::find(children_.begin(), children_.end(), child);
789  DCHECK(i != children_.end());
790  if (layout_manager_.get())
791    layout_manager_->OnWillRemoveWindowFromLayout(child);
792  FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child));
793  RootWindow* root_window = child->GetRootWindow();
794  RootWindow* new_root_window = new_parent ? new_parent->GetRootWindow() : NULL;
795  if (root_window && root_window != new_root_window) {
796    root_window->OnWindowRemovedFromRootWindow(child, new_root_window);
797    child->NotifyRemovingFromRootWindow();
798  }
799  child->parent_ = NULL;
800  // We should only remove the child's layer if the child still owns that layer.
801  // Someone else may have acquired ownership of it via AcquireLayer() and may
802  // expect the hierarchy to go unchanged as the Window is destroyed.
803  if (child->layer_owner_.get())
804    layer_->Remove(child->layer_);
805  children_.erase(i);
806  child->OnParentChanged();
807  if (layout_manager_.get())
808    layout_manager_->OnWindowRemovedFromLayout(child);
809}
810
811void Window::OnParentChanged() {
812  FOR_EACH_OBSERVER(
813      WindowObserver, observers_, OnWindowParentChanged(this, parent_));
814}
815
816void Window::StackChildRelativeTo(Window* child,
817                                  Window* target,
818                                  StackDirection direction) {
819  DCHECK_NE(child, target);
820  DCHECK(child);
821  DCHECK(target);
822  DCHECK_EQ(this, child->parent());
823  DCHECK_EQ(this, target->parent());
824
825  const size_t target_i =
826      std::find(children_.begin(), children_.end(), target) - children_.begin();
827
828  // By convention we don't stack on top of windows with layers with NULL
829  // delegates.  Walk backward to find a valid target window.
830  // See tests WindowTest.StackingMadrigal and StackOverClosingTransient
831  // for an explanation of this.
832  size_t final_target_i = target_i;
833  while (final_target_i > 0 &&
834         children_[final_target_i]->layer()->delegate() == NULL)
835    --final_target_i;
836  Window* final_target = children_[final_target_i];
837
838  // If we couldn't find a valid target position, don't move anything.
839  if (final_target->layer()->delegate() == NULL)
840    return;
841
842  // Don't try to stack a child above itself.
843  if (child == final_target)
844    return;
845
846  // Move the child and all its transients.
847  StackChildRelativeToImpl(child, final_target, direction);
848}
849
850void Window::StackChildRelativeToImpl(Window* child,
851                                      Window* target,
852                                      StackDirection direction) {
853  DCHECK_NE(child, target);
854  DCHECK(child);
855  DCHECK(target);
856  DCHECK_EQ(this, child->parent());
857  DCHECK_EQ(this, target->parent());
858
859  const size_t child_i =
860      std::find(children_.begin(), children_.end(), child) - children_.begin();
861  const size_t target_i =
862      std::find(children_.begin(), children_.end(), target) - children_.begin();
863
864  // Don't move the child if it is already in the right place.
865  if ((direction == STACK_ABOVE && child_i == target_i + 1) ||
866      (direction == STACK_BELOW && child_i + 1 == target_i))
867    return;
868
869  const size_t dest_i =
870      direction == STACK_ABOVE ?
871      (child_i < target_i ? target_i : target_i + 1) :
872      (child_i < target_i ? target_i - 1 : target_i);
873  children_.erase(children_.begin() + child_i);
874  children_.insert(children_.begin() + dest_i, child);
875
876  if (direction == STACK_ABOVE)
877    layer()->StackAbove(child->layer(), target->layer());
878  else
879    layer()->StackBelow(child->layer(), target->layer());
880
881  // Stack any transient children that share the same parent to be in front of
882  // 'child'.
883  Window* last_transient = child;
884  for (Windows::iterator it = child->transient_children_.begin();
885       it != child->transient_children_.end(); ++it) {
886    Window* transient_child = *it;
887    if (transient_child->parent_ == this) {
888      StackChildRelativeToImpl(transient_child, last_transient, STACK_ABOVE);
889      last_transient = transient_child;
890    }
891  }
892
893  child->OnStackingChanged();
894}
895
896void Window::OnStackingChanged() {
897  FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowStackingChanged(this));
898}
899
900void Window::NotifyRemovingFromRootWindow() {
901  FOR_EACH_OBSERVER(WindowObserver, observers_,
902                    OnWindowRemovingFromRootWindow(this));
903  for (Window::Windows::const_iterator it = children_.begin();
904       it != children_.end(); ++it) {
905    (*it)->NotifyRemovingFromRootWindow();
906  }
907}
908
909void Window::NotifyAddedToRootWindow() {
910  FOR_EACH_OBSERVER(WindowObserver, observers_,
911                    OnWindowAddedToRootWindow(this));
912  for (Window::Windows::const_iterator it = children_.begin();
913       it != children_.end(); ++it) {
914    (*it)->NotifyAddedToRootWindow();
915  }
916}
917
918void Window::OnLayerBoundsChanged(const gfx::Rect& old_bounds,
919                                  bool contained_mouse) {
920  if (layout_manager_.get())
921    layout_manager_->OnWindowResized();
922  if (delegate_)
923    delegate_->OnBoundsChanged(old_bounds, bounds());
924  FOR_EACH_OBSERVER(WindowObserver,
925                    observers_,
926                    OnWindowBoundsChanged(this, old_bounds, bounds()));
927  RootWindow* root_window = GetRootWindow();
928  if (root_window)
929    root_window->OnWindowBoundsChanged(this, contained_mouse);
930}
931
932void Window::OnPaintLayer(gfx::Canvas* canvas) {
933  if (delegate_)
934    delegate_->OnPaint(canvas);
935}
936
937base::Closure Window::PrepareForLayerBoundsChange() {
938  return base::Bind(&Window::OnLayerBoundsChanged, base::Unretained(this),
939                    bounds(), ContainsMouse());
940}
941
942bool Window::CanAcceptEvents() {
943  return CanReceiveEvents();
944}
945
946ui::EventTarget* Window::GetParentTarget() {
947  return parent_;
948}
949
950void Window::UpdateLayerName(const std::string& name) {
951#if !defined(NDEBUG)
952  DCHECK(layer());
953
954  std::string layer_name(name_);
955  if (layer_name.empty())
956    layer_name.append("Unnamed Window");
957
958  if (id_ != -1) {
959    char id_buf[10];
960    base::snprintf(id_buf, sizeof(id_buf), " %d", id_);
961    layer_name.append(id_buf);
962  }
963  layer()->set_name(layer_name);
964#endif
965}
966
967bool Window::ContainsMouse() {
968  bool contains_mouse = false;
969  if (IsVisible()) {
970    RootWindow* root_window = GetRootWindow();
971    contains_mouse = root_window &&
972        ContainsPointInRoot(root_window->GetLastMouseLocationInRoot());
973  }
974  return contains_mouse;
975}
976
977}  // namespace aura
978