Home | History | Annotate | Download | only in corewm
      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/views/corewm/window_util.h"
      6 
      7 #include "ui/aura/client/activation_client.h"
      8 #include "ui/aura/root_window.h"
      9 #include "ui/aura/window.h"
     10 #include "ui/compositor/layer.h"
     11 #include "ui/views/view.h"
     12 #include "ui/views/widget/widget.h"
     13 
     14 namespace {
     15 
     16 // Helper method for RecreateWindowLayers() which adds all the existing layers
     17 // for |view| and its descendants to |parent_layer|. New layers are created for
     18 // |view| (if it previously had a layer) and any descendants which previously
     19 // had layers. The new layers are blank, so nothing has been painted to them
     20 // yet. Returns true if this method added at least one layer to |parent_layer|.
     21 bool RecreateViewLayers(ui::Layer* parent_layer, views::View* view) {
     22   bool recreated_layer = false;
     23   if (view->layer()) {
     24     ui::Layer* layer = view->RecreateLayer();
     25     if (layer) {
     26       layer->SuppressPaint();
     27       parent_layer->Add(layer);
     28       parent_layer = layer;
     29       recreated_layer = true;
     30     }
     31   }
     32   for (int i = 0; i < view->child_count(); ++i)
     33     recreated_layer |= RecreateViewLayers(parent_layer, view->child_at(i));
     34 
     35   return recreated_layer;
     36 }
     37 
     38 }  // namespace
     39 
     40 namespace views {
     41 namespace corewm {
     42 
     43 void ActivateWindow(aura::Window* window) {
     44   DCHECK(window);
     45   DCHECK(window->GetRootWindow());
     46   aura::client::GetActivationClient(window->GetRootWindow())->ActivateWindow(
     47       window);
     48 }
     49 
     50 void DeactivateWindow(aura::Window* window) {
     51   DCHECK(window);
     52   DCHECK(window->GetRootWindow());
     53   aura::client::GetActivationClient(window->GetRootWindow())->DeactivateWindow(
     54       window);
     55 }
     56 
     57 bool IsActiveWindow(aura::Window* window) {
     58   DCHECK(window);
     59   if (!window->GetRootWindow())
     60     return false;
     61   aura::client::ActivationClient* client =
     62       aura::client::GetActivationClient(window->GetRootWindow());
     63   return client && client->GetActiveWindow() == window;
     64 }
     65 
     66 bool CanActivateWindow(aura::Window* window) {
     67   DCHECK(window);
     68   if (!window->GetRootWindow())
     69     return false;
     70   aura::client::ActivationClient* client =
     71       aura::client::GetActivationClient(window->GetRootWindow());
     72   return client && client->CanActivateWindow(window);
     73 }
     74 
     75 aura::Window* GetActivatableWindow(aura::Window* window) {
     76   aura::client::ActivationClient* client =
     77       aura::client::GetActivationClient(window->GetRootWindow());
     78   return client ? client->GetActivatableWindow(window) : NULL;
     79 }
     80 
     81 aura::Window* GetToplevelWindow(aura::Window* window) {
     82   aura::client::ActivationClient* client =
     83       aura::client::GetActivationClient(window->GetRootWindow());
     84   return client ? client->GetToplevelWindow(window) : NULL;
     85 }
     86 
     87 void DeepDeleteLayers(ui::Layer* layer) {
     88   std::vector<ui::Layer*> children = layer->children();
     89   for (std::vector<ui::Layer*>::const_iterator it = children.begin();
     90        it != children.end();
     91        ++it) {
     92     ui::Layer* child = *it;
     93     DeepDeleteLayers(child);
     94   }
     95   delete layer;
     96 }
     97 
     98 ui::Layer* RecreateWindowLayers(aura::Window* window, bool set_bounds) {
     99   const gfx::Rect bounds = window->bounds();
    100   ui::Layer* old_layer = window->RecreateLayer();
    101   DCHECK(old_layer);
    102 
    103   // Cache the order of |window|'s child layers. If |window| belongs to a widget
    104   // and the widget has both child windows and child views with layers,
    105   // |initial_layer_order| is used to determine the relative order.
    106   std::vector<ui::Layer*> initial_layer_order = window->layer()->children();
    107 
    108   // Recreate the layers for any child windows of |window|.
    109   for (aura::Window::Windows::const_iterator it = window->children().begin();
    110        it != window->children().end();
    111        ++it) {
    112     old_layer->Add(RecreateWindowLayers(*it, set_bounds));
    113   }
    114 
    115   // Recreate the layers for any child views of |widget|.
    116   bool has_view_layers = false;
    117   views::Widget* widget = views::Widget::GetWidgetForNativeView(window);
    118   if (widget && widget->GetRootView())
    119     has_view_layers = RecreateViewLayers(old_layer, widget->GetRootView());
    120 
    121   if (has_view_layers && !window->children().empty()) {
    122     // RecreateViewLayers() added the view layers above the window layers in
    123     // z-order. The window layers and the view layers may have been originally
    124     // intermingled. Reorder |old_layer|'s children based on the initial
    125     // order.
    126     for (size_t i = 0; i < initial_layer_order.size(); ++i) {
    127       ui::Layer* layer = initial_layer_order[i];
    128       std::vector<ui::Layer*>::const_iterator it = std::find(
    129           old_layer->children().begin(), old_layer->children().end(), layer);
    130       if (it != old_layer->children().end())
    131         old_layer->StackAtTop(layer);
    132     }
    133   }
    134 
    135   if (set_bounds)
    136     window->SetBounds(bounds);
    137   return old_layer;
    138 }
    139 
    140 }  // namespace corewm
    141 }  // namespace views
    142