Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2013 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/widget/native_widget_layer_reorderer_aura.h" | |
| 6 | |
| 7 #include <map> | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "ui/aura/window.h" | |
| 11 #include "ui/views/view.h" | |
| 12 #include "ui/views/view_constants_aura.h" | |
| 13 | |
| 14 namespace views { | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 18 // Sets |hosted_windows| to a mapping of the views with an attached window to | |
| 19 // the window that they are attached to. Only views attached to a child of | |
| 20 // |parent_window| are returned. | |
| 21 void GetViewsWithAttachedWindow( | |
| 22 const aura::Window& parent_window, | |
| 23 std::map<views::View*, aura::Window*>* hosted_windows) { | |
| 24 const std::vector<aura::Window*>& child_windows = parent_window.children(); | |
| 25 for (size_t i = 0; i < child_windows.size(); ++i) { | |
| 26 aura::Window* child = child_windows[i]; | |
| 27 View* host_view = child->GetProperty(kHostViewKey); | |
| 28 if (host_view) | |
| 29 (*hosted_windows)[host_view] = child; | |
| 30 } | |
| 31 } | |
| 32 | |
| 33 // Sets |order| to the list of views whose layer / attached window's layer | |
| 34 // is a child of |parent_layer|. |order| is sorted in ascending z-order of | |
| 35 // the views. | |
| 36 // |hosts| are the views with an attached window whose layer is a child of | |
| 37 // |parent_layer|. | |
| 38 void GetOrderOfViewsWithLayers( | |
| 39 views::View* view, | |
| 40 ui::Layer* parent_layer, | |
| 41 const std::map<views::View*, aura::Window*>& hosts, | |
| 42 std::vector<views::View*>* order) { | |
| 43 DCHECK(view); | |
| 44 DCHECK(parent_layer); | |
| 45 DCHECK(order); | |
| 46 if (view->layer() && view->layer()->parent() == parent_layer) { | |
| 47 order->push_back(view); | |
| 48 // |hosts| may contain a child of |view|. | |
| 49 } else if (hosts.find(view) != hosts.end()) { | |
| 50 order->push_back(view); | |
| 51 } | |
| 52 | |
| 53 for (int i = 0; i < view->child_count(); ++i) | |
| 54 GetOrderOfViewsWithLayers(view->child_at(i), parent_layer, hosts, order); | |
| 55 } | |
| 56 | |
| 57 } // namespace | |
| 58 | |
| 59 NativeWidgetLayerReordererAura::NativeWidgetLayerReordererAura( | |
| 60 aura::Window* window, | |
| 61 View* root_view) | |
| 62 : window_(window), | |
| 63 root_view_(root_view) { | |
| 64 window_->AddObserver(this); | |
| 65 const std::vector<aura::Window*>& child_windows = window_->children(); | |
| 66 for (size_t i = 0; i < child_windows.size(); ++i) | |
| 67 child_windows[i]->AddObserver(this); | |
| 68 } | |
| 69 | |
| 70 NativeWidgetLayerReordererAura::~NativeWidgetLayerReordererAura() { | |
| 71 if (window_) | |
| 72 StopObserving(window_); | |
| 73 } | |
| 74 | |
| 75 void NativeWidgetLayerReordererAura::ReorderChildWindowLayers() { | |
| 76 DCHECK(window_); | |
| 77 | |
| 78 std::map<View*, aura::Window*> hosted_windows; | |
| 79 GetViewsWithAttachedWindow(*window_, &hosted_windows); | |
| 80 | |
| 81 if (hosted_windows.empty()) { | |
| 82 // Exit early if there are no views with attached windows. | |
| 83 // View::ReorderLayers() should have already reordered the layers owned by | |
| 84 // views. | |
| 85 return; | |
| 86 } | |
| 87 | |
| 88 // Compute the desired z-order of the layers based on the order of the views | |
| 89 // with layers and views with attached windows in the view tree. | |
| 90 std::vector<View*> view_with_layer_order; | |
| 91 GetOrderOfViewsWithLayers(root_view_, window_->layer(), hosted_windows, | |
| 92 &view_with_layer_order); | |
| 93 | |
| 94 // Reorder the layers and windows. | |
| 95 for (std::vector<View*>::reverse_iterator it = view_with_layer_order.rbegin(); | |
| 96 it != view_with_layer_order.rend(); ++it) { | |
| 97 View* view = *it; | |
| 98 ui::Layer* layer = view->layer(); | |
| 99 aura::Window* window = NULL; | |
| 100 | |
| 101 std::map<View*, aura::Window*>::iterator hosted_window_it = | |
| 102 hosted_windows.find(view); | |
| 103 if (hosted_window_it != hosted_windows.end()) { | |
| 104 window = hosted_window_it->second; | |
| 105 layer = window->layer(); | |
| 106 } | |
| 107 | |
| 108 DCHECK(layer); | |
| 109 if (window) | |
| 110 window_->StackChildAtBottom(window); | |
| 111 window_->layer()->StackAtBottom(layer); | |
|
sky
2013/05/24 15:57:26
Don't we only care about items in hosted_windows h
pkotwicz
2013/05/26 04:12:15
IMHO, it's simpler (and safer) to reorder both lay
| |
| 112 } | |
| 113 } | |
| 114 | |
| 115 void NativeWidgetLayerReordererAura::StopObserving(aura::Window* window) { | |
| 116 window->RemoveObserver(this); | |
|
sky
2013/05/24 15:57:26
It's subtle and easy to get wrong that you're obse
pkotwicz
2013/05/26 04:12:15
Added a separate class
| |
| 117 if (window_ == window){ | |
| 118 const std::vector<aura::Window*>& child_windows = window_->children(); | |
| 119 for (size_t i = 0; i < child_windows.size(); ++i) | |
| 120 child_windows[i]->RemoveObserver(this); | |
| 121 window_ = NULL; | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 void NativeWidgetLayerReordererAura::OnWindowAdded(aura::Window* new_window) { | |
| 126 if (new_window->parent() == window_) { | |
| 127 new_window->AddObserver(this); | |
| 128 ReorderChildWindowLayers(); | |
| 129 } | |
| 130 } | |
| 131 | |
| 132 void NativeWidgetLayerReordererAura::OnWillRemoveWindow(aura::Window* window) { | |
| 133 if (window->parent() == window_) | |
|
sky
2013/05/24 15:57:26
Why do you care about this case?
pkotwicz
2013/05/26 04:12:15
This is no longer relevant because I separated the
| |
| 134 StopObserving(window); | |
| 135 } | |
| 136 | |
| 137 void NativeWidgetLayerReordererAura::OnWindowPropertyChanged( | |
| 138 aura::Window* window, | |
| 139 const void* key, | |
| 140 intptr_t old) { | |
| 141 if (key == kHostViewKey && window != window_) | |
| 142 ReorderChildWindowLayers(); | |
| 143 } | |
| 144 | |
| 145 void NativeWidgetLayerReordererAura::OnWindowDestroying(aura::Window* window) { | |
| 146 StopObserving(window); | |
| 147 } | |
| 148 | |
| 149 } // namespace views | |
| OLD | NEW |