Index: ui/views/widget/native_widget_aura.cc |
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc |
index 754b258eead2f0474b8189a9b147c285c587a58c..caa8368882afa1324ff08f62004575efbe6bbe45 100644 |
--- a/ui/views/widget/native_widget_aura.cc |
+++ b/ui/views/widget/native_widget_aura.cc |
@@ -30,6 +30,7 @@ |
#include "ui/native_theme/native_theme_aura.h" |
#include "ui/views/drag_utils.h" |
#include "ui/views/ime/input_method_bridge.h" |
+#include "ui/views/view_constants_aura.h" |
#include "ui/views/views_delegate.h" |
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" |
#include "ui/views/widget/drop_helper.h" |
@@ -59,6 +60,37 @@ void SetRestoreBounds(aura::Window* window, const gfx::Rect& bounds) { |
window->SetProperty(aura::client::kRestoreBoundsKey, new gfx::Rect(bounds)); |
} |
+// Sets |order| to the list of views whose layer / attached window's layer |
+// is a child of |parent_layer|. |order| is sorted in ascending z-order of |
+// the views. |
+// |hosts| are the views with an attached window whose layer is a child of |
+// |parent_layer|. For the sake of simplificity |hosts| must all have id |
+// |host_id|. |
+void GetOrderOfViewsWithLayers( |
+ views::View* current_view, |
+ ui::Layer* parent_layer, |
+ int host_id, |
+ const std::map<views::View*, aura::Window*>& hosts, |
+ std::vector<views::View*>* order) { |
+ DCHECK(current_view); |
+ DCHECK(parent_layer); |
+ DCHECK(order); |
+ if (current_view->layer() && |
+ current_view->layer()->parent() == parent_layer) { |
+ order->push_back(current_view); |
+ // |hosts| may contain a child of |current_view|. |
+ } else if (current_view->id() == host_id && |
+ hosts.find(current_view) != hosts.end()) { |
+ order->push_back(current_view); |
+ return; |
+ } |
+ |
+ for (int i = 0; i < current_view->child_count(); ++i) { |
+ GetOrderOfViewsWithLayers(current_view->child_at(i), parent_layer, |
+ host_id, hosts, order); |
+ } |
+} |
+ |
} // namespace |
//////////////////////////////////////////////////////////////////////////////// |
@@ -1031,6 +1063,98 @@ void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view, |
} |
// static |
+// TODO(pkotwicz): The implementation of the NativeWidgetPrivate statics is the |
+// same for NativeWidgetAura and DesktopNativeWidgetAura. Move the |
+// implementation of the static functions to a different file. |
+void NativeWidgetPrivate::ReorderLayers(gfx::NativeView parent, |
sky
2013/05/21 23:43:55
I think all this code should be moved into a stand
|
+ View* root_view) { |
+ // Reorder the layers according to the positions of the views with layers and |
+ // views with attached windows in the view tree. The reordered layers are |
+ // positioned above layers for windows which are not attached to a host view. |
+ // The reordered layers are however positioned below any window layers with a |
+ // NULL delegate. |
+ |
+ // Find all the child windows which are attached to a view. |
+ std::map<View*, aura::Window*> hosted_windows; |
sky
2013/05/21 23:43:55
This method is long, break it up where you can. Fo
pkotwicz
2013/05/23 02:28:07
Done.
|
+ const std::vector<aura::Window*>& child_windows = parent->children(); |
+ for (size_t i = 0; i < child_windows.size(); ++i) { |
+ aura::Window* child = child_windows[i]; |
+ View* host_view = child->GetProperty(kHostViewKey); |
+ if (host_view) { |
+ if (!child->layer()->delegate()) { |
+ // If there is a case where the attached NativeView has a NULL layer |
+ // delegate, we would need handle this case in View::ReorderChildView(). |
+ NOTREACHED(); |
+ } |
+ |
+ hosted_windows[host_view] = child; |
+ } |
+ } |
+ |
sky
2013/05/21 23:43:55
Can't you early out if hosted_windows is empty?
pkotwicz
2013/05/23 02:28:07
We cannot early out here because there may be view
sky
2013/05/23 15:36:49
Why don't we change ReorderLayers/ReorderChildLaye
pkotwicz
2013/05/23 17:21:45
The change you are suggesting would result in chan
sky
2013/05/23 17:33:35
I think that better matches expectations, right? R
|
+ // Compute the desired z-order of the layers based on the order of the views |
+ // with layers and views with attached windows in the view tree. |
+ std::vector<View*> view_with_layer_order; |
+ { |
+ // Temporarily modify the ids of the views attached to a window to simplify |
sky
2013/05/21 23:43:55
Yuck! Don't muck with the ids like this.
pkotwicz
2013/05/23 02:28:07
No more modifying of the ids
|
+ // GetOrderOfViewsWithLayers. |
+ const int kHostViewId = 1; |
+ std::map<View*, int> old_ids; |
+ for (std::map<View*, aura::Window*>::iterator it = hosted_windows.begin(); |
+ it != hosted_windows.end(); ++it) { |
+ View* v = it->first; |
+ old_ids[v] = v->id(); |
+ v->set_id(kHostViewId); |
+ } |
+ |
+ GetOrderOfViewsWithLayers(root_view, parent->layer(), kHostViewId, |
+ hosted_windows, &view_with_layer_order); |
+ |
+ // Reset the view ids. |
+ for (std::map<View*, int>::iterator it = old_ids.begin(); |
+ it != old_ids.end(); ++it) { |
+ it->first->set_id(it->second); |
+ } |
+ } |
+ |
+ // Find the bottommost window with a NULL layer delegate below which the |
+ // reordered layers should be stacked. |stack_below_window| should be NULL |
+ // if the reodered layers should be stacked at the top. |
+ aura::Window* stack_below_window = NULL; |
+ for (size_t i = 0; i < child_windows.size(); ++i) { |
+ aura::Window* child = child_windows[i]; |
+ if (!child->layer()->delegate()) { |
+ stack_below_window = child; |
+ break; |
+ } |
+ } |
+ |
+ // Reorder the layers and windows. |
+ for (size_t i = 0; i < view_with_layer_order.size(); ++i) { |
+ View* view = view_with_layer_order[i]; |
+ ui::Layer* layer = view->layer(); |
+ aura::Window* window = NULL; |
+ |
+ std::map<View*, aura::Window*>::iterator hosted_window_it = |
+ hosted_windows.find(view); |
+ if (hosted_window_it != hosted_windows.end()) { |
+ window = hosted_window_it->second; |
+ layer = window->layer(); |
+ } |
+ |
+ DCHECK(layer); |
+ if (stack_below_window) { |
+ if (window) |
+ parent->StackChildBelow(window, stack_below_window); |
+ parent->layer()->StackBelow(layer, stack_below_window->layer()); |
+ } else { |
+ if (window) |
+ parent->StackChildAtTop(window); |
+ parent->layer()->StackAtTop(layer); |
+ } |
+ } |
+} |
+ |
+// static |
bool NativeWidgetPrivate::IsMouseButtonDown() { |
return aura::Env::GetInstance()->is_mouse_button_down(); |
} |