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