Chromium Code Reviews| 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(); |
| } |