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