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